Rundown: I'm making a twine rpg and a core feature of my the game is being able to transfer gold and items between characters. I implemented a simple custom saving system that autosaves into a specific save slot using the following code (the save slot is chosen by the player at the start of the game):

I then implemented a common "stash" that enables the player to transfer gold between saved characters using a simple <<remember>> macro, and forcefully saving the game immediately after executing a gold transfer (to prevent unlimited gold duping).

The following code works beautifully. I was able to both deposit and withdraw gold using the common variable $stash_gold.

Now my primary problem is making the same thing happen with an array of objects. Simply put, my RPG has a lot of equipment: Swords, Shields, Armor, etc... and each is an object with its own properties. All these items are stored in an $equipment array. When I try to replicate the stash_gold method above, i.e. using the following code:

I successfully transfer said Object into the $stash_equipment array. Upon restarting my browser and using the "Debug" feature to view the variable library, I still see the object and all its properties in the $stash_equipment array. HOWEVER, when I load another saved character, the array simply VANISHES.

I checked my entire game's code thoroughly and I did not find any code snippet which modifies the $stash_equipment array in any way except the following code at the top of the "Stash" passage:

<<if ndef $stash_equipment>><<set $stash_equipment to []>><</if>>

Sorry for being long winded and very newbie-ish, but I've been wrecking my brain trying to figure out a solution to this problem. Am I doing it the wrong way? Can the <<remember>> macro remember Objects within arrays?

1 Answer

Also, a couple of other things—though they likely have nothing to do with your primary issue.

1. You don't need the slot metadata variables. Since you're manually saving, you may specify both a title and metadata for the save, which you may access later. For example, to store the metadata as-is:

<<set _temporary to $equipment.deleteAt(0)>>
<<remember $stash_equipment to $stash_equipment.concat(_temporary)>>
/*
You really don't need the temporary variable here,
so the following also works.
*/
<<remember $stash_equipment to $stash_equipment.concat($equipment.deleteAt(0))>>

Sorry for the late reply, TME. Was busy with work. Noted on using the .deleteAt(). Will use that instead.

When do you run the code to store items in the equipment stash?

When I click on an arrow in a passage called "The Stash". It has some complicated code so i'll just explain with a picture. I used some basic "onclick" javascript to determine which object they want to transfer (it sets the $equipmentslot variable to a specific number representing the object's position in the array, then clicking on the arrow runs the following code (note that I will modify it later according to your recommendation with the deleteAt() instead):

I basically use the .pluck method to remove the selected object from the desired array as shown in the code above.

I'm just trying to figure out WHY the $equipment_stash array just doesn't seem to <<remember>> its properties after loading a game. The objects persist on browser resets and restarts, but it does not persist when i manually "load" another character.

Edit: Okay... i figured out that loading a Saved Game also loads the current state of the variables at the time of the save (Well, duh...) and thus overwrites the $stash_equipment variable even though it was "remembered". Is there a better approach to trying to get variables and arrays to persist through saves? Like perhaps storing a variable's data in an external place and then loading it upon Loading a game?

Since you were attempting to use <<remember>> (generally a bad idea), I'm assuming you want the stashes to be persistent (i.e. closing the browser shouldn't cause the data to be lost). Warning: Browsing modes like Private/Incognito always cause session data to be discarded at the end of a session!

For the purposes of multiple characters in separate playthroughs (in the same browser), you could store your various stashes using SugarCube's (undocumented) storage subsystem. It's undocumented mostly because it's possible to clobber SugarCube's own data, which would be bad for your game. That said, as long as you keep your stashes named things like stash_equipment and stash_gold you should be safe.

Move equipment to stash example:

<<script>>
// Get the existing stash or initialize it to an empty array.
var stash = storage.get('stash_equipment') || [];
// Cache the story variables store.
var sv = State.variables;
// Remove the equipment at the selected index from its array and
// append it to the stash array.
stash.concat(sv.equipment.deleteAt(sv.equipmentslot));
// Set the stash.
storage.set('stash_equipment', stash);
<</script>>
<<autosave>>