Gamasutra: The Art & Business of Making Gamesspacer
View All     RSS
November 1, 2014
arrowPress Releases
November 1, 2014
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

Twisted Pixel Games
Twisted Pixel Games — Austin, Texas, United States

Senior Graphics and Systems Engineer
Twisted Pixel Games
Twisted Pixel Games — Austin, Texas, United States

Mid-level Tools and Systems Engineer
Sega Networks Inc.
Sega Networks Inc. — Madison, Wisconsin, United States

Mobile Game Engineer
Forio — San Francisco, California, United States

Web Application Developer Team Lead


Patrick Purcell
profile image
Congrats on the feature! Looking forward to seeing where this goes.

Sean Chan
profile image
Hi there, I did this for my school project at DigiPen (we got honorable mention for this year's IGF). I kept it simple and just saved data every frame, there's pretty much no optimization but it turns out we didn't need it to be that good to make the game happen

You can check it out at

Langdon Oliver
profile image
Great read, thanks for sharing. I've been playing Chronovolt for Vita that does rewinding in a 3D space. Super interesting to read someone's approach and how it was optimized.

Aaron San Filippo
profile image
Maybe more of a note for the Gamasutra editors, but the feature link on the front page takes you right to this part 2 article, which is kind of confusing and makes it seem at first that the author didn't know how to write a proper intro. It might be useful to have the "part 1" link at the top of the article.

Christian Nutt
profile image
Good idea! Added in.

Diego Santos
profile image
Very interesting. Congratulations for your advance. As a game designer, I always respect the work in programming. I expect the next post will came soon.

Sage Emerald
profile image
Awesome! I was working on a similar 2d game, but I wanted to use my idea of a snap back time travel without the rewind to flow things up a bit. I wanted to play with the idea of the piratical and short range implications of legit time travel I.e. going back in time to reinforce your self so there's like 6 of you v.s. six of them. It was great until I started adding the enemies that used the similar mechanic and circumnavigated it and then desperadoes became straight up unsolvable glitches.
Part of the problem was the udk, and how I wanted to mapp the engine to a frame by frame timeline so I could play with a system that predicts the current out come letting you travel to the future. And then I hit the same problems mentioned in the first post and everything burst into flames.
I'm downloading unity now that's for dang sure. Thank's for motivating me! I need to get back to work.

Terry Matthes
profile image
Can't wait for the next post!

Cameron LeBlanc
profile image
Thank you all for the awesome feedback. This will be a five part series, and I will be posting regularly over the next month or so.

profile image
Why don't you store per frame info for the last say 5 minutes, and then 1 per 10 frames for anything beyond that. No one will remember their exact movements 5 minutes in the past so interpolations are less likely to uncanny vally, and the cost for storing 5 minutes at max fidelity is not that high as you yourself identified.

James Hofmann
profile image
Variable sampling resolution makes it harder to test for exploitable glitches. For example, if a character jumps over a wall, and then the time is reversed at a low enough sample rate, the character will interpolate through the wall. Then the player stops reversal at that moment, and gets that character stuck in the wall.

It could still work if you test to make sure the lowest resolution works, and then upres for the rest, but you're still adding some complexity: Dropping samples from old data makes it more difficult to do delta compression or other techniques that rely on adjacent samples being similar.

Lewis Wakeford
profile image
I suppose certain movements are basically deterministic even in non-deterministic engines. For example if an object falls onto another object and bounces, the objects trajectory would be really easy to reverse prior to the bounce and afterwards, but almost impossible to replicate the exact interaction between the two objects due to the slight inconsistencies in most physics engines. You could store only the frames where a new force (only ones that caused more than negligible acceleration) was applied to the object, because it's easy to reverse the rest when you only need to worry about gravity acting on the object.

Jonathan Jennings
profile image
Very cool Cameron,will you be posting a vid of the finished result. I would love to see what the final product looks like!

Cameron LeBlanc
profile image
I will cover why interpolation works in my next entry. It isn't too complicated, but having some visual aids will help a lot. I will also cover some other points that are brought up in the comments.

For my final post I will make a video, and I might include one before then. I also plan on making the entire project available online, including the source code, after I finish it.