• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GML DS Map with nested maps that add up iteratively

F

FloresSottile

Guest
I've noticed that ds maps won't store childs with their full data if they are being cleared out from outside. So I was wondering if there's anyway to iteratively nest maps into a one big map so I can export all the data in JSON once the game is over (it's for statistical research so I need absolutely everything stored).

So I did this little test to store nested maps and I have no problem with it, but If I wanted to do this iteratively I know the variable storing the actual map saving the round (the game has rounds with waves) data will be a problem:

Code:
myMainMap = ds_map_create();
myOtherMap1 = ds_map_create();
myOtherMap2 = ds_map_create();
myOtherMap3 = ds_map_create();

ds_map_add(myOtherMap1, "multiploA", 5);
ds_map_add(myOtherMap1, "multiploB", 2);
ds_map_add(myOtherMap1, "resultado", 10);
ds_map_add(myOtherMap1, "respuesta", 10);
ds_map_add(myOtherMap1, "tiempo", 5);
ds_map_add_map(myMainMap, "1", myOtherMap1);


ds_map_add(myOtherMap2, "multiploA", 2);
ds_map_add(myOtherMap2, "multiploB", 4);
ds_map_add(myOtherMap2, "resultado", 8);
ds_map_add(myOtherMap2, "respuesta", 8);
ds_map_add(myOtherMap2, "tiempo", 5);;
ds_map_add_map(myMainMap, "2", myOtherMap2);


ds_map_add(myOtherMap3, "multiploA", 6);
ds_map_add(myOtherMap3, "multiploB", 7);
ds_map_add(myOtherMap3, "resultado", 42);
ds_map_add(myOtherMap3, "respuesta", 48);
ds_map_add(myOtherMap3, "tiempo", 5);
ds_map_add_map(myMainMap, "3", myOtherMap3);

var salidaJson = json_encode(myMainMap);

show_debug_message(salidaJson);
Is there anyway I could do this iteratively and then output the whole JSON format string with all the data without having to lose what my child maps stored?

Thanks in advance.
 

chamaeleon

Member
I've noticed that ds maps won't store childs with their full data if they are being cleared out from outside. So I was wondering if there's anyway to iteratively nest maps into a one big map so I can export all the data in JSON once the game is over (it's for statistical research so I need absolutely everything stored).

So I did this little test to store nested maps and I have no problem with it, but If I wanted to do this iteratively I know the variable storing the actual map saving the round (the game has rounds with waves) data will be a problem:

Is there anyway I could do this iteratively and then output the whole JSON format string with all the data without having to lose what my child maps stored?
You'll have to better explain what you mean with iteratively. Taking a stab though.. Do you perhaps want to use ds_map_copy()?
Code:
var copy = ds_map_create();
ds_map_copy(copy, myMapThatIClearBetweenRounds);
ds_map_add_map(myMainMap, string(counter++), copy);
If your original map contains references/ids to lists or maps that have not been added using ds_map_add_list or ds_map_add_map, I suspect the copy operation wouldn't know that it's supposed to do a deep copy (and I haven't verified what it does for sure if you do use those functions, but it seems reasonable to assume it would..) and would simply store a number in the copy without meaning resulting in JSON storing a number value for the key instead of a serialized map or list.
 
F

FloresSottile

Guest
You'll have to better explain what you mean with iteratively. Taking a stab though.. Do you perhaps want to use ds_map_copy()?
Code:
var copy = ds_map_create();
ds_map_copy(copy, myMapThatIClearBetweenRounds);
ds_map_add_map(myMainMap, string(counter++), copy);
Maybe didn't express myself so good. What I meant by iteratively is that every round I'll need to store everything that happend in that exact round as a nested map and there are many rounds you expect the player to play.
I'll try your answer and see if it all gets stored. Thanks
 

chamaeleon

Member
Maybe didn't express myself so good. What I meant by iteratively is that every round I'll need to store everything that happend in that exact round as a nested map and there are many rounds you expect the player to play.
I'll try your answer and see if it all gets stored. Thanks
I hope it works out. Try having a script that essentially does what I wrote, while keeping in mind the caveat that is due to the nature of ds_map/ds_list ids not having any meaning associated with them unless you add them to maps using those two special functions. If your map is "flat", storing just numbers or strings for some set of keys, it should be ok. So call the script at the end of a round, then ds_map_clear() the one you use for the next round. Should work.
 
F

FloresSottile

Guest
I hope it works out. Try having a script that essentially does what I wrote, while keeping in mind the caveat that is due to the nature of ds_map/ds_list ids not having any meaning associated with them unless you add them to maps using those two special functions. If your map is "flat", storing just numbers or strings for some set of keys, it should be ok. So call the script at the end of a round, then ds_map_clear() the one you use for the next round. Should work.
It worked! thanks a lot. I'll keep those in mind.
 

samspade

Member
You'll have to better explain what you mean with iteratively. Taking a stab though.. Do you perhaps want to use ds_map_copy()?
Code:
var copy = ds_map_create();
ds_map_copy(copy, myMapThatIClearBetweenRounds);
ds_map_add_map(myMainMap, string(counter++), copy);
If your original map contains references/ids to lists or maps that have not been added using ds_map_add_list or ds_map_add_map, I suspect the copy operation wouldn't know that it's supposed to do a deep copy (and I haven't verified what it does for sure if you do use those functions, but it seems reasonable to assume it would..) and would simply store a number in the copy without meaning resulting in JSON storing a number value for the key instead of a serialized map or list.
I did a quick check of this and ds_map_copy does not do a deep copy. However, it does seem to preserve the nested json structure.

my code for checking this was:

Code:
var map_copy = ds_create_map();
ds_map_copy(map_copy, saved_data_map);
ds_map_destroy(map_copy);
Where saved_data_map is an existing data map that is deeply nested. I then stepped through this in the debugger. The result was that map_copy contained all of the saved data that saved_data_map did and I could view all nested levels. However, with the exception of the top map itself, which was copied, all the rest of the data was the same. ds_map_destroy then had the expected result of not removing all nested data so that my saved_data_map still had its data but all data referenced in it was destroyed.


Original Data:
map 1
nested data
Data After Creating Map 2 and Copying Map 1:
map 1
nested data​

map 2
nested data
Data After Destroying Map 2:
map 1 (nested data gone)
 

FrostyCat

Redemption Seeker
I did a quick check of this and ds_map_copy does not do a deep copy. However, it does seem to preserve the nested json structure.
It doesn't preserve the nested JSON structure as a whole, it just preserves the type marking for the immediate next layer. Because the built-in JSON functions don't have a way to determine if an entry is a nested map or list, the only reliable way to do a deep copy with them is this:
Code:
var json_data_copy = json_decode(json_encode(json_data));
 
Top