How to manage "Load game" while a file is open?

Started by Monsieur OUXX, Wed 08/09/2021 13:30:12

Previous topic - Next topic

Monsieur OUXX

Hello,
I don't have a specific situation on mind, I'm asking about general best practice.

Let's say you have this :
Code: ags

    File* f = File.Open("file.txt", eFileRead);
    while (!f.EOF) {
      String s = f.ReadRawLineBack();
      //EVENT HAPPENS HERE
    }
    f.Close();



Notice the line "EVENT HAPPENS HERE". I'm talking about random events that almost never happen but could happen.

Two scenarios :
a) On that line, this game gets saved (e.g. through "SaveGameSlot" in another script) and then instantly quits (the player closed the game in Windows).
b) On that line, another game gets restored (e.g. through "RestoreGameSlot" in another script). As a mental exercise we imagine that we restore a previous occurrence of scenario "a".

Question:
If "a" just happened, then do I just have to accept that the file is not entirely loaded into the game's VM, and deal with it next time it gets loaded?

If "b" just happened, then
1) Is f in an undefined state? I guess I can't just continue reading from it.
2) What should I do? Just scrap it and have a mechanism to restart reading the file from the top?

 

Crimson Wizard

#1
In AGS no events may occur while the script is running, and game is only updated at all when the control is given back to the engine, that is using "Wait" and other functions from the "Wait*" group.
Game save and restore cannot occur while any script function is running, this is simply forbidden by the engine.

---

Putting that aside, we may still assume a hypothetical case when you have an opened file stream in script which remains for a prolonged amount of time (as a global variable), and which you read from periodically.

File* object is never saved or restored, and there's a good reason for that, as there's no guarantee that the game was loaded on same filesystem as before. So there's no way to keep reading from it after restoring a save, you wll have to reopen the file again anyway. Whether to try skip data which had been already read or not depends on other factors. For example, do you assume that the file could've changed between save and restore, and how do you want to deal with such case? Is there a real practical benefit in not reading it whole again (like, is it that huge that reading takes lots of time, and so on)?

Thinking about it, I may imagine only one reason to reposition file after restoring a save: if the file's reading position is somehow connected with the game progress.

Of course in that case you must also have a global variable that tells current file position, because it will be saved (unlike the File*).

Monsieur OUXX

#2
The end of your message is overthinking it. I don't really need to reposition the file. I just want to know "what would happen".
You wrote that File* is never saved. So, what happens to the variable f in this situation if the game gets saved then restored in-between some of the repeatedly_execute:

Code: ags

File* f; //global variable

void game_start() {
    f = File.Open("file.txt", eFileRead);
}

void repeatedly_execute() {
    if(!f.EOF) {
      String s = f.ReadRawLineBack();
    }
}


Does f become null? Does it have a value that will make the game crash? Etc.

"Go try it yourself, you lazy bum" is an accepted answer.


Also, you wrote that the game cannot quit in the middle of a script.
So does that mean that the game would hang (or at least refuse to quit) if I clicked Windows' "close" cross while this is running :
Code: ags

noloopcheck void Hang()
{
   while(true) {
      int i; //arbitrary no-op
   }
}

void repeatedly_execute_always()
{
    Hang();
}
 

Crimson Wizard

Quote from: Monsieur OUXX on Wed 08/09/2021 14:45:38
Does f become null? Does it have a value that will make the game crash? Etc.

As far as I know it will be an actual object, but not connected to a real file, so any operation with it will fail. Whether it will fail safely or crash the engine depends on how it's done, which I dont know for sure.
File.Error or File.EOF properties may be the way to check if it's open. But then again, it's best to just reopen it on "game restored" event.

Crimson Wizard

#4
Quote from: Monsieur OUXX on Wed 08/09/2021 14:45:38
Also, you wrote that the game cannot quit in the middle of a script.

I did not write that it cannot quit, I wrote that it cannot save or restore.

I think in theory it may quit, but I don't remember how this is handled on practice. may depend on the engine version too.

EDIT: this does not work in before 3.6.0 and crashes the engine in 3.6.0. I think this is a bug and should be fixed.

SMF spam blocked by CleanTalk