Plan for new save format

From OHRRPGCE-Wiki

Jump to: navigation, search

The current save format is a big binary file with fixed offsets. it is pretty messy, wastes a lot of space, and is inconvenient and bug-prone to extend.

A new save format would accomplish the following goals:

  • Easier to extend while maintaining back/forward compatibility
  • Each save slot should be one separate file (or folder?)
  • Each type of save data should be a separate lump (or file?)
  • Space should be provided for optionally storing things which are not already stored
    • saved NPC state
    • saved map state
    • the script interpreter state: all currently running scripts
    • other script object state such as strings or slices
  • Some provisions should be made for RPG file upgrades obsoleting certain SAV data (this is a problem in the current SAV format for things like shop stock and hero spell lists)
    • It is possible that this could be as simple as a game-specific version number that could be used to display a warning message about possible bugs when opening SAV files created with older versions of the same RPG file.
    • Some of the items above, like script interpreter state, are going to be impossible to recover if the relevant game data (ie compiled scripts) has changed in the slightest, unless maybe a copy of the old data is available for examination (eg temporarily load old instead of new copy of script).
    • It might make sense to store some kind of checksum or hash of this sort of upgrade-volatile data so that it can be invalidated if necessary at load-time.
  • Old SAV files need to be convertible into the new format.
    • The import globals and export globals commands will need to be re-written for the new format.

[edit] A proposal

Save game data will be a collection of files in a specially named subdirectory. On Windows this will be inside %APPDATA%\OHRRPGCE\GameName\ and on Linux it will be in $HOME/.ohrrpgce/GameName/ (see the prefsdir global var for access to this location)

Inside that location would be a folder named saves and inside that would be numbered folders, one for each save slot. So for example, save slot zero for Wandering Hamster being run by a user named Fred on Windows XP would be something like:

C:\Documents and Settings\Fred\Application Data\OHRRPGCE\wander\saves\0\
File Description
version.bin Contains the game's version number (optional: incremented by the game author) Obsolete game version number would show a warning before loading to tell the player they are using a sav that may contain incorrect data for the new version of the game. (We might be able to provide a plotscripting hook for this situation, so game authors can write "on load" scripts that automatically correct for this sort of thing)
fixbits.bin This would keep track of SAV format upgrades, much in the same way that the similarly named Fixbits.bin RPG lump tracks format changes. Changes to the format can be automatically applied when loading.
README.TXT A plain text file explaining that this folder is an OHRRPGCE Save-Game, and include a link to the documentation. Mentions that files manually created in this directory might be deleted when saving.
state.bin Contains misc things like current map, hero positions, random battle counter, camera position, money
gen.bin Contains the saveable parts of the gen() global
npc.bin Contains NPC locations for the current map (see SerNPCL code)
map#_?.bin Map saved state in the same format that is used on a temporary basis (Note that the current temporary format takes twice as much space as necessary, presumably we'd get around to fixing it).
tags.bin Store tags
onetime.bin store one-time-use tags
heroes.bin stores the state of the heroes in your party, including ID, name, stats, spell lists, current picture, palette, default weapon, level, experience, equipment, swap locks, current bitsets (nativehbits() array)
inventory.bin stores the party's inventory of items
stock.bin stores the available items for shop stuff that has limited stock.
globals.bin stores script globals (integers only)
vehicle.bin stores state of currently active vehicle
plotstrings.bin Plotstrings: other state such as postion and color for each string
slices.bin (*) Store state of slice tree (but what if a slice has a modified graphic, supposing that we ever add such support?)
scriptobjs.bin (*) Persistant storage of all non-integer script variables, including things like NPC extras, eg. strings, arrays, user defined objects. Would probably be same format as the lump doing the same thing in .RPG files.
scrinterpret.bin (*) A resumable dump of the script interpreter's state.

(*) - Currently only very wishful thinking

The above should duplicate everything that the old .SAV format can store, plus a little, and it should be easy to extend.

[edit] Sharing Data Between Games

Based on discussion, the best way to do this would probably be to allow games to read the globals of another game, either by ID number, or by name, or both. With the Plan for dynamic types in HamsterSpeak this will allow for sharing of not just integers, but also more complex data structures.

[edit] before-save scripts

A "before save" script trigger should be provided. As an argument it would get the slot number that the player has chosen to save into. This would make it easy for game authors to tie together the saving of shared data with the normal save system. (although there is no reason why shared data couldn't be read or written at other times too)