Considerations of time travel

September 14th, 2011

In my experience, writing code is at most 10% implementing the basic functionality and the rest of the time is spent taking care of exceptions. The same applies to authoring games and to making authoring tools. In the case of Vorple the single most imposing exception is that the stories can be saved and restored later, and in parser IF there’s the UNDO command that rolls the story back one turn.

Undum and Parchment handle save/restore differently. Undum saves the reader’s actions and replays the story from the start when the story is restored. Parchment saves the current story state and at restore jumps directly to that state.

From the UI standpoint these methods are crucially different. Let’s say we have a story where every location has theme music associated with it. When you move to another location the music changes. In Undum the system shouldn’t load and play the theme music for every location the reader had visited previously, just the latest track. And what if there’s a sound effect every time the reader clicks on a choice? If they’re played also when the story is being loaded the reader would hear them all at the same time as a jumble of sounds all mixed together.

That problem is relatively easy to fix: the latest version of Undum has a way to check whether the story is being played normally or replayed by the restoring mechanism. Any elements that are affected by the problem described above can disable themselves during the reload.

With Parchment there wouldn’t be a problem with the sound effects because when restoring the story you leap straight into the situation instead of replaying from the start. The system must instead know the exact state of the user interface at the time when the story was saved. Not only that, but it must also know what to do when the reader uses undo to move back one turn or more.

Let’s take a simplified example of a story where you drive a car and there’s a graphical gauge depicting the current gas level. Every turn the gauge’s needle moves back a notch. It’s not enough to just decrement the value that moves the needle every turn. Otherwise the system doesn’t know where to point the needle when the story is loaded from a save state. Similarly when undoing it must know what was the previous state. It’s not enough to just counter the normal effect by moving the needle to the opposite direction, because the rule is probably more complex than “decrement every turn” (what if the car was stopped the last turn? Or if the gas tank was refilled last turn?)

The solution is to build the UI such that every turn all the information that’s needed to remake the current state is saved into memory. When a leap in time is requested, either by restoring or going back with undo, the UI resets itself and uses the saved information to get back to the previous state.

Getting saves and undo working correctly will probably be the biggest challenge to come. It’s also a challenge to the author, who must take saves and undo into consideration. The simple way out would be to just disable saving and undoing, but that would cripple the player experience more than what the benefits for the author would be.

§ One Response to Considerations of time travel

  • That’s exactly the problem I encountered with Jaiffa: there’s no reasonable way to back up the game state at any one point. I could use a real database instead of a haphazard network of objects, or I could walk said network and serialize everything, but either approach leaves out functions. And in Javascript, functions are values like any other. In fact, the demo game relies on the ability to change code on the fly.

    Luckily, it was never intended as anything more than a toy, otherwise I’d be in trouble. :P