0 votes
by (44.7k points)
edited by

Just curious but if I do this:

<<set $Arr = []>>
<<set $Arr["ArrTst"] = "Arr val">>
<<set $Obj = {}>>
<<set $Obj["ObjTst"] = "Obj val">>

Both will work fine.  However, once I save and load the game, the values of $Obj are reloaded, while $Arr is set to [].  Why don't the values of $Arr get saved?  They're in the game history until you save, so what's the difference?

2 Answers

+1 vote
by (68.6k points)
selected by
Best answer

The JavaScript equivalent of an "associative array" is simply a generic object, not actual instances of Array.  I do not recommend ever using an array that way.

In general, you should never stick non-numeric properties onto an instance of Array.  While it will work at a basic level, that's only because arrays in JavaScript are just objects and that's how objects work.  Nothing actively expects or supports using arrays thus.  That's why non-numeric properties added to arrays aren't restored, because they never get serialized in the first place.


And now to address the W3Schools elephant in the room (from Chapel's answer).

Edit. I was not aware that JavaScript attempted to coerce arrays with non-numeric indexes into objects, though, that is cool.

Arrays are already objects, just ones with a prototype (the Array object) and some very minor special handling.

As far as jamming non-numeric properties onto instances of Array.  Doing so changes absolutely nothing about the array, save for adding the non-numeric properties to it.  Its type doesn't change at all.  Whoever wrote that was very, very wrong (then again, it's from W3Schools, so that should be expected).

W3Schools has been a hive of stupid for, literally, decades (I'm firmly convinced that anything they get right is an accident).  Anyone who wants accurate information about JavaScript, and/or other web technologies, should go to MDN.

by (63.1k points)
In the interest of fairness, that language I used is not accurate as to what W3Schools actually says. They do have a long list of warnings indicating to never ever do that. I just tried it out and was surprised it worked and then misused the term coercion.
by (68.6k points)

Actually, they do say that.  From the first warning under the associative array heading:

If you use named indexes, JavaScript will redefine the array to a standard object.

Which is absolutely untrue.

That error is neither an isolated instance, nor a recent phenomenon (when I said decades before, I was not exaggerating).  Trust me when I say that calling W3Schools a hive of stupid is being more than fair to them.

by (63.1k points)
Ah. So they do. Yeah I have heard some things about them in the past. I'll steer clear.
0 votes
by (63.1k points)

You can't set array properties, or at least you can't set them and have them load due to SugarCube's serialization system. It's kind of a weird thing to do anyway.

If you need some additional info in an array, place it inside an object.


<<set $var to {
    arr: [], 
    otherStuff: 'blah'


on re-reading, I think you might be confusing what arrays do in JS (and therefore SugarCube). Arrays are made up of numbered indexes, not string properties. Example: 

<<set $array to []>>
<<run $array.push("array value")
<<set $array[1] to "another value">>


by (44.7k points)

In JavaScript associative arrays can use named indexes (or "string properties" as you called them).  They're not supported by JavaScript, thus some array methods won't work with them properly, but you can use them and JavaScript redefines them to a standard object.  See here.

I was just curious why both work the same in Twine/SugarCube, except one can be saved/loaded while the other can't.


by (63.1k points)
edited by
That link might be wrong? It specifically says not to do that.

Anyway, I'm not aware of anyway to make a 'real' associative array in JS with all the fixings. I mean, you have objects and maps.

Edit. I was not aware that JavaScript attempted to coerce arrays with non-numeric indexes into objects, though, that is cool.

That said, since SugarCube uses JSON.stringify() to serialize saved data, I imagine that the problem is still related to that, especially if only the save system is acting up.
by (68.6k points)
edited by
See my answer for details about this.