eternaldensity / Sandcastle-Builder

xkcd: 1190: Time: The Game
Other
79 stars 65 forks source link

Save an object as a Boost attribute? #1438

Open charmsRace opened 8 years ago

charmsRace commented 8 years ago

I'm fiddling around with a couple new boosts, but I can't figure out how to save an object as a boost attribute (like how kitkat stores prey). SaveData only takes int, float, and array. I've even tried saving it as a single-element list of the object, but no luck. Is this a thing that can be done with the current saving system? I'm really not sure how to store the data I need to store in a list, at least not in a sane and readable way.

To be clear, I want to be able to have something like Molpy.Boosts['Example'].dict = {'foo': 200, 'bar': 12} persist through loading.

pickten commented 8 years ago

You can use an associative array instead.

charmsRace commented 8 years ago

JS doesn't seem to have dedicated associative arrays; it seems objects are used for that purpose. Of course, everything is an object in JS, but y'know. What am I missing?

pickten commented 8 years ago

There aren't dedicated associative arrays, but there's no reason you can't make your own, either in the format [[key,val],[key,val],...] or [keys], [vals]. You'd have to make a lookup function, but it's easy to do.

charmsRace commented 8 years ago

Blah. I did that, storing the "object" in the form [{key1: x1}, {key2: x2}...], and it still just doesn't work. In fact, I can't even get it to store Molpy.Boosts['Example'].foo = ['bar']. It seems like only numbers are saved in lists. For example, [1, 'foo', 2] gets loaded as [1, 0, 2].

Probably should have done some testing before (re)writing hundreds of lines based on that data structure... Oops.

At this point I would greatly appreciate it if @eternaldensity would step in and let me know where/how the best place to save objects is, if there even is one. I assume he wrote the save/load code.

Worst case scenario, I have to figure out how to encode all of this data as a list, which poses... problems. And lots and lots of refactoring. =[

pickten commented 8 years ago

My suggestion was slightly different, actually from the example you gave. Use actual lists, so that would be [["key1",x1],["key2",x2]...], so then the lookup/change becomes

Array.prototype.lookup(key,new){
for(var i=0;i<this.length;i++){
if(this[i][0]==key){var t = this[i][1]; if(new!=undefined){this[i][1]=new} return t}}
}

or something of this sort depending on what helper funcs you want.

w.r.t. strings not being saved, I have no idea what to do. List of character-codes?

charmsRace commented 8 years ago

Sorry, that's actually what I did, I mis-typed. But yeah, either way, the strings won't save. I'm looking into string/integer conversion... sigh.

deterb commented 8 years ago

Giving a quick look at things, it seems like the cleanest way to support this would be to add JSON as a storage mechanism. I don't think it'd be hard to add, and it'd prevent more hacks elsewhere. I'm not sure how well it'd handle the number ranges used in the game, though it will probably cover your use cases.

pickten commented 8 years ago

JSON works fine with the numbers used since they are all within the JS number range (+/- 2^(1024)), but it would be a pain to do, since there's a lot that shouldn't be saved (e.g. everything in data.js, .limit properties on boosts, .Level on many boosts, etc.). Also, hacks are really not a concern as is. I will try to implement str saving tonight if possible.

Random question though: why do you need obj saving in the first place? Edit: I see it's on your github. I'm looking it over as we speak; btw it might be simpler to save the id of boosts aimed rather than the alias. This eliminates the need for string saving. Also, it would be simpler to use an on-load filter to find all stuffs (.defStuff), rather than a hardcoded stuffs list.

deterb commented 8 years ago

Okay. I was thinking about adding it as something alongside the int, float, and array save types rather than trying to save the entire boost object.

Updating around https://github.com/eternaldensity/Sandcastle-Builder/blob/master/persist.js#L669 and https://github.com/eternaldensity/Sandcastle-Builder/blob/master/persist.js#L363 would cover it.

pickten commented 8 years ago

I see. It's a good idea, and I'll do it shortly; regardless, I just sent a pull allowing string saving. Edit: your JSON idea is now in the pull as well.

charmsRace commented 8 years ago

So I got a bit confused in my last post, so scratch it. I don't need object saving anymore, I just need to save something of the form [['foo', 3], ['bar', 4]] (which gets loaded as `[0, 0]``).

Specifically, this is how the data for Glowitzer caps is stored (so we have something like [['Princesses', 718], ['Ninja Stealth', 1802]]).

pickten commented 8 years ago

You'll have to call that an object, sadly. I saw what's causing this whole debacle when I made the change, and it's that arrays must contain only floats. That's probably faster/less space-consuming, so you should use that when possible, but that won't work for this. If you instead call that an object, it ought to work (once my PR is merged in, ofc). My idea with ids would be that, since all Glowitzable stuffs are derived from boosts, you could replace 'Princesses' with Molpy.Boosts.Princesses.id (and break it into a key list and value list).