Gamasutra: The Art & Business of Making Gamesspacer
View All     RSS
July 26, 2017
arrowPress Releases

If you enjoy reading this site, you might also want to check out these UBM Tech sites:

Recreating the time mechanics of Braid (Part 2)
by Cameron LeBlanc on 03/13/13 03:18:00 pm   Featured Blogs

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.


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.

Related Jobs

Insomniac Games
Insomniac Games — Durham, North Carolina, United States

Mid to Sr Gameplay Programmer
Telltale Games
Telltale Games — San Rafael, California, United States

Tools Engineer
Magic Leap
Magic Leap — Sunnyvale, California, United States

Lead Software Engineer - SDK/Tools
Sucker Punch Productions
Sucker Punch Productions — Bellevue, Washington, United States

Senior Systems Designer

Loading Comments

loader image