JSON-based save / restore

A while back there was a discussion about cross-release saves in TADS 3. As a sort of down payment on that idea I’ve put together a serializer extension that overrides the built-in save & restore functions to use a JSON format text file.

You can get the files from my T3 Extensions repository. You’ll need intrinsic.t, json.t, and serialize.t.

With those in place, you can mark objects and properties to serialize like so:

journal: Thing, Serializable 'journal' 'JOURNAL' @bedroom
	desc = "An old journal. "

	testNil = nil
	testTrue = true
	testSString = 'test'
	testList = ['x', 1, rock]
	testInt = 803948
	testProp = &testFunc
	testEnum = muffin
	testFunc = testSum

	serialProps = [&location, &testNil, &testTrue, &testSString,
				&testList, &testInt, &testProp, &testEnum, &testFunc]
;

testSum(a,b) { return a+b; }
enum muffin, cupcake, pastry;

The object must inherit from the Serializable class, and it must set the serialProps property to a list of property pointers to serialize.

You can serialize any named object and any property that holds a stable value.

Methods aren’t allowed; a method is an object property that points to some executable code, so even though it has a name it doesn’t have a value that can be serialized. Anonymous objects are the other way around; their values can be serialized but without a name associated, the restore process wouldn’t know where to put the data.

The output will go in a file called .json and will look something like this:

{ "D9D0EB9F-6951-4C1F-8F50-983BA3C23E26": { 
"journal": {
	"location": { "type": "TypeObject", "value": "bedroom" },
	"testNil": { "type": "TypeNil", "value": null },
	"testTrue": { "type": "TypeTrue", "value": true },
	"testSString": { "type": "TypeSString", "value": "test" },
	"testList": { "type": "TypeList", "value": [
                { "type": "TypeSString", "value": "x" },
                { "type": "TypeInt", "value": 1 },
                { "type": "TypeObject", "value": "rock" } ] },
	"testInt": { "type": "TypeInt", "value": 803948 },
	"testProp": { "type": "TypeProp", "value": "testFunc" },
	"testEnum": { "type": "TypeEnum", "value": "muffin" },
	"testFunc": { "type": "TypeFuncPtr", "value": "testSum" }
} } }

Right now this is more of a tech demo than anything else. Please don’t release a game that relies on this code for save and restore!

adv3 is full of state - the current player character, the current item in a shuffled list, an NPC’s available conversational topics - and right now the only serialized property is location, for Thing and its subclasses. I plan on improving that over time, as I develop my own game, but I could really use some help.

A final point to mention is that the JSON parser is largely independent of the serialization logic. It takes JSON text and turns it into an internal data structure (a list of lists). What that structure means is up to the game to decide. Here it’s a list of objects, properties, and values, but it could be anything.

I have some hope that this will be useful in the context of HTTPRequest and Web UI, as a way for JavaScript and the TADS 3 code to share structured data. I’d be interested in hearing from anyone who tries it.