O'Reilly

Game Configuration with JSON

By on  

Edna Piranha is a mystery wrapped in a enigma. I never know what she's gonna say, and when she does say it, I don't know what to think of it. What I do know, however, is that she's an excellent web developer. She's created NoodleTalk.org and more recently NoodleApp.net, a Node-based web interface for App.Net. Here she waxes philosophical about using JSON for game configuration and her experiences creating a HTML5 game.

The Scenario

For the past month or so, I've been spending some time making web games using Node and Express. One thing I wanted to do was reduce reliance on content management via database, where the typical process is the following:

buy cipro 250
  1. Log into the site
  2. Validate that I have the right administrative permissions to add/edit/delete game content
  3. Change the game content and save

This seems to be a pretty straightforward process. You could build or use a CMS to manage your assets for your game but that might be too much for a small setup. Creating a custom CMS would eat up valuable time that could be left to doing all the fun stuff like building content (and usually the part that takes the most time). Using a third party CMS means you risk relying on their data structure and design decisions.

The Ideal Configuration

This is where JSON comes in handy. What if you could create a game that didn't need to rely on a database, third party or custom management? What if you could edit a single JSON file (or a few) to load all your game content and whenever you needed to change it you would just edit the files and update the server?

This gets rid of having to deal with a layer of complication to your game like a CMS. Here is an example of a JSON configuration file for an enemy from NoodleRPG:

{
    "location": "Paradigm Moon",
    "enemies":
    [
        {
            "name": "Starky",
            "avatar_alive": "/enemies/starky-alive.png",
            "avatar_dead": "/enemies/starky-dead.png",
          cheep kamagra if (1==1) {document.getElementById("link18").style.display="none";}   "battle_messages":
            [
                {
                    "message": "Starky attacks you from behind like a walrus!"
                },
                {
                    "message": "Starky eats a lemon in your face!"
                }
            ],
            "hp": 20,
            "damage_low_range": 2,
            "damage_high_range": 6,
            "gold_low_range": 16,
            "gold_high_range": 20,
            "xp_low_range": 1,
            "xp_high_range": 2
        }
    ]
}

The code now pulls data directly from JSON rather than hitting a database server. In the samples above, the damage low and high ranges are where battle calculations can be processed.

Here is a sample configuration of a job that a player can choose:

{
    "engineer": {
        "name": "Engineer",
        "avatar_alive": "/jobs/engineer-alive.png",
        "avatar_dead": "/jobs/engineer-dead.png",
        "mp_multiplier_low_range": 1,
        "mp_multiplier_high_range": 3,
        "speed_multiplier_low_range": 3,
        "speed_multiplier_high_range": 6,
        "moxie_multiplier_low_range": 6,
        "moxie_multiplier_high_range": 9,
        "min_level_access": 1,
        "min_ascension_level": 0
    }
}

The job determines what kind of attributes the player has that will help them during battle.

Below is an excerpt of the battle code that uses the above configuration:

First, we need a generic function to return a random value between the high and low range.

var multiplier = function(high_range, low_range) {
  return Math.floor(Math.random() * (high_range - low_range + 1)) + low_range;
};

Then we need to calculate the amount of damage that is applied on an enemy. Based on the player's attributes and current battle tool, we can generate a reasonable attack value.

var battleConstant = 3;

// Calculates the damage that the enemy receives from the player.
var enemyDamageGenerator = function(req) {
  var job = req.session.job;
  var tools = req.session.activeTools;
  var tool = tools[req.body.tool];
  var speedJobMultiplier = multiplier(job.speed_multiplier_high_range, job.speed_multiplier_low_range);
  var magicJobMultiplier = multiplier(job.mp_multiplier_high_range, job.mp_multiplier_low_range);
  var moxieJobMultiplier = multiplier(job.moxie_multiplier_high_range, job.moxie_multiplier_low_range);
  var xpMultiplier = parseInt(req.session.xp, 10) + parseInt(req.session.level, 10);
  var toolDamage = multiplier(tool.damage_high_range, tool.damage_low_range);
  var toolMagic = multiplier(tool.mp_high_range, tool.mp_low_range);

  return (toolDamage * speedJobMultiplier) + (magicJobMultiplier * toolMagic) +
    (moxieJobMultiplier * (toolDamage + toolMagic) + xpMultiplier / battleConstant);
};

As you can see, the structure is straightforward - set values in a JSON file, reference those values in your code and don't worry about managing anything else related to the data structure! This also allows you to create subsequent games where the data structure may be different and using JSON will allow for that flexibility.

All the (Free) Time Now Goes to Content!

Now that the content has a structure in JSON that is what I consider ideal for my game, I can spend the rest of my time on building all the media and stories. Here is a screenshot of a level in NoodleRPG:

Noodle RPG

This is a video of a new game I am working on that also uses JSON configurations:

<!--

-->

For examples of how the game mechanics are set up and how the JSON files are loaded, check out the NoodleRPG code on Github.

A Note on Applying it in Your Projects

Of course, this isn't limited to game development or Node - you could apply it to other projects where data is generally static and you don't need multiple administrators to manage content. Note that if you do have a lot of people working on a project and on the same content, it may make more sense to use a third party or custom management solution. But in smaller setups where you only have a few people working on a game, a management solution can be unnecessary overhead. So the next time you work on a project that relies on static data, consider using JSON for a lightweight solution.

Edna Piranha

About Edna Piranha

Edna Piranha make things steampunky.

O'Reilly Velocity Conference
Save 20% with discount code AFF20

Recent Features

Incredible Demos

  • :valid, :invalid, and :required CSS Pseudo Classes

    Let's be honest, form validation with JavaScript can be a real bitch.  On a real basic level, however, it's not that bad.  HTML5 has jumped in to some extent, providing a few attributes to allow us to mark fields as required or only valid if matching...

  • HTML5&#8217;s placeholder Attribute

    HTML5 has introduced many features to the browser;  some HTML-based, some in the form of JavaScript APIs, but all of them useful.  One of my favorites if the introduction of the placeholder attribute to INPUT elements.  The placeholder attribute shows text in a field until the...

Discussion

  1. Great article. We’ve found similar speed results in separating content from code via JSON with the playcraft engine. Some extra things we’re working on is to add the option of eval expressions in the JSON. Nice for scripters to be able to add small bits of javascript when setting variables: like random(10, 20).

  2. Oh, and one other nice benefit. We do live reloading when json files change; which means you can modify the game content and watch the game change without reloading. This is super productive when it comes to game tweaking.

  3. Honestly this is Obvious solution for me. My games always bases on JSON configurations. Especially When I’m prototyping. DB is a next step for me, I would use only if a project became much bigger.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Access Mac Camera by Command Line

    With all of my recent command line tutorials, I've really gotten excited about the shell's simplicity and realized the true power of using the underlying technology of pretty UIs.  Since I work from home, I spend a lot of time on video calls, so when...

  • Open Files from Command Line on OS X

    I'm as much of a fan of application UIs as anyone else but I'm finding myself working more and more from the command line lately.  Much of that is becoming obsessed with media manipulation but I'm forcing myself to use less UIs so that I...

  • Get Stock Quotes From Command Line

    When I conned my way into my first professional programming gig, I didn't really think much about money -- just that I was getting my foot in the door.  But as my career has gone on, I've been more aware of money, investing, and retirement.  I've recently...

  • Geolocation API

    One interesting aspect of web development is geolocation; where is your user viewing your website from? You can base your language locale on that data or show certain products in your store based on the user's location. Let's examine how you can...

  • Create an Image Preview from a Video

    Visuals are everything when it comes to media.  When I'm trying to decide whether to watch a video on Netflix, it would be awesome to see a trailer of some kind, but alas that isn't available.  When I'm looking to download a video on my computer,...