0

I'm creating a web RPG using HTML5 and JavaScript embedded directly into my website. The game will be a single player game against computer opponents... the design will be top-down 2D, Zelda style. It will be real time, but conversing with computer players will be scripted... they say something, and you're given some response options.

I was thinking of writing the dialog in XML, but I was told I should use JSON as it's easier to parse using JavaScript.

I saw Abstract Chaos' answer in XML...

<?xml version="1.0" encoding="UTF-8"?>
    <npcs>
      <npc name="Abstract">
        <dialogue>
          <text>Welcome #{PlayerName} to Stack Exchange, What would you like to know? </text>
          <options>
            <option action="dialogue5">Tell me about Stack Exchange?</option>
            <option action="quest1">Give me quest</option>
            <option action="object1">Give me object</option>
          </options>
        </dialogue>
        <dialogue id="5">
          <text>Stack Exchange is a fast-growing network of 87 question and answer sites on diverse topics</text>
          <text>We build libraries of high-quality questions and answers, focused on the most important topics in each area of expertise</text>
        </dialogue>
      </npc>
    </npcs>

And was wondering how I could achieve the same sort of layout in JSON...

My questions are:

  • How can I layout RPG dialog scripts in JSON to be parsed by JavaScript?
  • Can I have an example of how I could use JavaScript logic to parse JSON given certain conditions (ex: NPC asks question: "Can you help me?", JSON should have options "Yes" and "No", which could be based on if the player actually has that skill set to help).
  • The JSON dialog text will be stored in a separate "dialog" folder in my project folder... so it will need to be accessed externally

The only thing I've found on how to layout and parse JSON is:

        var json = '{"result":true,"count":1}',
            obj = JSON && JSON.parse(json) || $.parseJSON(json);

        alert(obj.result);

But it doesn't have the neatness factor that XML seems to have.

Any help would be appreciated...

Thanks!


Trying to load and alert external JSON text file doesn't work:

HTML:

<html>
    <head>
        <title>Working with JSON</title>
        <script src="jquery.js"></script>
        <script>
            (function() {

            var data = "/JSON_TEXT.txt";    

            var first_q = data.npcs[0].dialogs[0];
            alert(first_q.text);

            }());
        </script>

    </head>
    <body>
    </body>
</html>

JSON plain text file: JSON_TEXT.txt

'npcs': [
            {
                'name': 'Abstract',
                'dialogs': [
                    {
                        'text': 'Welcome',
                        'options': [
                            'df', 'f'
                        ]
                    }
                ]
            }
        ]
Community
  • 1
  • 1
user3871
  • 12,432
  • 33
  • 128
  • 268
  • I don't get your questions. *Every* [JSON](http://json.org/) can be parsed by JavaScript, it doesn't need a schema. The logic of your game doesn't have anything to do with the JSON parsing. If the question was "*how to structure the JSON*" - you already have an XML equivalent. – Bergi Jul 31 '13 at 16:52
  • @Bergi yes, the question was more so "how to structure JSON" from XML equivalent, and how to parse it as an object or externally using JavaScript. I've edited the title accordingly – user3871 Jul 31 '13 at 16:56
  • 1
    +1 for making a game, and I'd give you another +1 for your website. – Reactgular Jul 31 '13 at 17:00
  • @MathewFoscarini which aspect of the site do you like? the comics or the fact that I developed it? – user3871 Jul 31 '13 at 17:01
  • 1
    @Growler both!! I use to draw comics when I was a kid. It's a good outlet. – Reactgular Jul 31 '13 at 17:04
  • 1
    @MathewFoscarini Thanks! I've been drawing for a while, and as my profile says I've always liked comedy... It's a great outlet. Be sure to check out the artwork too... and share with friends! – user3871 Jul 31 '13 at 17:15

2 Answers2

2

How can I layout RPG dialog scripts in JSON ?

The equivalent of the XML you gave us would be (without the comments):

// you might use a top wrapper object with a property "npcs" for this array
[
    {
        "name": "Abstract",
        "dialogues": {
// I recommend on object with dialogues by id instead of an array
             "start": {
                 "texts": [
                     "Welcome #{PlayerName} to Stack Exchange, What would you like to know?"
                 ],
                 "options": [
                     {
                         "action": "dialogue 5",
                         "text": "Tell me about Stack Exchange?"
                     }, {
                         "action": "quest 1",
                         "text": "Give me quest"
                     }, {
                         "action": "object 1",
                         "text": "Give me object"
                     }
                 ]
             },
             "5": {
                 "texts": [
                      "Stack Exchange is a fast-growing network of 87 question and answer sites on diverse topics",
                      "We build libraries of high-quality questions and answers, focused on the most important topics in each area of expertise"
                 ]
             }
         }
         // further properties of the NPC like objects and quests maybe
    },
    … // further NPCs
]

How to parse JSON?

See Parse JSON in JavaScript?.

var json = {…};
var data = JSON && JSON.parse(json) || $.parseJSON(json);

Ouch, no! That's no JSON, that's just an object literal in JavaScript. You can use it like

var data = {…};

and data will be your object. You need to parse JSON only when you have it as a string, for example when you've loaded a file via ajax.

JavaScript logic to parse JSON given certain conditions

That's your game logic, with which we can't help you. But you don't need to parse JSON there, you only need to access the data which you have already parsed. See Access / process (nested) objects, arrays or JSON for that.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

Some find JSON harder to read than XML. I think it's much cleaner and easier to use, especially if you want to parse it with JS.

That said, I'm not really sure what your question is—you already have the data in XML, so just convert it to JSON. You can use arrays ([]) for lists and objects ({}) for when you need named keys:

{
    'npcs': [
        {
            'name': 'Abstract',
            'dialogs': [
                {
                    'text': 'Welcome #{PlayerName} to Stack Exchange, What would you like to know?',
                    'options': [
                        //options here
                    ]
                },
                //next dialog object here
            ]
        },
        //next npc object here
    ]
}

So, like you said, first you'll need to parse the JSON string:

var json; //contains the json string, perhaps retrieved from a URL via AJAX
data = JSON && JSON.parse(json) || $.parseJSON(json);

You could also assign the JSON object to a JS variable in the first place (say, in a .js file somewhere) and you won't need to parse at all. Just be sure not to pollute the global scope.

After parsing, data is a normal JS object. You can access its properties just like any other object. So, to access the first question from the first NPC, do:

var first_question = data.npcs[0].dialogs[0];

Let's alert the question itself:

alert(first_question.text);

You can access its options like this:

first_question.options;

You asked about how to load the JSON data from an external file. The usual approach is to load the file's URL via AJAX. Here is a nice tutorial for making AJAX requests with vanilla JavaScript: https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started

But there's not much reason to hand-code AJAX requests with vanilla JavaScript. I recommend using a library like jQuery, which has handy AJAX functions such as .ajax and the shorthand function .get. Here's an example using .get:

var data;                          //will hold the parsed JSON object
var json_url = 'json.txt';         //URL of your JSON (just a plain text file)
$.get(json_url, function(json) {
    data = JSON && JSON.parse(json) || $.parseJSON(json);
});

//use data here
user428517
  • 4,132
  • 1
  • 22
  • 39
  • How can I store it in external txt files and bring it in to my html document then parse with javascript? – user3871 Jul 31 '13 at 16:40
  • typically you'd use ajax to load it from a url, could also just assign it directly in a `.js` file as a variable, in which case you wouldn't need to parse at all (but be careful about polluting the global scope!) – user428517 Jul 31 '13 at 16:45
  • see http://www.codecoffee.com/articles/ajax.html for how to use ajax, or just use a library, which makes ajax requests much simpler (i recommend jquery) – user428517 Jul 31 '13 at 16:51
  • I've added my code above... it doesn't seem to be outputting "Welcome" even though I'm alerting the first array's first dialog value – user3871 Jul 31 '13 at 16:57
  • hi @Growler, please see my updated answer for an ajax example – user428517 Jul 31 '13 at 17:03
  • @growler your code doesn't work a) because you left my extra commas in. i only meant to provide an example; you'll have to modify it for it to actually work. (i also forgot a comma after the `name` assignment, so add that too). you also should NOT parse the json if you've already assigned it to a variable. you only need to parse if you have a JSON **string** (say, loaded from a url via ajax). in your code, the json is already an object, so no need to parse. – user428517 Jul 31 '13 at 17:05
  • @growler see this fiddle for a working version of your code: http://jsfiddle.net/dq83n/2/ – user428517 Jul 31 '13 at 17:15
  • Thank you for the fiddle! It works. One last question... I've tried loading the JSON text externally and it doesn't work. see above code. – user3871 Jul 31 '13 at 17:28
  • @growler one thing you need to do is put everything inside of curly braces, like in my example. you're also not loading the file with ajax, so of course it won't work. (`var data = "/JSON_TEXT.txt"` assigns a string to a variable, it doesn't load the file. you need to use ajax to actually load the file, per my example) – user428517 Jul 31 '13 at 17:29
  • Error: Uncaught TypeError: Cannot read property '0' of undefined – user3871 Jul 31 '13 at 17:32
  • Okay, then that means I need to run this on a webserver.. I was just loading the html web page locally. Getting error `XMLHttpRequest cannot load file:///.../JSON_TEXT.txt. Origin null is not allowed by Access-Control-Allow-Origin. ` – user3871 Jul 31 '13 at 17:33
  • 1
    yeah @growler, i've never tried to use ajax locally but that might be due to the same origin policy: http://en.wikipedia.org/wiki/Same_origin_policy. or maybe not ... try giving it the full, absolute path to the file instead of a local path. best option would be just to test on a server though. – user428517 Jul 31 '13 at 17:39
  • @Thanks for walking me through this. Accepting your answer :) – user3871 Jul 31 '13 at 17:40