Gamasutra: The Art & Business of Making Gamesspacer
View All     RSS
May 29, 2016
arrowPress Releases
May 29, 2016
PR Newswire
View All
View All     Submit Event

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

Glu Mobile
Glu Mobile — Toronto, Ontario, Canada

Senior Game Programmer
Game Circus LLC
Game Circus LLC — Addison, Texas, United States

Game Server Engineer
Cold Iron Studios
Cold Iron Studios — Santa Clara, California, United States

Senior Game Programmer
Psyonix — San Diego, California, United States

UI Artist for Rocket League

Loading Comments

loader image