I’m working on a small online game where there is a need to store a reasonable amount of information about many (100+) different kinds of game objects.
I’m trying to decide whether to have this data generated by code or stored in some configuration file.
Data generation approach would be something like (in java-ish pseudo code):
(within a set of functions executed once at program startup)
....
// create grass terrain
grass=new GameObject();
grass.inheritProperties(generic_terrain);
grass.set(NAME,grass);
grass.set(MOVEABLE,true);
grass.set(MOVECOST,10);
grass.set(IMAGE_INDEX,1);
....
Whereas the config file approach would probably just use an XML-type format e.g.
(within terrain.xml file)
....
<terrain name="grass">
<inherit class="generic_terrain"/>
<property key="NAME" value="grass"/>
<property key="MOVABLE" value="true"/>
<property key="MOVECOST" value="10"/>
<property key="IMAGE_INDEX" value="1"/>
</terrain>
....
Some important points:
- This information is static each time
the game game is run (i.e. does not
change during execution) - The property names (NAME, MOVECOST etc.) are a relatively small list but additional ones could be added over time
- It is safe
to assume that it will only get
changed by the development team (i.e.
there is not a need for configuration
to be managed outside the build
process). - It will need to be tweaked
quite regularly during development
for game balancing reasons (e.g. making units less/more powerful) - There is a certain amount of “inheritance” of properties, i.e. in the example above grass needs to have all the standard properties defined by generic_terrain plus a few new additions/changes.
Which approach would be best for this situation? Any more importantly why?
Personally I like to push as much to config as possible. The reason for this is that at some point I may want to reuse the code I wrote for the game in a completely different way. If the source code is littered with references to implementation specific details this becomes much harder.
One interesting caveat to the config approach comes up when you want to start describing the behaviors of objects in addition to their values. Consider a simple example where you have a cup object which needs to “catch” ball objects. You might express them like:
The problem here is that somewhere you still have to define what “catches” does inside your code. If you are using an interpreted language you could do something like:
Now you have gained the ability to describe how an object behaves as well as what it is. The only problem here is that if you are not working in a interpreted language you do not have the luxury of defining code at run time. This is one of the reasons Lua has become so popular in game development. It works well as both a declarative and procedural language and it is easy to embed in a compiled application. So you may express this situation like: