Sponsored By
Featured Blog | This community-written post highlights the best of what the game industry has to offer. Read more like it on the Game Developer Blogs or learn how to Submit Your Own Blog Post
Recreating the time mechanics of Braid (Part 2)
Now that I have a working version, I explain what I have done and what I will do to optimize the system to make it run much faster.
3 Min Read
Simple rewind
For the first implementation I decided to go with the simplest possible solution. I use Unity because it is a complete engine that is easy to code in. The script saves the state of the game object every single frame.
See Part 1 here. See Part 3 here.
Braid is a 2D game, but I wanted to try the same idea in a 3D game. The problem with this idea is that it increases the required memory by 50%. I also wanted to try to make it somewhat physics based, because watching the physics generate in reverse would look impressive and awesome. I would have to keep track of rotations as well as positions and velocities, increasing the memory usage by another 50%. The total is 9 floats per frame, about 2.1 kilobytes per second per object at 60 frames per second. If it only affects the player, it would take 7.7 minutes to use up 1 megabyte of memory. That is not too bad considering you could rewind all the way to the beginning, but it would cause a problem with extended playing sessions. If this script is running on multiple objects, it would quickly use up memory. The good part is that the system provides a perfect 1:1 between the original generation and rewinding the game.
Next it is time to optimize the system to make it use less memory, and also to make it more impressive. The first optimization was the biggest; I only capture every 10th frame which divides the memory usage by 10. This optimization alone still looks decent, and could be cleverly written off as stylized. In the future I will be interpolating between the states. Although it will not be a perfect 1:1, it will be smooth and give the illusion of a 1:1 rewind.
Next was less of an optimization and more of a problem. The rotations are stored as quaternions, which were not rewinding correctly. The quaternions would work for a rewind but would quickly become unstable, causing all objects using the script to jitter. Removing rotations saves 30% on memory usage, and without rotations, 3D becomes pointless/difficult to design, so I will remove that for an additional 30%.
Next up is compressing the floats into another data type. By keeping track of the player's velocity, I realized that it only has a single digit in front of and behind the decimal. That can be compressed all the way down to a sbyte. The position requires a fair amount of precision: It can be compressed to a short, but with some loss. The total of the compression is a 62.5% reduction in memory. The total is 2 sbytes and 2 shorts per 10 frames, about 0.03 kilobytes per second per object at 60 frames.
The optimizations make the system very lightweight. I will be able to have many items on screen that are affected by time reversal, and the system will be able to rewind for a long time. I will try to get rotations into the rewind system to make a physics based destruction game. The player would be able to knock down a stack of blocks, and then rewind it and watch it again.
See Part 1 here. See Part 3 here.
Read more about:
Featured BlogsAbout the Author
Daily news, dev blogs, and stories from Game Developer straight to your inbox
You May Also Like