Save Game Progress Feature

Save Game Progress Feature

If character death / restart is a common feature of your game design, and the game itself is likely to be of any appreciable length, you might want to consider incorporating a “Save Game Progress” feature at specific intervals. In longer games especially, it can quickly become very annoying having to restart from the very beginning over and over again, directly impacting a player’s enjoyment of your game.

The following, relatively simple system–based on an idea by ChoiceScript community member @Luxtizer–is one possible solution to this problem.

One important thing to bear in mind is that this system is only a “soft save” for the duration of that web session. The save is lost when the player quits, so his or her next attempt will be from the very beginning.

For a practical example of this system in use, take a look at:

http://vendetta1.webs.com/web/mygame/index.html

PLAYER CHOICE OR NOT?

Decide whether or not to have this feature governed by a player-choice setting (in my game I call this the “Difficulty Level”, with the option to Save Game Progress being considered the lower “difficulty” setting).

If so, you will need to prompt for this decision near the very beginning of the game and set a variable accordingly. In the following example code this variable will be called “save_game” with the default setting of “false”. If the player chooses to save progress for this session, save_game should be *set to “true”, otherwise it remains false.

ADDING LATER VARIABLES

The main downside of this system is that in mygame.js it requires a second variable for each normal one, and in the savegame.txt file used by this system, both variables are again listed (as *set commands). ChoiceScript itself can handle this just fine, but it does mean that whenever you add more variables to your game in future, you need to add it in two places in mygame.js and in two places again for savegame.txt–for every new variable you add. It’s not a problem once you get into the habit of doing so, but it will definitely cause problems if you forget!

MYGAME.JS

In this file, below all your normal variables, you need to repeat the changeable variables and slightly rename each one. I precede the second batch with the simple letter ‘s’ (for Save, cuz my brain likes things simple . . .) but it doesn’t really matter how you choose to do it so long as the variable name is still unique and you don’t confuse yourself in the process . . .

Example:

(Apologies for the messy lines–the forum doesn’t at present properly maintain correct indentation.)

stats = {
--------gold: 0
--------,weapon: 0
--------,shield: 0
--------,armor: 0
--------,sgold: 0
--------,sweapon: 0
--------,sshield: 0
--------,sarmor: 0
};

SAVEGAME.TXT

The savegame.txt file is the one you use (with *goto_scene savegame) to save the current game position, and also to later reset game variables back to the “Saved Progress” point when the character has died (or is otherwise unable to continue from that point). It is governed by the variable save_flag, which you will *set accordingly elsewhere prior to jumping to this file (examples further below).

Example:

*if save_flag = 1
–*set sgold gold
–*set sweapon weapon
–*set sshield shield
–*set sarmor armor
–*goto endsaveloadgame

*if save_flag = 2
–*set gold sgold
–*set weapon sweapon
–*set shield sshield
–*set armor sarmor
–*goto endsaveloadgame

Quite simply, what the above does is switch your variable settings based on whether you’re “saving” (2) or “resetting” (1) the game.

Below those two lists of *set commands, you need a screen to inform the player of the new Saved / Reset status, and to redirect the game to the correct scene_name.txt file in order to continue. My example follows–just reword the text as you like and change scene_name parts accordingly.

*label endsaveloadgame
*page_break

*if save_flag = 1
–*set save_flag 0
–PROGRESS SAVED . . .

–Should you die during the next Chapter you will have the option of trying again
–from this exact point, or to replay the game from the very beginning.

–Please note that this option applies only to this session. After quitting the game,
–the next time you play will be from the very beginning.

–Are you ready to begin
–*if return_to_scene = “chapter1”
----Chapter One?
–*if return_to_scene = “chapter2”
----Chapter Two?
–*if return_to_scene = “chapter3”
----Chapter Three?
–*choice
----#Yes, I’m ready.
------*if return_to_scene = “chapter1”
--------*goto_scene chapter1
------*elseif return_to_scene = “chapter2”
--------*goto_scene chapter2
------*else
--------*goto_scene chapter3

*if save_flag = 2
–*set save_flag 0
–GAME RESET - START OF CURRENT CHAPTER

–Are you ready to resume from the beginning of
–*if return_to_scene = “chapter1”
----Chapter One?
–*if return_to_scene = “chapter2”
----Chapter Two?
–*if return_to_scene = “chapter3”
----Chapter Three?
–*choice
----#Yes, I’m ready.
------*if return_to_scene = “chapter1”
--------*goto_scene chapter1
------*elseif return_to_scene = “chapter2”
--------*goto_scene chapter2
------*else
--------*goto_scene chapter3
----#No, I want to start again from the very beginning.
------*ending

Note that I use a variable called “return_to_scene” to store the scene filename it needs to *goto_scene after savegame.txt. You will need to use something similar and add it your own list of variables.

Likewise, I name my scene files (e.g.) “chapter1.txt”, “chapter2.txt”, etc. You will need to modify the script above to suit your own scene file names.

SAVING CURRENT GAME PROGRESS

To save the current game progress at any point in one of your scenes, you need to insert the following at the desired point. This is probably best at the end of each significant scene_name.txt file. For example, at the end of chapter1.txt you would put the following, which then forwards the game to chapter2.txt after saving the current position and informing the player it has done so.

*if save_game = true
–*set save_flag 1
–*set return_to_scene “chapter2”
–*goto_scene savegame
*else
–*finish

Note that in this case, if the player has not previously opted to save the game, it will *finish instead and automatically move on to the next scene_name.txt file in your mygame.js list of scene files, as normal.

RESETING THE GAME TO LAST SAVE

At any point in any scene where the character might die (or be unable to continue in the game for any other reason) you will need to insert the following script to reset the last-saved game position and allow them to restart from that point.

Reword “Restart Chapter Two” accordingly as this is what it will say on the player’s continue / next button.

*if save_game = true
–*page_break Restart Chapter Two
–*set save_flag 2
–*set return_to_scene “chapter2”
–*goto_scene savegame
*else
–*ending

Note that in this case, if the player has not previously opted to save the game, it will *ending instead and automatically restart him or her at from the very beginning, as normal.

VARIABLES TO ADD TO MYGAME.JS

To use this system exactly as described above, the following variables need to be added to your mygame.js file:

save_game: false
save_flag: 0
return_to_scene: “”

None of these need to be included in the list of saved / changeable variables in savegame.txt, and in particular save_flag most definitely must not be, as that one controls this system.

DISCUSSION

If anyone has anything they would like to add, or possible improvements to suggest, please feel free.

2 Likes

Thanks for posting this! I’ll look it over this weekend to see if there’s any way to improve it, but on a quick perusal, it looks like the best implementation possible.

Thanks for posting this as I was going to add a save function to “Unnatural”.

What I had come up with is the idea to have the death scenes in the same file as the episode then just have a [*page_break Restart followed by *goto episode_start] the only issue with this idea is the player will start the chapter with the stats they had when they died so they could become overpowered.

For ‘The Race’, I had chapter saves, where if you died (or were out of the race) you could restart from the beginning of that chapter. Thankfully, the stat changes were minimal so easy to look after.

For ‘Blackraven’, which is much more complex, I’m going for and ‘undo’ feature. Every time you hit a ‘game over’ moment, the game naturally takes you back one move. Hence, your stats are intact and there’s no need for extra variables. I’m toying with the idea of having X lives per play through, meaning if you hit a dead end, you lose a life. Lose too many and it will be game over for real.

@Nocturnal_Stillness You’re most welcome. It looks like we’re going to have more, longer games where character death is a frequent danger so I figured it might be useful to some with less experience, and it’s easier to include early on than add later.

It has limited long-term use where other mediums are concerned (such as iOS devices would probably need a hard save for these games) but for the web it’s better than nothing, and the benefit to community playtesters can be considerable.

@JimD It’s nice to be able to give something back to the community, as I wouldn’t have come even this far without such as yourself, andy and Reaperoa. :slight_smile:

@andymwhy I like the idea, though I’d definitely be inclined towards x-lives for the undo, otherwise you could lose the feeling of danger and suspense if there are no ultimately-fatal consequences to your choices.

Just FYI Vendetta, I’m pretty sure that the hard save function is actually included in the current built of ChoiceScript (from Affairs of the Court). If you want to take a crack at figuring it out. you can open up scene.js and check the last lines. You’ll see a list of valid commands, which include *save_game, *restore_game and *show_password. Personally haven’t had the time/inclination to yet, but you might.

Cool, thanks. Not for the first time, I wish I could actually get my head around JavaScript itself to make all of this easier, but I’ll certainly have a play with those extra commands sometime just out of curiosity. Trial and error sometimes works for me–even if I don’t always immediately grasp why it works . . . :wink: