Jump to content
  • Advertisement
Sign in to follow this  

Thoughts on saving state where scripts are concerned

This topic is 4760 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am currently working on a save-game feature, and saving the majority of the game state has proved fairly easy, except for a few issues. One issue is that we use scripts (custom scripting system), to perform actions and events. It should be noted that in our system only one script at a time may be running, but many others may be in a 'wait' state. When a script function is executed it happens 'all at once' (like in C++), however at any point in a script function, the script can be put into a Wait state, wherein it will wait until some event occurs (a timer time-out for instance). When that event happens it will trigger the script's execution again. It is because of this 'wait mechanisim' that we must serialize the state of the scripts into save-games (since somthing could be pending to happen, and if the game is loaded without knowledge of that, it wouldn't happen). Now, my problem isn't saving the state of our scripting system, that is simple as. -save all global variables For All Running Scripts{ -save script file name -save local variables -save script locks(these are the wait conditions) -save execution head position(this is the issue) } My issue is that, by having to save the execution head position (what 'line' of code the current script executed last) it means that if I modified the source script, by adding or removing some code, it would break the save-game. Example(psuedo command structure): assign a to 10 assign b to 20 call function1 <-instruction head at index 2 assign a to 30 asign b to 40 Example(after modification): assign a to 10 assign b to 20 assign c to 100 <-instruction head at index 2 call function1 <-should be at index 3 instead assign a to 30 asign b to 40 This does not seem like a good thing, and I can see it leading to many headaches =) Does anyone have and thoughts, or potential solutions for storing the state without making it so that changing a script's command length (number of commands) doesn't break it? All feedback is welcome, thanks =)

Share this post


Link to post
Share on other sites
Advertisement
Well, there may be a patch(thought this is common to break save games so it isn't much of an issue)

but it is more a case of development, having gotten half-way through a long game, and having to change one thing in any script and have it void all save-games would be very counter-productive for testing.

I am having a hard time thinking about it now, but I am fairly positive there must be a way to express position in a list that grows down, wherein if you know,

last list length
new list length
last list position

then you can discover, new list position

the trick seems to be that items can be added and/or removed before or after the head position

Share this post


Link to post
Share on other sites
After some more thought, it seems that this is somthing I am just going to have to live with.

Even if I could find a way to keep track of where the new head position should be, the potential extent of modification to the script code, could cause potentialy unforseen issues.

so it is probably a good idea to throw an error when trying to deserialize a script if that script's command length has changed. it unfortunetly wont catch all errors (if somthing was removed and another thing added), but it should be enough to catch most of the issues of (why the heck is it doing that? Oh! I modified a script and used an old save-game) so that we arn't going around the preverbial table trying to solve a non-issue.

I am still interested if anyone has any alternative ideas, it is very possible (and probable) that I've overlooked somthing.

Thanks =)

Share this post


Link to post
Share on other sites
I think it's quite acceptable that older savegames might no longer work when the game is updated to a newer version. Anyway, some solutions I can think of are:

- Maybe have some locations in your game where no scripts are waiting, if this is at all feasible. Like, when another chapter/level/whatever is entered, make an autosave at the beginning of that.

- You could always save the whole script an interpreter is executing with its state, of course ;)

- A more complicated method would be to never change a released script, but instead install the updated script in parallel and give the old one a pointer to the new version so it can be switched when excution is finished.

Well, just a bunch of ideas...

-Markus-

Share this post


Link to post
Share on other sites
Hmm some good ideas there.

It seems that a solution to my problem would be to have the save-game include the compiled script itself, so even if the file was changed, it wouldn't reload that file, instead it would deserialize the old(and correct) script's commands.

this would increase the size of the save-game of course, but it would provide protection.

however, if you made a change to the script (during development), you would still need to blow away the save game, since you wouldn't make use of the changed script(you would use the one stored in the save-game).

so it seems the end result is the same, except it takes care of potential errors, at the cost of larger save-game size.

I will have to think on this, thanks =)

Share this post


Link to post
Share on other sites
I believe you can do it using Serializable Continuations. [1][2][3]

If you change the save games, write an old-new save game translator or use the file versioning system you obviously implemented in your file format. You used one, right? [grin]

Share this post


Link to post
Share on other sites
the serializable continuation stuff looks a little bit complicated =)

as for versioning, yes, we 'can' save a version number into a serialized file, however, this version isn't directly linked to anything, that is, when somthing is changed I would have to modify the version number myself.

it seems like the simplest way is simply to save out the instruction head index, and if that breaks save games then so be it =/

Share this post


Link to post
Share on other sites
Without knowing exactly how your scripting system works, I can't say I know of a good solution, but one thing that comes to mind, with a scripting language, is, not only saving the execution pointer, but also a hash (or something) of the contents of that line/command. That way, when you load up that save with a modified script, you search through it for the proper line, update your execution pointer, and continue. If you fail to find the line, throw an exception or something, or restart the script.

Now, while this is a simplistic idea, it's what pops to mind first.

Share this post


Link to post
Share on other sites
The problem is that you could change the script any amount, so any way you could possibly synchronize across changes might be invalidated.

What I would suggest would be some kind of 'diff' that is used to update save files whenever a patch is applied. This 'diff' file would have the information needed to tell the game 'ok, you were executing line X before, but now you need to execute commands _1, _2, and then pretend you were on line Y and resume from there'. This can't work for drastic changes (without a lot of work specifying the _1, _2, etc commands to execute before resuming), but it can allow mostly-automated updating from only slightly changed script.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!