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

  • CSS Filters

    CSS filter support recently landed within WebKit nightlies. CSS filters provide a method for modifying the rendering of a basic DOM element, image, or video. CSS filters allow for blurring, warping, and modifying the color intensity of elements. Let's have...

  • How to Create a Twitter Card

    One of my favorite social APIs was the Open Graph API adopted by Facebook.  Adding just a few META tags to each page allowed links to my article to be styled and presented the way I wanted them to, giving me a bit of control...

Incredible Demos

  • Optimize Your Links For Print Using CSS — Show The URL

    When moving around from page to page in your trusty browser, you get the benefit of hovering over links and viewing the link's target URL in the status bar. When it comes to page printouts, however, this obviously isn't an option. Most website printouts...

  • MooTools-Like Element Creation in jQuery

    I really dislike jQuery's element creation syntax. It's basically the same as typing out HTML but within a JavaScript string...ugly! Luckily Basil Goldman has created a jQuery plugin that allows you to create elements using MooTools-like syntax. Standard jQuery Element Creation Looks exactly like writing out...

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

  • Prevent Chrome from Translating a Page

    A while back I shared my favorite Google Chrome extension:  Google Art Project.  I've enjoyed seeing beautiful art when I open a new tab -- it's brought genuine happiness to my day, however small that happiness may be.  About a week ago, however, the art presented had...

  • Create Any Type Of Website With These Multi-Purpose Themes

    We have selected what we believe are the very best multipurpose WordPress themes on the market today. Our list contains a number of best sellers, several newcomers that are proving to be highly popular, and a few themes that are ideal for creating the types of...

  • An Introduction to Static Site Generators

    Static site generators seem to have been becoming more and more popular recently, but they’re not one of those ephemeral novelty things that grow in popularity as quickly as they fall into oblivion shortly after. For over a decade, many different projects — 394 of...

  • Automated Tests for Visual Responsive Layouts

    Today it's all about testing. In 2015, many developers knows about TDD and I personally think that testing is one of the key for quality products. But what about testing in a Front-end environment? How do you guys write your tests for a responsive page or...

  • Getting Dicey With Flexbox

    What if you could build complex CSS layouts in minutes? Flexbox is a new CSS layout spec that makes it easy to construct dynamic layouts. With flexbox, vertical centering, same-height columns, reordering, and direction agnosticism are a piece of cake. There's a popular myth floating around that...