1
\$\begingroup\$

Currently messing around on how to make a text engine in GameMaker and figured I would hold all my conversations in JSON format stored in a .txt file, which I'll convert into a ds_map and draw the text using the screen to the map.

Here's the JSON:

{"Neku": ["Hey Shiki.","Just trying to make this text engine thingy.","I really hope it works!"],"Shiki": ["Hey Neku! Long time no see!","What's up?","Wow thats cool!","I believe in you Neku!"]}

And here is the code I added into the create section of an empty object in a room:

str = ""
file = file_text_open_read("convo.txt")
str = file_text_read_string(file)
file_text_close(file)
map = json_decode(str)
if(ds_map_exists(map,"Shiki")) show_debug_message("A map exists") else show_debug_message("No map exists")
lst = ds_map_find_value(map,"Neku")
show_debug_message("What is lst?: " + string(typeof(lst)))

Now when I look at my console I see that a map does exist and the type of lst is shown to be a number and not an array as I had hoped. If I remove the [] in the JSON and just have one key-value pair the text shows up. If anyone could point me in the proper direction here I'd be grateful, apologies if this is a redundant stupid question.

\$\endgroup\$
  • \$\begingroup\$ No question is either "redundant" or "stupid" if asked out of curiosity and after showing your efforts towards solving the issue involved, right like you did. Welcome to GameDev :) \$\endgroup\$ – liggiorgio Jun 27 '18 at 22:34
  • \$\begingroup\$ Thanks, man appreciate it! Kinda used to curt answers to my questions on stack overflow so I was weary! \$\endgroup\$ – Jamie Hyland Jun 27 '18 at 22:42
0
\$\begingroup\$

Of course lst is not an array, because it is a ds_list data structure. From the documentation about JSON decode:

If the JSON to be decoded requires a hierarchy of lists and maps [...] these are decoded too [...] using the following rules [...]:

  • Json is a single value - returns a ds_map with a single entry "default" that is the value
  • Json is an array of objects or values - returns a ds_map with a single entry "default" that is a ds_list of the objects or values
  • Json is an object - returns a ds_map that has the object entries in it

Since your JSON keys have arrays as corresponding value (second case above), they cannot be decoded directly into an array, instead they are stored as a ds_list - I guess because it is way more versatile to return as result rather than a simple array.

I'm not sure why the result of typeof(lst) is "number", though GameMaker always warns us that dealing with dynamic data structure is our own concern when it comes to writing/reading values and freeing memory, so I'm not surprised I can't be told whether a variable is a data structure or not.

This said, after you call lst = ds_map_find_value(map,"Neku") you have a full-working ds_list where values are stored exactly as you defined in the JSON string. After assigning lst, if you call:

show_debug_message(ds_list_find_index(lst, 0));

the result will be:

Hey Shiki.

which is the first value in the array referenced by the label "Neku". Values order is always preserved. You can iterate through the ds_list to read the values, or just go full ds_list_*() functions, so you don't have to hardcode strings and can even use text files dynamically.

At the bottom of the JSON decode doc page there's a nice code snippet showing how to read data from a JSON string with multiple arrays saved internally.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you so so much! I knew it was going to be something silly like me not reading the documentation more thoroughly! \$\endgroup\$ – Jamie Hyland Jun 27 '18 at 23:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.