Is there a way to "simplify" the JSON commands?

0 favourites
  • 5 posts
  • I'm a very lazy person. I like efficient systems.

    I plan to store just about everything in JSON objects except local variables. From savedata to databases and so on.

    But there are some things that I do not like about the nature of the Construct 3 JSON object. Whenever I want to manipulate a value I have to choose the Set value, Add to or Subtract from event commands from a list of 16 JSON event commands after I first navigated to the JSON object in the object list. And the other thing is that I don't like to type JSON.Get("") all the time.

    First I thought about using global json variables inside the script interface. It is very typing-efficient.

    Instead of:

    • choosing the json object "Data" from the object list
    • choosing Subtract from, from a list of 16 json events
    • defining the path "defender.hp"
    • setting Data.Get("attacker.atk") - Data.Get("defender.def") as the value

    I can just type this inside a script:

    • data.defender.hp -= data.attacker.atk - data.defender.def

    The problem with this is that I would need to update the "Data" JSON object after every change so that I can continue to use event conditions like checking for variables.

    So instead I thought I could use a JSON handler function.

    When I call the function and put data.defender.hp -= data.attacker.atk - data.defender.def as the parameter/argument the function could translate this into the event system.

    But how would I be doing this?

    My first guess is to first check for the operation that is done using find(). Then use tokenat() to find the path.

    But for the value it gets tricky for me. Because I can not know beforehand if the value just consists of a normal number or if it will need to check 1, 2 or 20 json values. Maybe I would need a loop in combination of tokenat() and every time it finds a math operation ( + - * / ) it creates a local variable and adds Data.Get("") around the argument.

    Example from the formula above:

    • Function call: JsonHandler(defender.hp -= attacker.atk - defender.def)
    • Function: find(formula, "-=") > -1 -> Data Substract Data.Get("attacker.atk") - Data.Get("defender.def") from Data.Get(str(tokenat(formula, 0, "-="))

    But as I said I'm not sure how I can handle the formulas arguments (example: attacker.atk ; defender.def). What is giving me even more headaches is the fact that the arguments could even refer to other json files.

    Like:

    Data.Get("defender.hp") -= ( Data.Get("attacker.atk") + Skills.Get("swordslash.dmg") ) - Data.Get("defender.def")

    Or is there a whole other way how I could do this?

    Thanks for reading! :)

    Edit:

    Okay after hours of tinkering around I think I found a great solution. I use a JSON handler function but I do it with a script instead of trying it with funky events like from the screenshot above.

    The function is very simple and looks as follows:

    It just copies the JSON objects, then evaluates the function parameter (the formula) and then copies the data back to the JSON objects.

    Here is the simple function call:

    And it worked! Screenshot below is from the debugger and after the evaluation/damage calculation.

  • Making an expression parser would be useful to do that. It's basically what you're describing. First step is to break the text up into tokens (numbers, operators and names). For speed you could make a regex to do that. Then with the tokens you'd make a parser.

    Here's a rough outline of the grammar the parser could use.

    script: name assignOp exp
    exp: atom [op atom]*
    atom: number | name
    number: digit+[.digit+]
    op: "+" | "-" | "*" | "/"
    name: letter+["." | letter]*

    I've made a few parsers in constuct in the past with various levels of complexity. I think you can get away with making it simpler if you cut out most error checking and order of operations perhaps. I'll try to wip something up with just a dictionary in c2 and that should be able to be translated to C3 and json if it works out.

  • Oh that sounds great! Is it possible to have the parser check for biggest hp amongst enemies, smallest atk of a character etc.?

    I imagine having skills stored inside a JSON file and storing some script formulas in them (Data Driven Design).

    Like:

    {
    	"skills": [
    		{
    		"name": "Sword Slash",
    		"description": "Deals 3*a.atk damage to an enemy.",
    		"target": 1 enemy,
    		"effect": doDamage(a.atk*3-b.def)
    		},
    		{
    		"name": "Mass Healing",
    		"description": "Heals all allies for a.mag*2.",
    		"target": all allies,
    		"effect": Heal(a.mag*2)
    		},
    	]
    }

    Edit: Whoops my phone slipped in my hand and made me post halve of my post before finishing typing.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • In the json file itself you can only have text and numbers. The parser can be made to run them.

    Anyways, it's not exactly simple but you can make it do whatever you like.

    Here is a partial example using just a dictionary. I ran out of time but it will run stuff like:

    foo=33
    bar=foo/3
    a = a + 5

    I didn't get around to making it handle operator precedence (multiplies before additions), or parenthesis. You can assign a single value or a simple one operator equation. For error checking it knows when it's wrong but I didn't get around to giving anything more than a message that says syntax error.

    dropbox.com/s/w49tbarkexaq3bb/dict_parser_partial.capx

    Overall it's a tradeoff. Polishing up a parser and adding all the features you want vs doing more in the event sheets.

  • Wow, thanks a lot for the example. It looks pretty complex. I appreciate the time you took to do it. I will see how I can build on it.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)