Logistics for a cross-release save

Couldn’t the save-game format be put into an actual format like XML or JSON? XML tags named after the variables, etc. that it holds values for would provide some protection even when the coder adds or removes variables in new releases, and the typo-fixing re-release would be perfectly fine.

I understand that any system is going to require the author to do some hard work. I just feel that having the infrastructure built into the IF system, rather than tacked on as an afterthought, is most likely to produce an efficient, easy to use system.

On the other hand, though, efficiency is probably mostly going to depend on saving the absolute minimum of information necessary, and that’s something only the author can know. I guess it’s probably best at this point for authors and extension programmers to work on the problem. If we find that we need extra support from the language/VM, then we can put in a specific feature request.

(Off topic for this part of the forum, but on reflection I think it shouldn’t be too hard to build a simple cross-release compatible save system in TADS 3. Include reflect.t so you have access to the source code names of objects and properties even after the game is compiled. Create a list of object properties that need to be saved and restored. Offer hooks where the author can manipulate the data before it’s saved and after it’s restored, so s/he can manually deal with any problematic incompatibilities. Knowing which of the library objects’ properties need to be saved would be tricky just because of the size of the library, though. Darn, I’ve got myself interested in the problem now. Putting it on my post-Comp to-do list.)

In any case, your suggestion of bundling the old game file sounds like a good compromise - it’s easy for authors to opt into, and it gives the player a clear choice.

Yeah, I like the idea of bundling old versions, too, except it doesn’t exactly encourage rapid iteration. Even with small games, that’s likely to get too bulky. (Also, as a player, I don’t want to download 30 versions of a game when one will do.) It’s probably good for small games with significant releases, though. I love the idea that it would be easy to tell which version of a game your save belonged to; is that information readily accessible to players currently?

I think a modified checkpoint system is workable for my game - it wouldn’t be perfect, but it would get players 80% of the way there (with way less than 20% of effort on my part).

Save files contain a simple fingerprint that identifies a particular game file. (The details are in the Quetzal spec (5.4) and the Glulx spec (1.8.4).)

An interpreter can look at a save file, and then look through a batch of game files, and find the game file that matches.

If the interpreter doesn’t have access to the matching game file, the problem is harder. There’s no IFID, so the interpreter can’t just go download the right game. It can find the release number and serial number, which are probably sufficient to display a message to the player. (“Please go find release 6, serial 12346”)

This has been on my want list for YEARS, mostly because it’s an unofficial industry standard when it comes to other types of games.

I think Emerald’s idea is the schiznit. That sounds achievable. Too bad it’s in TADS, not I6, though. Gravel’s checkpoint system also sounds workable.

If we can decompile games, I’m not sure why that couldn’t be done to get at the variables / data types. Heck, I’d be open to something like: “You must declare your variables/objects/etc in this space or in this manner so that the language can get at them later.”

If anyone needs someone to beta-test their stuff, I’m open. I could probably help out some with the coding if you wanted to split it up.

Not that it makes any less work for the author, but I’ve seen games where checkpoints give you a password, sort of like a cheat code. Once you have the code, you can skip right to that point in the game. The player has to remember the code, but they don’t have to have a save file available when they restore.

It’s an interesting problem. For TADS, at least at the source code level you can distinguish between writes to locals (which generally do not affect state) and writes to properties (which generally do.) I can imagine a compiler that wrapped any writes to properties with a serializing function that would hash the most recent value. Then you could write that hash table to disk on save and read it back in during restore.

There are problems with this for non-integer assignments. For example, when you write a new string to a property, you are really updating that property with a pointer to an address in memory (somewhere in the VM string pool). Those addresses are probably quite dependent on source code order; I doubt the compiler makes any effort to give the same string the same address during a subsequent compilation. So even in the case where you changed just a few lines of logic in a function, your strings could end up stored at different addresses. Restoring a game from an earlier version might work fine, but it might also scramble descriptions or crash the VM.

The same issue holds for object assignments. Reflection helps here somewhat, since you could serialize the source code name instead of the object address, but it would break if you rename the object at the source code level. This might be OK if the library throws an exception (serialized object not found) - the author can add error handling in the restore code to swap in a different object and resume the restore. However you would need a Q/A pass on each release, testing with a variety of saved games, to feel confident that you had found those issues.

I don’t know how it would work with anonymous function assignments, or dynamically compiled code. Anonymous functions are actually objects, so it might wind up as a special case of the above, except with more wrinkles. BigNumbers could probably be turned into strings. Lists and vectors could (and usually would) contain object or string references, and would need special handling. More special cases, more wrinkles.

As an author I wouldn’t use the system without the sort of automated library / compiler support I’ve described. As a programmer I’m not persuaded that the problem is tractable. But I’m certainly happy to talk about it. :slight_smile: