Extending Save/Restore with Custom Data

From another discussion someone was asking about storing data that would cross story file versions. We know that if you alter your story and compile it, previously saved games will not work with the new story file.

I started thinking about this and poked around I6 for a potential implementation, but I have questions before I do anything. Or, I have a set of requirements, hoping they can either be validated or shot down…

Provide an I7 extension called “External Storage”:

  • has simple syntax for storing data, for now key/value pairs (let’s leave serialization/deserialization of objects off the table for now (or forever)
  • replace Save/Restore
    • on save, append the external storage data.
    • on restore, slice off appended storage data.
    • after restore is completed
      • restore key/value pairs (the author would have to provide the mechanism to actually make this restored data useful)

The author would be to be able to:

Check saving the game:
write the strength of The Minotaur to external storage;
write the health of The Minotaur to external storage;
write the wisdom of The Minotaur to external storage.

Report restoring the game:
read the strength of The Minotaur from external storage;
read the health of The Minotaur from external storage;
read the wisdom of The Minotaur from external storage.

And this data would simply be appended to the save file as a list of key/value pairs.

Obviously if the author changes “The Minotaur” to “The Cyclops”, that’s a breaking change. Or if any of the existing properties of The Minotaur are changed, that’s a breaking change. But this could be a useful way to enable cross-version support for save files.

Thoughts?

Kerkerkkruip does something similar, with our key/value persistent data extension: github.com/i7/kerkerkruip/blob/ … 20Data.i7x

I think a more extensible system should use JSON. It wouldn’t be overly hard to build a JSON implementation in Inform 7 - especially if floats could be left out initially, but they would only be a little more complex to implement if needed. It would be both forward and backwards compatible - the biggest issue would be files growing massively. When I’ve thought about how to do such an extension, the easiest way would be to copy the whole file at once into memory.

The one thing I think that would be essential is appending the data to the save file and not creating new files. Would we have to alter the underlying interpreters to enable this?

Oh, I missed that.

For the extra data not to confuse other interpreters it shouldn’t just be appended, but added as an IFZS chunk. It wouldn’t need interpreter changes because an IFF parser could be written in Inform, but it would take an extra amount of work. Two files would be much simpler.

Two files is easier, but for the user, knowing there are two files to track is not easier. Adding IFZS chunks is the optimal solution.