I'm a pretty experienced JS developer but new to messing with Twine, and I'm trying to build a bit of an RPG system for Twine. I have a number of "complex" JS objects representing various bits of state (with methods and prototypes other than Object) that I want to be able to expose to Twine in $variables, but this is proving problematic as the history/state tracking system doesn't seem to play well with non-JSON-like objects.
I've also tried using SugarCube with history tracking disabled (since for a game it seems like it should be sufficient to store the current variables and the current passage only, which is what that seems to do) but SugarCube's state serialisation mechanism also doesn't preserve the "object-ness" of the objects.
Is there a clever way to do this that's not obvious to me? I have a vague idea of using a window global to store the "interface" objects with the methods defined, but having them keep their actual states in JSON forms in $variables, but haven't managed to get that looking particularly nice yet..
Comments
Can you provide an example of exactly what you're trying to store in $variables?
<<set $player = new Player()>>
in StoryInit and then proceeding to call methods on it in later places like<<print $player.carriedWeight()>>, having previously used a script passage to define, say:<br /><br /><blockquote><code>window.Player = function () {
// constructor stuff goes here
}
window.Player.prototype.carriedWeight() = function () {
// calculate some answer and return it
}
The only idea I have currently is to make the actual constructed objects window globals as well, and have them store all their state in variables instead, by doing something like: and then making sure that the Player code stores all of its state inside this.state instead of directly on this, in a form that's JSON-serialisable, but this seems kinda gross
toJSON()
method to your prototype, which will return a code string that leverages SugarCube's built-in revival code. That will allow automatic revival of your objects.For example, you could do something like this: (you'll need at least SugarCube v0.9.9 for this) All that
JSON.reviveWrapper
does is wrap your code string in a bit of sugar that makes SugarCube automatically execute your code string on deserialization.I've attached an example TWS showing full working example of something like the above.
PS: Never use the
SugarCube
global object in code. It's there to expose some of the internals for developer inspection (debugging). Code executing inside has absolutely no reason to use it (especially since it doesn't export everything).