[MapTool] JSON Tutorials
Moderators: dorpond, trevor, Azhrei
-
- Cave Troll
- Posts: 90
- Joined: Thu Apr 23, 2009 6:37 pm
[MapTool] JSON Tutorials
Okay guys, I am befuddled by JSON items. I shirk from them much like I would a Cthulhian horror.
Can anyone direct me to a comprehensive tutorial for JSON that pertains to maptool? I know many of the things I need/want are far easier to do with JSON.
There is this, but I honestly freeze up a bit when I see it.
Any help would be appreciated.
Can anyone direct me to a comprehensive tutorial for JSON that pertains to maptool? I know many of the things I need/want are far easier to do with JSON.
There is this, but I honestly freeze up a bit when I see it.
Any help would be appreciated.
Re: [MapTool] JSON Tutorials
Hmm. If the tutorial is overwhelming, that's unfortunate
I was a little intimidated until I found this concise description of json objects and arrays. There's a lot of technical programming notation there, but once I got the basic jist of things, it made a lot more sense.
Without a specific question, all I can offer for the moment is the following:
If you are familiar with Lists and String Property lists (Wiki: getStrProp(), for example), there are analogous data structures in json form. The main difference is that json structures use more complex delimeters and structures, making them much more flexible in terms of their contents. Don't worry about the actual formatting: the json functions will take care of this for you.
I find it easier to not even think about the format of json entities: just think in terms of the structure and stick to the json-specific functions and you'll be fine.
json arrays are like lists, but fancier. Kind of like arrays in most programming languages (but they primarily hold strings or numbers). In fact, there are many more things you can do with a json array than with a list (Wiki: json.unique(), Wiki: json.intersection(), etc.)
json objects are like String Property Lists ( name = value ; ), but fancier and more flexible. Because both names (keys) and values can be entire strings, you can include "reserved" characters (like = or ; or spaces or whatever) with impunity, and it won't break the structure. (It is still probably a good idea to use Wiki: encode() on any strings hat get stored in a json object, especially if it's entered by a user input or somesuch).
It might help to find some example and play with them. Here's a few from my learning process:
I was a little intimidated until I found this concise description of json objects and arrays. There's a lot of technical programming notation there, but once I got the basic jist of things, it made a lot more sense.
Without a specific question, all I can offer for the moment is the following:
If you are familiar with Lists and String Property lists (Wiki: getStrProp(), for example), there are analogous data structures in json form. The main difference is that json structures use more complex delimeters and structures, making them much more flexible in terms of their contents. Don't worry about the actual formatting: the json functions will take care of this for you.
I find it easier to not even think about the format of json entities: just think in terms of the structure and stick to the json-specific functions and you'll be fine.
json arrays are like lists, but fancier. Kind of like arrays in most programming languages (but they primarily hold strings or numbers). In fact, there are many more things you can do with a json array than with a list (Wiki: json.unique(), Wiki: json.intersection(), etc.)
json objects are like String Property Lists ( name = value ; ), but fancier and more flexible. Because both names (keys) and values can be entire strings, you can include "reserved" characters (like = or ; or spaces or whatever) with impunity, and it won't break the structure. (It is still probably a good idea to use Wiki: encode() on any strings hat get stored in a json object, especially if it's entered by a user input or somesuch).
It might help to find some example and play with them. Here's a few from my learning process:
ExampleJSONcode
Code: Select all
<!-- json functions -->
[H: json.object1 = json.set("", 'first', 1, 'second', 2, 'third', 3)]
[H: json.object2 = json.set("", 'first', 2, 'second', 4, 'fourth', 6)]
[json.union(json.object1, json.object2)] <!-- array of all field names in either object -->
[json.intersection(json.object1, json.object2)] <!-- array of all field names in BOTH object -->
[json.merge(json.object1, json.object2)] <!-- object with keys from both objects -->
[R: json.evaluate(json.object1)]
<!-- sum of JSON object values -->
[R: json.object1 = json.set("", 0, 1, 1, 2, 2, 3)]
[R: json.get(json.object1, "first")]
[R: valueList = ""]
[R, C(json.length(json.object1), ";"): valueList = listAppend(valueList, string(json.get(json.object1,roll.count)) )]
[R: valueArray = json.fromList(valueList)]
[sum(json.toList(valueArray))] <!-- still only creates a string list -->
[eval( "sum("+ valueList +")" )] <!-- the eval wrapper is needed because the math functions dont work on STRING lists ( each item must be a separate argument )-->
<!-- building dynamic input parameter from a string -->
[ inputLine = "%s | %s | %s | %s | %s" ]
[ inputParam = strformat( inputLine, "varName", defaultValue, promptLabel, inputType, parameters )] <!-- if optional parameters are not used, a blank string ("") must still be specified as an argument for strformat() to work -->
[ input( inputParam )]
<!-- e.g. -->
[H: inputLine = "%s | %s | %s | %s | %s" ]
[H: inputArg = strformat( inputLine, "varName", "defaultValue", "promptLabel", "TEXT", "" )] <!-- if optional parameters are not used, a blank string ("") must still be specified as an argument for strformat() to work -->
[H: input( inputArg, "", inputArg )] <!-- input still works with empty arguments -->
[R: varName ]
[H: inputParameters = json.append( "", inputArg, inputArg )]
[H: inputParameters = json.toList( inputParameters, "##" )]
[H: input( inputParameters )] <!-- input still works with empty arguments, but NOT if separated by "##" -->
<br>[R: varName ]
<!-- building dynamic inputs from a string list!
Thanks again, zEal
http://forums.rptools.net/viewtopic.php?f=20&t=10114&start=0 -->
<!-- use json.merge() to insert a previously built section somewhere in the middle -->
[ InputParameters = json.append( "",
"tab|Tab|Tab|TAB",
"text|Default Text|Text|TEXT",
"list|List Item 1, List Item 2|List|LIST",
"check|1|Check Box|CHECK",
"radio|Radio1, Radio2|Radio|RADIO",
"label|Label|Label|LABEL",
"props|Prop1=1;Prop2=2|Props|PROPS"
)]
[ InputParameters = json.toList( InputParameters, "##" )]
[ input( InputParameters )]
"The trouble with communicating is believing you have achieved it"
[ d20 StatBlock Importer ] [ Batch Edit Macros ] [ Canned Speech UI ] [ Lib: Math ]
[ d20 StatBlock Importer ] [ Batch Edit Macros ] [ Canned Speech UI ] [ Lib: Math ]
Re: [MapTool] JSON Tutorials
I feel your pain. I was up late last night trying to figure these things out too when I stopped to realize that "class" is a javascript reserved word and doesn't work. It's in the notes of the wiki under json.set, but was more focused on json.get and didn't see it until much later.
Here's how I understand the structure so far.
You have 2 things, arrays and objects. Arrays are simple enough to comprehend. They are surrounded by brackets "[ ]" and separated by commas ",".
Examples:
[1,2,3]
["bob","joe","jane"]
[1,"joe",3]
What's between the commas doesn't matter as long as it's a valid datatype (string, number, array or object). So, you can have:
["bob",2,[1,2,3],{"varName":"value"}]
The problem I found to get to this point without using json.set or json.append is that I can't type [h: myArray = ["bob",2,[1,2,3],{"varName":"value"}]] because you'll get "unexpected char: '{'". But it will work if you surround it with a "squote" (single quote, or superquote) like so, [h: myArray = '["bob",2,[1,2,3],{"varName":"value"}]'].
But if you're building a data structure from scratch, you may want to consider using json.set or json.append for arrays.
Example:
As far as I can tell, you can't use json.set to set array positions that don't exist. I hope this gets you started on understanding. I know it was a learning experience for me just to write this post
Here's how I understand the structure so far.
You have 2 things, arrays and objects. Arrays are simple enough to comprehend. They are surrounded by brackets "[ ]" and separated by commas ",".
Examples:
[1,2,3]
["bob","joe","jane"]
[1,"joe",3]
What's between the commas doesn't matter as long as it's a valid datatype (string, number, array or object). So, you can have:
["bob",2,[1,2,3],{"varName":"value"}]
The problem I found to get to this point without using json.set or json.append is that I can't type [h: myArray = ["bob",2,[1,2,3],{"varName":"value"}]] because you'll get "unexpected char: '{'". But it will work if you surround it with a "squote" (single quote, or superquote) like so, [h: myArray = '["bob",2,[1,2,3],{"varName":"value"}]'].
But if you're building a data structure from scratch, you may want to consider using json.set or json.append for arrays.
Example:
Code: Select all
[h: obj = json.set("{}","varName","badvalue")] <!-- create object -->
[h: arr = json.append("",1,2,4)] <!-- create array -->
[h: arr = json.set(arr,2,3)] <!-- fix value is position 2, to value 3 -->
[h: arrStruct = json.append("","bob",2,arr,obj)] <!-- create new array with append -->
[r: arrStruct]<br> <!-- what we have so far -->
<!-- the complicated way to set nested objects and arrays (set(set(get)))-->
[h: arrStruct = json.set(arrStruct,3,json.set(json.get(ArrStruct,3),"varName","goodvalue"))]
[r: arrStruct]<br>
<!-- the easy way (get,set,set) -->
[h: pos3 = json.get(arrStruct,3)] <!-- get object from array position 3 -->
[h: pos3 = json.set(pos3,"varName","another value")] <!-- set object to new value -->
[h: arrStruct = json.set(arrStruct,3,pos3)] <!-- put object back in array position 3 -->
[r: arrStruct]<br>
<!-- This doesnt work -->
[h: newArr = json.set("",1,2,3,4)]
[r: newArr]<br>
<!-- But this does -->
[h: newArr = json.append("",1,2,3,4)]
[r: newArr]<br>
Downloads:
- Notepad++ MapTool addon
- RPEdit details (v1.3)
- Coding Tips: Modularity and Design
- Videos: Macro Writing Tools
Re: [MapTool] JSON Tutorials
Unless you're making a trivial object or array - something like
I would do all assembly of JSON datatypes using the functions. It's just easier.
Code: Select all
'{"Yay":5, "Nay":2}'
-
- Cave Troll
- Posts: 90
- Joined: Thu Apr 23, 2009 6:37 pm
Re: [MapTool] JSON Tutorials
I appreciate ya'll's help. I haven't had a chance to do any coding yet, but when I do I'm sure I'll be asking questions.
Re: [MapTool] JSON Tutorials
I have a few questions:
1) Does using json to store "large" numbers of properties reduce the memory usage?
2)Since I've been after these darn json for days and coundn't understand a thing about how to use them as I need (I can't even use json.get from a campaign property as I'd wish, despite trying and trying), could someone please tell me which pages (wiki or not) should I read in order to finally understand how the hell does it work?
1) Does using json to store "large" numbers of properties reduce the memory usage?
2)Since I've been after these darn json for days and coundn't understand a thing about how to use them as I need (I can't even use json.get from a campaign property as I'd wish, despite trying and trying), could someone please tell me which pages (wiki or not) should I read in order to finally understand how the hell does it work?
"There are many ways my Son, to find where the souls of Demons remain...
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."
Re: [MapTool] JSON Tutorials
Irrlicht wrote:I have a few questions:
1) Does using json to store "large" numbers of properties reduce the memory usage?
2)Since I've been after these darn json for days and coundn't understand a thing about how to use them as I need (I can't even use json.get from a campaign property as I'd wish, despite trying and trying), could someone please tell me which pages (wiki or not) should I read in order to finally understand how the hell does it work?
Not sure I can address the first question, but the second question I can address.
The wiki tutorial on JSONs is not maptool specific - it's about the idea of the JSON format. For maptool purposes, though, look at it this way:
JSON Objects and JSON Arrays are two variable types that MapTool macros can manipulate. In MapTool, they are formatted in a particular way (enclosed in { } or [ ], respectively) and it is that formatting that clues MapTool in to the type of variable you're talking about.
In essence, they are a simple way to store data of various kinds in a single variable, and then retrieve it (in this manner, they are quite similar to String Lists and String Property Lists, which you might already be familiar with). There are important differences between an Object and an Array.
JSON Objects
A JSON Object is a variable that contains one or more key-value pairs. The key is a string, and the value can be a number, another string, or even another JSON Object or Array.
For instance, consider a hypothetical weapon in a game - it has a Name, a Damage Value, an Ammunition value, and a Type. You could store all these separately, in individual properties, but you could instead store them as a JSON Object (by pairing the key - Name, Damage, Ammunition, Type - with the corresponding value for that weapon). A generic JSON object of this type, in MapTool, would look like this:
Code: Select all
{"Name":"Colt 1911", "Damage":7, "Ammunition":7, "Type":"Pistol"}
Code: Select all
<!--Constructing a new json, the paired curly braces indicates that you wish to create a new object-->
<!--If you want to add information to an existing JSON Object, put that objects name in place of "{}"-->
[h:weaponJSON = json.set("{}", "Name", "Colt 1911", "Damage", 10, "Ammunition", 7, "Type", "Pistol")]
<!--You could also use variables as part of the process-->
[h:wpnDam = 10]
[h:wpnName = "Colt 1911"]
[h:wpnAmmo = 7]
[h:wpnType = "Pistol"]
[h:weaponJSON = json.set("{}", "Name", wpnName, "Damage", wpnDam, "Ammunition", wpnAmmo, "Type", wpnType)]
Code: Select all
[h:wpnName = json.get(weaponJSON, "Name")]
[h:wpnDam = json.get(weaponJSON, "Damage")]
[h:wpnAmmo = json.get(weaponJSON,"Ammunition")]
You hit with your [r:wpnName], dealing [r:wpnDam] damage. You have [r:wpnAmmo - 1] rounds left.
Assume then, that you wanted to add another weapon to your weapon JSON Object. This poses a problem - a JSON Object only permits one instance of a key to exist in it - if you set "Name" to a new value, it will overwrite the existing value. That's bad. So, we have to have a more complex object. As mentioned already, JSON Object values can themselves be other JSON Objects. So instead of a single object looking like:
Code: Select all
{"Name":"Colt 1911", "Damage":10, "Ammunition":7, "Type":"Pistol"}
Code: Select all
{"Colt 1911":
{"Damage":10, "Ammunition":7, "Type":"Pistol"},
"HK MP-5":
{"Damage":8, "Ammunition":30, "Type":"SMG"}
}
Code: Select all
<!-- Create the two JSONs about the individual weapons-->
[h:childJSON_1 = json.set("{}", "Damage", 10, "Ammunition", 7, "Type", "Pistol)]
[h:childJSON_2 = json.set("{}", "Damage", 8, "Ammunition", 30, "Type", "SMG")]
<!--Add them to a new JSON, the Parent object-->
[h:parentJSON = json.set("{}", "Colt 1911", childJSON_1, "HK MP-5", childJSON_2)]
<!--As a quick example, if you were adding one child, and then later added a second, you'd do it like this-->
[h:parentJSON = json.set("{}", "Colt 1911", childJSON_1)]
[h:parentJSON = json.set(parentJSON, "HK MP-5", childJSON_2)]
Finally, just like creating a nested JSON Object is a 2-step process, retrieving data from them using the built-in functions is likewise a 2-step process. The first step is to extract the child object from the Parent, and then extract the necessary value(s) from the Child.
Code: Select all
<!--Get the Child Object for the HK MP-5 out of the Parent JSON-->
<!--Remember, hkDetails will be a JSON Object itself-->
[h:hkDetails = json.get(parentJSON, "HK MP-5")]
<!--Get the Damage and Ammo values from the hkDetails object-->
[h:hkDmg = json.get(hkDetails,"Damage")]
[h:hkAmmo = json.get(hkDetails,"Ammo")]
You fire a burst from your HK MP-5, doing [r:hkDmg] damage. You now have [r:hkAmmo - 3] rounds left.
Okay, whew. That was long. I'll address Arrays in the next post. Let me know if there are any errors / ambiguities!
Last edited by Rumble on Sun Oct 31, 2010 10:40 am, edited 2 times in total.
Re: [MapTool] JSON Tutorials
continued...
JSON Arrays
A JSON Array, while still part of the JSON concept, is significantly different from a JSON Object. First off, obviously, it's an array - and, much like an array in any language, it is a sequential collection of individual elements. In a JSON array, the elements can be strings, numbers, JSON Objects, or other JSON Arrays.
Second, JSON Arrays do not have keys - you access the value of an element by its index in the array, not by an associated key. Indexes start at 0, so to access the third element in an array, you access index 2.
Third, IIRC, JSON Arrays have an inherent order - that is, the order in which things are added to an array is the inherent order of the array. JSON Objects, by contrast, do not have an assumed order - the keys in an object may be in any order at any given time (so don't assume a particular order for a JSON Object!).
Finally, building a JSON Array uses Wiki: json.append() as opposed to json.set(). So, taking the weapon example, an array of weapon details might look like:
In this case, you see the same information, but you have to know two things: one, the order will always be as shown, and two, you need to know (if you want to extract information from the array) that the weapon name is always at index 0, the weapon damage at index 1, ammo at index 2, and type at index 3.
To build that array, and retrieve information from it, you would use json.append() and json.get(), respectively:
As mentioned, JSON Arrays can hold JSON Objects as their elements, too. So remember the object we created earlier - the weapon object, that looked like this:
We could add that directly to a JSON Array like so. In fact, we could add that one, and the one for the HK MP-5, both to the same array.
After doing all that, the JSON Array weapons looks like:
If you wanted to extract information from it, you again do a two-step process - first you pull the element you want out of the array, and then (since the element is a JSON object) you can pull the value out of the element by using the right key.
That, in a nutshell, is how JSON Objects and JSON Arrays work. There are LOTS of tricks and uses you can put them to, but in the end they are a variable type used to store information in a couple ways - either by key-value pairing, or in a sequential array of values.
JSON Arrays
A JSON Array, while still part of the JSON concept, is significantly different from a JSON Object. First off, obviously, it's an array - and, much like an array in any language, it is a sequential collection of individual elements. In a JSON array, the elements can be strings, numbers, JSON Objects, or other JSON Arrays.
Second, JSON Arrays do not have keys - you access the value of an element by its index in the array, not by an associated key. Indexes start at 0, so to access the third element in an array, you access index 2.
Third, IIRC, JSON Arrays have an inherent order - that is, the order in which things are added to an array is the inherent order of the array. JSON Objects, by contrast, do not have an assumed order - the keys in an object may be in any order at any given time (so don't assume a particular order for a JSON Object!).
Finally, building a JSON Array uses Wiki: json.append() as opposed to json.set(). So, taking the weapon example, an array of weapon details might look like:
Code: Select all
["Colt 1911",10,7,"Pistol"]
To build that array, and retrieve information from it, you would use json.append() and json.get(), respectively:
Code: Select all
<!--Build the array - using "[]" indicates that you want to create a new array-->
<!--if you want to add to an existing array, put that variable name in instead of "[]"-->
[h:wpnArray = json.append("[]", "Colt 1911", 10, 7, "Pistol")]
<!--Retrieve Data-->
[h:wpnDamage = json.get(wpnArray, 1)]
Code: Select all
{"Name":"Colt 1911", "Damage":10, "Ammunition":7, "Type":"Pistol"}
Code: Select all
<!--Create the weapon JSON Objects-->
[h:coltObject = json.set("{}", "Name", "Colt 1911", "Damage", 10, "Ammunition", 7, "Type", "Pistol")]
[h:hkObject = json.set("{}", "Name", "HK MP-5", "Damage", 8, "Ammunition", 30, "Type", "SMG")]
<!--append them to the array-->
[h:weapons = json.append("[]", coltObject, hkObject)]
Code: Select all
[{"Name":"Colt 1911", "Damage":10, "Ammunition":7, "Type":"Pistol"}, {"Name":"HK MP-5", "Damage":8, "Ammunition":30, "Type":"SMG"}]
Code: Select all
<!--Pull out the element for HK MP-5-->
[h:hk = json.get(weapons,1)]
<!--Pull out the damage value for the HK-->
[h:hkDmg = json.get(hk, "Damage")]
That, in a nutshell, is how JSON Objects and JSON Arrays work. There are LOTS of tricks and uses you can put them to, but in the end they are a variable type used to store information in a couple ways - either by key-value pairing, or in a sequential array of values.
Re: [MapTool] JSON Tutorials
Ugh, I really appreciate your effort to answer me, but I must hope it will be more useful for other people than it is for me... sadly, I find myself lost in it as much as I do in wiki.
Let me clarify a bit: I had already understood that json objects and arrays are variable containers and the syntax (more or less) to assemble them, but the trouble comes when I try to use them.
To begin with, I'm still unable to fully understand how to retrieve a value properly.
For example, if I have the object {"WpnName":"Longsword", "Damage":1d8} I can use json.get("WpnName") to see the text Longsword in the chat box. All right.
But now I'll make it more complex, and this is where troubles start.
1) Say I use json.get("Damage"); I'll get 1d8, and I'll visualize exactly the text '1d8', not the result of a 1d8 roll. How could I get that result?
2) Say I build the object {"Weapons":{"WpnName":"Longsword", "Damage":1d8}, {"WpnName":"Great Axe", "Damage":1d12}} (if the syntax is correct); Now, what should I write exactly to get the WpnName or Damage value I'm looking for (be it either one of the two contained in the json object)?
To tell it short, I wanted to create a json object as a campaign property so that it could be a container for weapons; then a macro (call it "Create Weapon") that would be able to create other macros for given tokens; this last kind of macros would use the Strength and other pertinent properties of the token who has it in its list, and would have the other values (name, damage, range, etc.) already set, based on what I chose when using the Create Weapon macro.
I suppose I'm forced to use json to do all this, but I'm totally clueless about how.
Let me clarify a bit: I had already understood that json objects and arrays are variable containers and the syntax (more or less) to assemble them, but the trouble comes when I try to use them.
To begin with, I'm still unable to fully understand how to retrieve a value properly.
For example, if I have the object {"WpnName":"Longsword", "Damage":1d8} I can use json.get("WpnName") to see the text Longsword in the chat box. All right.
But now I'll make it more complex, and this is where troubles start.
1) Say I use json.get("Damage"); I'll get 1d8, and I'll visualize exactly the text '1d8', not the result of a 1d8 roll. How could I get that result?
2) Say I build the object {"Weapons":{"WpnName":"Longsword", "Damage":1d8}, {"WpnName":"Great Axe", "Damage":1d12}} (if the syntax is correct); Now, what should I write exactly to get the WpnName or Damage value I'm looking for (be it either one of the two contained in the json object)?
To tell it short, I wanted to create a json object as a campaign property so that it could be a container for weapons; then a macro (call it "Create Weapon") that would be able to create other macros for given tokens; this last kind of macros would use the Strength and other pertinent properties of the token who has it in its list, and would have the other values (name, damage, range, etc.) already set, based on what I chose when using the Create Weapon macro.
I suppose I'm forced to use json to do all this, but I'm totally clueless about how.
"There are many ways my Son, to find where the souls of Demons remain...
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."
Re: [MapTool] JSON Tutorials
Ah, I see - apologies for missing the real question!
Okay, so, this:
Dice rolls in maptool can be written directly, e.g. [myRoll = 1d8], and it will interpret that as you expect (rolling 1d8 and assigning that to the variable myRoll). However, if you need to store a dice roll, the only way to do so is as a string (no matter whether you're using a string property, a list, a JSON array, a JSON object, or just assigning it directly to a Token Property, saving a dice roll like 1d8 ALWAYS means saving it as a string).
And, in MapTool, the string "1d8" is not the same as the dice roll command 1d8.
Instead, what you'd need to do is retrieve the string value, and then use the Wiki: eval() function on it - that evaluates the string as if it were a macro command. So, like this:
This takes the value of wpnDamageString - "1d8" - and evaluates it as if it was a command (so the eval function makes maptool "see" the string as just the 1d8 roll).
Then, if you needed to extract a specific damage value, you'd need to do the two-step extraction sequence mentioned above: first, retrieve the proper object from the Parent JSON Object, and then retrieve the damage value from that.
Step 1: Assume we needed to get the Damage associated with Weapon2, and that the full JSON Object of all weapons is in a property called Weapons.
You now have a variable weapon2info, whose value is the following JSON Object:
then, you need to extract the Damage value and the Weapon Name:
This gives you the variable wpn2damage, whose value is "1d8". And finally, you'll evaluate that string to get an actual dice roll:
Finally, it may occur to you that the structure of the Weapons JSON object is a little contrived - why not, instead of saying "Weapon1" and "Weapon2" are the keys, just make the name of the weapon the key? So instead, you'd have:
Note that I added in the type bits because there's no real point in having a nested JSON object with only one key - you could just use a plain old JSON Object if there's only one interesting value (e.g., it would just be {"Longsword":"1d8", "Great Axe":"1d12"}).
Okay, so, this:
First, a quick note - probably a typo on your part - remember that json.get() requires you to specify both the JSON Object you're getting from, and the key you wish to get. Your example is missing the object, it should beBut now I'll make it more complex, and this is where troubles start.
1) Say I use json.get("Damage"); I'll get 1d8, and I'll visualize exactly the text '1d8', not the result of a 1d8 roll. How could I get that result?
Code: Select all
[json.get(weaponobject,"Damage")]
And, in MapTool, the string "1d8" is not the same as the dice roll command 1d8.
Instead, what you'd need to do is retrieve the string value, and then use the Wiki: eval() function on it - that evaluates the string as if it were a macro command. So, like this:
Code: Select all
[h:wpnDamageString = json.get(weaponObject, "Damage")]
[h:actualDamage = eval(wpnDamageString)]
Okay, the syntax is not quite right. First, every value in a JSON Object needs it's own key - so, this object: {"WpnName":"Longsword", "Damage":"1d8"} is assigned to the key "Weapons"; however, the second object (for the greataxe) is not assigned to its key. Properly structured, the object would be something like:) Say I build the object {"Weapons":{"WpnName":"Longsword", "Damage":1d8}, {"WpnName":"Great Axe", "Damage":1d12}} (if the syntax is correct); Now, what should I write exactly to get the WpnName or Damage value I'm looking for (be it either one of the two contained in the json object)?
Code: Select all
{"Weapon1":{"WpnName":"Longsword", "Damage":"1d8"}, "Weapon2":{"WpnName":"Great Axe", "Damage":"1d12"}}
Step 1: Assume we needed to get the Damage associated with Weapon2, and that the full JSON Object of all weapons is in a property called Weapons.
Code: Select all
[h:weapon2info = json.get(Weapons, "Weapon2")]
Code: Select all
{"WpnName":"Great Axe", "Damage":"1d12"}
Code: Select all
[h:wpn2damage = json.get(weapon2info, "Damage")]
[h:wpn2name = json.get(weapon2info, "WpnName")]
Code: Select all
[h:wpn2actualdamage = eval(wpn2damage)]
Finally, it may occur to you that the structure of the Weapons JSON object is a little contrived - why not, instead of saying "Weapon1" and "Weapon2" are the keys, just make the name of the weapon the key? So instead, you'd have:
Code: Select all
{"Longsword":{"Damage":"1d8", "Type":"Heavy Blade"},"Great Axe":{"Damage":1d12, "Type":"Axe"}}
-
- Cave Troll
- Posts: 90
- Joined: Thu Apr 23, 2009 6:37 pm
Re: [MapTool] JSON Tutorials
I just want to say, Rumble, that all of this has really helped me. Thank you.
Re: [MapTool] JSON Tutorials
You're welcome - the tutorial on the wiki is pretty decent for the concept of a JSON Object/Array, i think, but they are fiddly and they will pitch vague errors when they don't work, and that can get frustrating. So I hope I've helped.Nonsapient wrote:I just want to say, Rumble, that all of this has really helped me. Thank you.
One quick note on errors: if you get "Unknown JSON type in json.get" (or in "json.fields," json.set, etc.), that means that whatever you were trying to json.get from is not a JSON object or array. Generally, that means (or it has always meant for me) one of the following:
1. Typo in a variable name in one of the json.get() calls I'm using
2. I'm using the wrong variable in the json.get() call
3. I've used the wrong key in the json.get() call - json.get() doesn't fail if you call a key that doesn't exist; it just returns an empty string (NOTE: this can also be the source of "illegal argument java.lang.string, expecting java.lang.bigDecimal" errors - you think you've extracted the key "wpnAmmo", which should have a number as a value, but the key is really named "wpnAmmunition" - extracting "wpnAmmo" returns an empty string, which causes any math operations to blow up).
4. I've forgotten the structure of the JSON Object/array I'm messing with, and the piece I think will be a JSON Object/array when extracted from its parent really isn't.
Re: [MapTool] JSON Tutorials
I've given only a quick look because I'm short of time at present, but it's already more clear, thanks a lot. I'll see it in full detail later.
EDIT
Alright, now the json.get is clear for me. The trouble moves to json.set and adding/removing/editing json objects (expecially json objects inside other json objects), if anyone can give some advice.
I have understood (I think) how to use json.set to create a new json object with other objects inside it, as long as it is built from zero and not tied to anything, but I've not understood how to do that when it's an already existing object, expecially if it is a campaign property.
Say I have the campaign property:
Weapons:{"Wpn1":{"Dmg":"4"}, "Wpn2":{"Dmg":"8"}}
How do I exactly add an eventual Wpn3 and how could I edit or remove either one of the Wpn1, Wpn2 or others?
EDIT
Alright, now the json.get is clear for me. The trouble moves to json.set and adding/removing/editing json objects (expecially json objects inside other json objects), if anyone can give some advice.
I have understood (I think) how to use json.set to create a new json object with other objects inside it, as long as it is built from zero and not tied to anything, but I've not understood how to do that when it's an already existing object, expecially if it is a campaign property.
Say I have the campaign property:
Weapons:{"Wpn1":{"Dmg":"4"}, "Wpn2":{"Dmg":"8"}}
How do I exactly add an eventual Wpn3 and how could I edit or remove either one of the Wpn1, Wpn2 or others?
"There are many ways my Son, to find where the souls of Demons remain...
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."
Re: [MapTool] JSON Tutorials
In this case you have 2 levels of nesting. If you want to add a Wpn3, you would first construct it's individual detail JSON Object:Irrlicht wrote:I've given only a quick look because I'm short of time at present, but it's already more clear, thanks a lot. I'll see it in full detail later.
EDIT
Alright, now the json.get is clear for me. The trouble moves to json.set and adding/removing/editing json objects (expecially json objects inside other json objects), if anyone can give some advice.
I have understood (I think) how to use json.set to create a new json object with other objects inside it, as long as it is built from zero and not tied to anything, but I've not understood how to do that when it's an already existing object, expecially if it is a campaign property.
Say I have the campaign property:
Weapons:{"Wpn1":{"Dmg":"4"}, "Wpn2":{"Dmg":"8"}}
How do I exactly add an eventual Wpn3 and how could I edit or remove either one of the Wpn1, Wpn2 or others?
Code: Select all
[h:wpn3_details = json.set("{}", "Dmg", 8)]
Code: Select all
[Weapons = json.set(Weapons, "Wpn3", wpn3_details)]
If you wanted now to change the damage of Wpn2 to 5, you would need to do the extraction of the value associated with the key "Wpn2":
Code: Select all
[wpn2_details = json.get(Weapons, "Wpn2")]
Code: Select all
[wpn2_details = json.set(wpn2_details, "Dmg", 5)]
Then, you can put that newly edited object back into the overall Weapons object like so:
Code: Select all
[Weapons = json.set(Weapons, "Wpn2", wpn2_details)]
Bottom line is that when using json.set() and json.get() with multiply-nested JSON objects, you have to do multiple steps to drill down into the object and extract the data you need. If you change that data, you have to sequentially reassemble the object.
-
- Kobold
- Posts: 7
- Joined: Sun Oct 17, 2010 10:38 am
Re: [MapTool] JSON Tutorials
Hi, MapTools newbie here..
This is a pretty good tutorial, but .. Nowhere (here or on the wiki) have I found out how to initialize an empty json array and then add items to it using append.
What I -want- to do is this (In pseudo-code)
MyArray = new Array()
loop (x times) {
json.append(MyArray, someval)
}
So, I figured out the looping part. The while constructor works well enough. It's not for (i=0;i<10;i++), but I can make it do what I need.
Hell, I can't even get this code to work:
[h:allDice = '[""]']
[h:json.append(allDice,"blah")]
[h:json.append(allDice,"blah2")]
But I'm not entirely sure if that's supposed to give me an array that looks like this:
["","blah","blah2"]
or one that looks like this:
["blah","blah2"]
... I'd guess the former, since I'm initializing the array with an empty string, but the documentation is somewhat unclear on this. (In that i can't even find out how to initialize an empty array to be added to later - All of the initialization examples appear to assume you already know at least some of the values that are going to go into the array)
Syntax is always the hardest part when learning a new language. Any help would be appreciated
This is a pretty good tutorial, but .. Nowhere (here or on the wiki) have I found out how to initialize an empty json array and then add items to it using append.
What I -want- to do is this (In pseudo-code)
MyArray = new Array()
loop (x times) {
json.append(MyArray, someval)
}
So, I figured out the looping part. The while constructor works well enough. It's not for (i=0;i<10;i++), but I can make it do what I need.
Hell, I can't even get this code to work:
[h:allDice = '[""]']
[h:json.append(allDice,"blah")]
[h:json.append(allDice,"blah2")]
But I'm not entirely sure if that's supposed to give me an array that looks like this:
["","blah","blah2"]
or one that looks like this:
["blah","blah2"]
... I'd guess the former, since I'm initializing the array with an empty string, but the documentation is somewhat unclear on this. (In that i can't even find out how to initialize an empty array to be added to later - All of the initialization examples appear to assume you already know at least some of the values that are going to go into the array)
Syntax is always the hardest part when learning a new language. Any help would be appreciated