Last time I wrote a blog entry, I started it off with an apology of sorts, where I literally did no game development for a month due to The Legend of Zelda: Breath of the Wild. That was a month ago. What’s my excuse this time?

Well, I don’t really have one, for the most part. 90% of the work I was doing was (as you’ll see in today’s post) lots of backend data work, stuff that isn’t so easy to show off in fancy screenshots. I should have been simply talking about it, which I think is good for other developers that may read this blog, but I digress. It happened, I’d like to think I’ve learned from my mistake, and hope to be back to a more normal schedule in the future.

So, without further ado:

State of the Union

As soon as I was finished with my work discussed in last month’s post, I went all in on data driven design. What is that, you ask? Simply put, it’s a method of software development where your program loads data files that describe how the application will work. In my case, I decided to use JSON as the file type. It’s flexible, it’s human readable, and as it turns out, there is great support for it with Unity and C# via the Newtonsoft Json.NET for Unity3D project.

I’ve use it to handle the loading of data for the following entities:

Attributes

I talked about Creating An Attribute System towards the beginning of the new year. At the time, I had a static file that preset many of the attributes of the game, knowing I would eventually move to a more proper, attributes.json file. Once I got started on this whole data driven development thing, this was the first to come to mind, since it’s a prerequisite for many of the other systems in the game. Here’s an example of the JSON:

{
  "EXPERIENCE": {
    "Type": "EXPERIENCE",
    "Name": "Experience",
    "ShortName": "XP",
    "ToolTip": "Points until you reach the next level",
    "MinimumValue": 0.0,
    "MaximumValue": 100.0
  },
  "LEVEL": {
    "Type": "LEVEL",
    "Name": "Level",
    "ShortName": "LVL",
    "ToolTip": "Current level",
    "MinimumValue": 1.0,
    "MaximumValue": 100.0
  }
}

Items

Next up was my existing Item system I previously talked about. As Items have Attributes, it only made sense to do it this way. You can see in this example how just what I mean:

{
  "Items": [
    {
      "Id": 0,
      "Type": "WEAPON",
      "Name": "Sword of Galladoran",
      "Description": "Forged during the ancient Kilveran days, this sword has been in the Galladoran family for 4000 years.",
      "ToolTip": "Sword of Galladoran",
      "IconPath": "Prefabs/Icons/Items/Weapons/Swords/sword_1",
      "SlotType": "RIGHT_HAND",
      "Tier": "TIER_5",
      "Attributes": {
        "DAMAGE": 15.0,
        "HIT_PERCENT": 90.0,
        "CRITICAL_CHANCE": 10.0,
        "RANGE": 1.0,
        "AOE_RANGE": 1.0
      }
    },
    {
      "Id": 4,
      "Type": "ARMOR",
      "Name": "Dundalan Chest Plate",
      "Description": "Armor given to all Knights of Dundalas, enchanted by Stramadonians to ward off magic attacks.",
      "ToolTip": "Dundalan Armor",
      "IconPath": "Prefabs/Icons/Items/Armor/Chest/Heavy/chest_1",
      "SlotType": "BODY",
      "Tier": "TIER_4",
      "Attributes": {
        "ARMOR": 6.0,
        "DODGE_CHANCE": 0.0
      }
    }
  ]
}

Units

Units are of course the pieces of the game that represent the player, party members, allies, enemies, etc. And since they have both items and attributes, they were next in line:

{
  "Units": [
    {
      "ResRef": "aramus",
      "FirstName": "Aramus",
      "LastName": "Galladoran",
      "Class": "Swordsman",
      "PortraitLocation": "Prefabs/Portraits/p-aramus",
      "Sprite": "Prefabs/Characters/Animations/Allies/aramus/Sprite",
      "UnitType": "PLAYER",
      "Attributes": {
        "EXPERIENCE": 0.0,
        "LEVEL": 5.0,
        "HIT_POINTS": 17.0,
        "ABILITY_POINTS": 10.0,
        "MOVEMENT": 5.0,
        "SPEED": 6.0,
        "DEXTERITY": 4.0,
        "MAGIC": 3.0,
        "STRENGTH": 10.0,
        "DEFENSE": 8.0
      },
      "Inventory": {
        "RIGHT_HAND": 0,
        "LEFT_HAND": 7,
        "BODY": 4,
        "HANDS": 5,
        "FEET": 6
      }
    }
  ]
}

One thing to note is that under the Inventory section, each body part ‘s value is an ID of an Item. Obviously, nothing is set in stone as of yet, and I’m not entirely sure if this is how it will go moving forward, mostly because this is not human readable. But, we’ll see.

TileMaps

Ah, TileMaps. One of my first blog posts ever was about the creation of TileMaps. They have, from the start, always been data driven. However, since I was using CSV files to describe the data (in this case, an ID corresponding to the texture to use), a lot of the other metadata per tile was hacked in. No more, now that I have moved to JSON:

{
  "Width": 37,
  "Height": 27,
  "TileSize": 5.0,
  "TileResolution": 64,
  "TileData": [
    [
      {
        "TerrainType": "MOUNTAINS",
        "IsWalkable": false,
        "Name": "Mountains",
        "DefenseModifier": 0,
        "DodgeModifier": 0,
        "AccuracyModifier": 0,
        "MovementModifier": 0,
        "SerializablePosition": {
          "x": 0.0,
          "y": 0.0,
          "z": 0.0
        },
        "UnitResRef": "aramus"
      }
    ]
  ]
}    

Now that I could describe these 4 entities via JSON files, I just had to tweak my code a bit in order to properly deserialize the files into the proper game objects that the game has currently been using.

One that was done, the last thing I started to take a look at was Tiled, a platform agnostic map editor. What’s the point of having a data driven system if you’re not using tools to supply the data? Now, of course, the export file format that it uses varies greatly from mine, but no so much so that I cannot create a converter for it. Here’s some screenshots of me making maps:

No longer must I stare at spreadsheets and insert numbers in order to design my levels!

Like I said, I still need to write a converter for the output, as well as some other things, but I’m well on my way.

Till tomorrow…