1
\$\begingroup\$

I'd like to ask you, since most of you have some or a lot of experience in writing games. What is your approach to running scripts and saving game state when script is executing when there is a chance that some resources (in worst case - a script that is executing) are changed (new mod installed or game is updated)?

From what I gather most prevalent approach is to prevent saving in such cases (for example in Skyrim one can't save if some long running script is executing, e.g. when one of daedra princes (or princesses or whatever) speaks his/her lines) and organize all other things (AI in particular) in a small, atomic functions.

But maybe there are other approaches?

EDIT:

I think that there is a misunderstanding here. Assume the following: - when new game is started, a script is run. It reads as follows in hypothetical language:

func main() {
    i = 0;
    while (true) {
        i++;
        if (i < 100) {
            yield();
        } else {
            i = 0;
            user.write("Hi, 100 frames passed!");
        }
    }
}

Script is started once, it calls 'yield()', it's state is saved and other things are done. Now next frame starts. Script is called again and continues (so next line after yield() is executed) and continues until yield() is called again. After some time user saves game and exits program. I assume that scripts state is somehow serialized ('how' is a separate issue, but it's definitely doable). Later, user starts game again, installs mod downloaded from the internet, launches game and loads saved game state. But mod changed this very script that was currently restored.

Now, my question is: what are common solutions to this problem? I assume that such long-running scripts could be serialized in their binary form (that is, list of opcodes and state of virtual machine, it's stack and registers) which would mean that changing them has no effect, but this is only my own approach. From your practice, how is it solved/approached/mitigated?

\$\endgroup\$
1
\$\begingroup\$

If there is a chance that a script can update and change a value while you're saving, your application is not thread safe.

You would have to synchronize and pause all threads/activities/simulation while you perform a serialize of all relevant information. Only after the serialization is done can you let the simulation progress, although you are free to write to the disk after resuming, you may wish to wait for it to complete.

Ideally all game logic will ultimately be called from a single thread, the "main game loop." In Unity this would be Update() (and I think, FixedUpdate()). As long as the save action happens between executions of these methods, then there is no need to pause the game (set timeScale to 0, or whatever) as the entire serialization process will occur between steps.

For other engines, other tactics may be necessary. But a good method would be to pause the game via some global flag that every update function goes "oh, its paused" and does nothing (I've done this in Flash), which combined with some kind of user-friendly GUI (main menu, etc.) that already pauses the game, you're free to serialize the game's state without having to worry about those "chance updates." Unless, of course, your game is not thread safe. ;)

\$\endgroup\$
  • \$\begingroup\$ Thank you for your answer. It seems that my question wasn't phrased properly. I added some explanation to it. \$\endgroup\$ – Jędrzej Dudkiewicz Jan 15 '16 at 14:46
  • \$\begingroup\$ @JędrzejDudkiewicz Your edit includes a yield() call. Yield causes the function to be a coroutine and thus threaded. Example is not thread safe. ;) \$\endgroup\$ – Draco18s Jan 15 '16 at 14:48
  • \$\begingroup\$ Yes, but it's only dependence on external world is call to hypothetical "user.write()" method, which can be as simple as sending event for later processing. So when this script is serialized/saved, the worst that can happen is that it's code will be changed by update or installed mod. What then? \$\endgroup\$ – Jędrzej Dudkiewicz Jan 15 '16 at 14:55
  • \$\begingroup\$ @JędrzejDudkiewicz I do not understand what you mean by "the worst that can happen is that its code is changed." \$\endgroup\$ – Draco18s Jan 15 '16 at 14:57
  • \$\begingroup\$ I guess my edit still doesn't explain things enough. I have a game with an ability to serialize running scripts. I hit "save game", everything is saved. If some script that runs for multiple frames is executing, it's state is serialized. Now user somehow changes this script when game is not running. It no longer counts to 100 but to 200. What to do in this case? What approach is preferred? \$\endgroup\$ – Jędrzej Dudkiewicz Jan 15 '16 at 15:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.