About

I'm developing my first game, Age of Goblins. I develop this part time, and work at a "real" (read: paying) job full time. Age of Goblins is a three dimensional goblin empire building game. Inspired by Dwarf Fortress and Minecraft. Age of Goblins gives a player control over a small band of goblins in a cube-based sandbox world. The player can instruct the goblins to add or remove different types of cubes, build various structures, make elaborate traps, and craft a multitude of items.

Monday, January 28, 2013

Data files: Materials

Age of Goblins stores a good deal of its data in script files. These files store everything from the blueprints for a goblin to the definitions for materials in the ground.

For all the materials in game, be it a cube making up the terrain:


Or the material it leaves behind when it's mined:






Are all defined in data files. These definitions start in the "base definition" files. These files contain all the material base types. This is where some hard coded values get used. The game defines an enum list of base materials. For example, "WOOD" is a base material type. Then the data files extend that with "SoftWood", "Wood", "HardWood". Then they are extended in other data files with a variety of different types of each kind of wood. Most of which I haven't come up with yet :). But, you get the idea, it's a hierarchy of material types.



It's more than just organic materials however. The same hierarchies exist for stone, sand, soil and so on. For example, the base file definition of "Top Soil" is:


BASEMATERIAL:"Top Soil" {
description="Soil found commonly on the surface of the world"
materialtype=Soil
strata=surface:15
}

Where "materialtype" is referencing the enum in code. There's a shared common description for all the soils that will extend this base type and the the strata definition. The strata definition tells the world generation where this material is most likely to show up. That attribute is only applied to materials that show up in the ground. Currently the stratum are arranged from top to bottom like so:

Surface
NearSurface
SuperSediment
Sediment
SubSediment
SuperStone
Stone
SubStone
SuperCondense
Condense
SubCondense
Adamastos
Neutrpauli

Obviously, we'd want "Top Soil" to show up on the surface. The `15` following the strata definition is the weighted chance that this material will be chosen from among all the other materials that are defined to show up on the surface. The density of the material also matters, but that's defined later.

The next level in the hierarchy defines the actual materials that will show up in game. For example, "Grassy Dirt" is a material that extends "Top Soil":

MATERIAL:"Grassy dirt" {
basetype="Top Soil"
commonName="Dirt with grass"
pluralCommonName="Dirt with grass"
qualityrange=1.0:1.0
itemtextureindex=2
cubetextureindex=YP:4,SIDES:4,YM:1
value=3
density=75:0:90.0
}
Everything from the textures to the value is defined here. In "cube form" (like the top most image above), the textures can be defined for each of the sides individually, or using shortcuts like "SIDES" or "ALL". The numbers define the index in the texture sheet to use for drawing that cube. In "item form" (like the second image down from the top), the texture is also defined using the index from a texture sheet. The density value is used in world generation, resistance to mining, and allows for limiting the structures that can be created with that material.

Lets look at some organic materials, as they're a bit more interesting. How about fruit? Starting with the base type:


BASEMATERIAL:"CulinaryFruit" {
description="A fruit that is good for goblin eating"
materialtype=CulinaryFruit
}
Obvious enough. The looking at a material the extends this base type, the "Redbatan":


MATERIAL:"Redbatan" {
description="An redbatan, a tasty fruit"
commonName="Redbatan"
pluralCommonName="Redbatans"
tags=Fruit,Edible
basetype=CulinaryFruit
qualityrange=0.2:1.0
itemtextureindex=10
value=15
density=20.0
entityBaseAttributes="Small Physics Item","Slow Decay"

HarvestItems{
HarvestItem{
material="Redbatan seed"
TimeToCollect=200:500
WeightedChance=1
MinConditionToProduce=0.3
OverrideQuality=1.0:1.0
}
HarvestItem{
material="Redbatan core"
TimeToCollect=200:500
WeightedChance=1
MinConditionToProduce=0.3
}
}
}
Now things are getting interesting. We see here that there's a few of the same attributes that the top soil had, however there's some notable exceptions. The "Tags" section helps the game identify the material, so when creatures are looking for something to eat, they'll know when they found it. The "EntityBaseAttributes" is kind of a macro. It talks to the entity component system. When creating the in world representation of this material, the entity component system needs to know some common attributes to give it. I'll get more into how the entity component system interacts with scripts in my next post, but for now, just know that we define everything about an entity in the scripts.

One of the more interesting differences in this material description is the "HarvestItems" section. This section defines the other materials that reside inside this material. So when a goblin performs a harvest operation on this material, there's some materials you can expect to come out. Additionally, this defines the materials that might come out once a Rebatan were to decay. The materials referenced here are defined in the same file as the Rebatan:

MATERIAL:"Redbatan seed" {
baseType=CulinaryFruitSeed
commonName="Redbatan seed"
pluralCommonName="Redbatan seeds"
qualityrange=0.5:1.0
itemtextureindex=14
value=10
density=2.0
entityBaseAttributes="Small Physics Item","Very Slow Decay"
}
Overall this ability to create a hierarchy of materials and define everything we need to know about materials in script files makes it easy to dramatically change the game just by swapping out a few text files. With only a little complexity, it's a very powerful system for defining materials. It gets even more interesting when defining entities like goblins or spike spitters. In my next post I'll cover the data files used to create full entities. Until next time, thanks for reading!



No comments:

Post a Comment