Manual Save System in Chapbook

Twine: 2.7.1
Chapbook: 1.2.3

I’m writing a rather long story in Chapbook, and came to the realization that I’d like to give players the ability to manually save their progress. Chapbook doesn’t immediately support this, and as far as I can tell, nobody else has raised this question yet. I thought of asking this forum how I might go about making it possible—then realized right away how it could be done.

I’m using two separate passages to construct a save system. What I want to do is save the state of all the game’s variables, as well as the passage that the player saves on. Certain passages in the game will act as checkpoints; on these passages, the footer displays a link to the passage which acts as the first half of the save system. I named it the save panel. In it, every variable I want to save is given an identical equivalent. I’m doing this by means of a hugely original naming system. Example: save.variable: variable. Once the player navigates to this passage, the state of all the game’s variables is captured this way.

But then how do I record which passage the player came from, so that they can be returned to it when they load a save? Through the variable save.checkpoint, which has a unique value for each possible checkpoint passage where the option to save progress is presented. I set it up the same way as the other variables, with checkpoint set in the vars section of the checkpoint passage, and save.checkpoint recording it.

So let’s say the player reaches an ending of the game, maybe an unsatisfactory one. Or maybe completes the game and wants to go back to make some rash decisions. They decide that, rather than playing through perhaps half of the game, they’d like to load their saved progress. The title screen will have the option to load a save. But note: the first passage of the game is not the title screen, it’s a short bit of introductory text that links to the title screen. In this first passage, save is set to false. The “save panel” passage sets it to true. So if the player hasn’t saved any progress, there won’t be any option on the title screen to load a save. If they have, then there is!

Great. How do we actually load a save?

That’s where the second half of the save system comes in. The loading passage takes all those save.variables and converts them back into variables. Based on the value of save.checkpoint, it displays a link to the passage from which the save data was taken. I also set up some flavor text based on the values of other variables, to provide a bit of context for players returning to the situation of that passage.

Some of this still needs to be tested ingame. And a note: none of the checkpoints have vars sections which modify any game variables—because, otherwise, upon returning to them by loading a save, it would be like playing the passage twice. I don’t want those variables to be modified a second time, which would throw off the player’s progress.

There’s almost certainly an easier and more streamlined way to create a manual save system here. But I think it says something nice about Chapbook that I was able to construct one entirely within the confines of its native capabilities.

1 Like

Besides the Objects and Lookup Variables listed in the Chapbook documentation, its engine exposes an undocumented variable named trail.

This undocumented variable references a JavaScript Array that the engine uses to track the Name of each Passage visited, in the order they were visited.

So if during the current playthrough only three Passages named Home, Library, and Shops have been visited so far, then the Array in the trail variable will be…

['Home', 'Library', 'Shops']

…and if at that point the end-user transitioned to the Home Passage again, then the trail Array would change to…

['Home', 'Library', 'Shops', 'Home']

So this Array can be used to determine the Name of the Passage currently being visit, as well as the Name of any Passage previous visited.
eg. like the Passage that was visited directly before your “Save” related one.

3 Likes

Chapbook also has the seemingly convenient passage.name variable, which I thought about using, but since it’s not possible to evaluate expressions inside link inserts (such that [[{save.passage.name}]] isn’t viable), I couldn’t figure out a way to incorporate a direct transcription of the checkpoint passage name into the save system.