this is comprehensively wild. does the programming language have a name? it compiles to native code? does it use a compiler backend or did you also implement that from scratch?
I’ve had quite a hard time posting this comment. it keeps saying “your comment appears to be spam”.
also please can you unarchive your old blogs on 2dboy? they have really cool stuff like the world of goo betas and prototypes and currently you need to use Internetarchive
Very cool demo, came away with a bunch of questions.
* Is the act of rewinding/fast-forwarding itself recorded?
* If you rewind far is it loading a snapshot of state, or is it rapidly playing back all the inputs from the start and that just happens to be fast enough to be realtime? Or a blend? Dumping a full snapshot seems like it could be slow with lots of state, but a long session that crosses levels and requires loading lots of assets seems like it could be slow to playback as well?
* You show how the code reverts when you rewind. Can you then edit the code, in effect “forking” the history?
* Did you implement your own lang -> x86/arm compiler or are you leaning on something like LLVM?
The act of going forward and back is not itself recorded – just the evolution of the game’s state.
The snapshots happen according to 2 different schedules – a coarse grain schedule that records a new snapshot every so often based on time (we do every 2 minutes currently) and a fine grain limited set of snapshots that move around depending on where you are currently working on the timeline. That’s why the initial reverse debugger step causes a brief pause and then becomes fast – the first one seeks back to the most recent coarse grain snapshot, simulates forward creating fine grained snapshots that are exponentially spaced out backwards from your seek target, and then the subsequent steps will tend to have a snapshot that is right on the frame you need (or very close – unless you step back far enough to need to go create more snapshots but that is the rare case.)
The state capture is mostly just a memcpy of the game’s heap (snapshots only happen on frame boundaries so the stack is never needed.) It for sure could be too big to keep as many snapshots as we currently do – that will just be game dependent. Something to use to calibrate what you expect is possible though is to remember that games like Metroid Prime, LOZ The Wind Waker, RE4, Mario Sunshine, etc. all ran on a system that basically had 24MB of RAM to use for your game. And it wasn’t just game state filling up that 24MB, it was your code and other read only resources – the kind of stuff that we don’t have to include in our snapshots. So while it’s true that this system is not a general purpose solution for any and all kinds of games, it’s also true that you can make some pretty incredible games with not a ton of actual game state.
Yes in theory you could totally fork the timeline in the past and create a new session based off of the old one up to that point. That is a feature that I had in the reverse engineering debugger I made before this because it was good for creating what were basically tool assisted speed run videos for code coverage purposes. For our current system though it hasn’t been something that I thought we would actually use enough to justify spending the time to implement it.
The code gen is totally custom but keep in mind that this toolchain only needs to run on our development platform which is Windows. To ship the finished game we will transpile the code to C and then compile it with the native toolchains on whatever platforms we’re targeting.
You mentioned that Human Resource Machine was ported from something else to your current toolchain. What was the previous toolchain? Just plain ol’ C/C++ or a script VM or something?
This is absolutely amazing. I would love to see more about how you got the entire system so well integrated.
this is comprehensively wild. does the programming language have a name? it compiles to native code? does it use a compiler backend or did you also implement that from scratch?
I’ve had quite a hard time posting this comment. it keeps saying “your comment appears to be spam”.
ah, it appears that didn’t like that my website’s TLD is “.xyz”.
I’m glad you guys have published something for once lol, I always wondered how you made world of goo in whatever the hell SDL is.
make world of goo 2 xx 🙂
also please can you unarchive your old blogs on 2dboy? they have really cool stuff like the world of goo betas and prototypes and currently you need to use Internetarchive
Very cool demo, came away with a bunch of questions.
* Is the act of rewinding/fast-forwarding itself recorded?
* If you rewind far is it loading a snapshot of state, or is it rapidly playing back all the inputs from the start and that just happens to be fast enough to be realtime? Or a blend? Dumping a full snapshot seems like it could be slow with lots of state, but a long session that crosses levels and requires loading lots of assets seems like it could be slow to playback as well?
* You show how the code reverts when you rewind. Can you then edit the code, in effect “forking” the history?
* Did you implement your own lang -> x86/arm compiler or are you leaning on something like LLVM?
The act of going forward and back is not itself recorded – just the evolution of the game’s state.
The snapshots happen according to 2 different schedules – a coarse grain schedule that records a new snapshot every so often based on time (we do every 2 minutes currently) and a fine grain limited set of snapshots that move around depending on where you are currently working on the timeline. That’s why the initial reverse debugger step causes a brief pause and then becomes fast – the first one seeks back to the most recent coarse grain snapshot, simulates forward creating fine grained snapshots that are exponentially spaced out backwards from your seek target, and then the subsequent steps will tend to have a snapshot that is right on the frame you need (or very close – unless you step back far enough to need to go create more snapshots but that is the rare case.)
The state capture is mostly just a memcpy of the game’s heap (snapshots only happen on frame boundaries so the stack is never needed.) It for sure could be too big to keep as many snapshots as we currently do – that will just be game dependent. Something to use to calibrate what you expect is possible though is to remember that games like Metroid Prime, LOZ The Wind Waker, RE4, Mario Sunshine, etc. all ran on a system that basically had 24MB of RAM to use for your game. And it wasn’t just game state filling up that 24MB, it was your code and other read only resources – the kind of stuff that we don’t have to include in our snapshots. So while it’s true that this system is not a general purpose solution for any and all kinds of games, it’s also true that you can make some pretty incredible games with not a ton of actual game state.
Yes in theory you could totally fork the timeline in the past and create a new session based off of the old one up to that point. That is a feature that I had in the reverse engineering debugger I made before this because it was good for creating what were basically tool assisted speed run videos for code coverage purposes. For our current system though it hasn’t been something that I thought we would actually use enough to justify spending the time to implement it.
The code gen is totally custom but keep in mind that this toolchain only needs to run on our development platform which is Windows. To ship the finished game we will transpile the code to C and then compile it with the native toolchains on whatever platforms we’re targeting.
You mentioned that Human Resource Machine was ported from something else to your current toolchain. What was the previous toolchain? Just plain ol’ C/C++ or a script VM or something?
Plain ol’ C/C++