Performance++; MemoryFootprint--; (Patreon)
Content
After last month's upgrade to the engine's physics system, we saw the need to implement a few, but huge, changes to the code to reduce the memory footprint and to improve the peformance of our games. The changes mostly consisted in replacing the underlying math type used for all the spatial data, positions, velocities, etc. by a smaller one.
The problem
Depending on the processor, performing arithmetic operations on rational numbers with a decimal part can be very expensive; on the Virtual Boy, it can take from 24 up to 44 CPU cycles, depending on the mathematical operation. So, some very clever people figured out how to perform those operations on the same numerical information but using integer types using a method called fixed point math. Imagine that you have a byte, which is 8 bits, and use the first 4 bits to represent the integral part of a number and the last 4 bits to represent the decimal part. Thus, instead of interpreting the byte's content as an integer number that can be 0 up to 255, you have a rational number up to 16, with a decimal part that has a precision of 0.0625. If you have more bits, you can represent more numbers and with greater precision.
Until recently, we used a fixed point data type which consisted of 32 bits, 19 for the integral part and 13 for the decimal part. That gave us good precision and allowed us to have very large stages (262,144 pixels!), but it used lots of memory and had huge performance drawbacks. Remember that the VB's CPU is 32 bits? That means that it cannot perform a single CPU instruction on numbers that require more than 32 bits to be stored (some very big numbers). But when using fixed point math, those very big numbers can be easily produced during the game simulation, causing the program to store them in variables that use more than 32 bits.
The solution
So, we decided to use a smaller fixed point type for all the spatial data to make sure that the program always deals with numbers that can be stored in a 32 bit variable even in extreme cases, making sure that we are always using the VB's CPU efficiently. Instead of the 19/13 split, we now use a 16 bit fixed point type, where 10 bits are used for the integral part and 6 bits for the decimal part.
But that change forced us to re-engineer the units of the spatial representation through the whole engine. With 19 bits for the integral part, we can store up to 262,144 values. If that number represent pixels, we can build huge stages. With 10 bits, only 1,024 values are representable. But 1,024x1,024 pixels stages seem very small and restrictive. So, the solution was to change the engine's units from pixels to meters. With a meter that equals 8 pixels, 1,024 meters equate to 8,192x8,192 pixel stages, which is much more reasonable from a gameplay perspective and should allow to have big enough game stages.
Outlook
This past month we have been very busy implementing all these changes (while juggling with the holidays). Going through about 30 thousands of lines of code have been at time tedious, and at times daunting, but worthwhile in the end because we are now sure that we are using the VB's hardware resources in the most efficient way that we are capable of.
Finalizing and thoroughly testing the changes, as well as porting the demos, should keep us busy through the next week. When that is done, we'll release a new engine version and move on to the next major tasks.