Saturday 3 August 2013

The data driven approach

What is the data driven approach, you ask?  In a nutshell, it means using information instead of code.  There are many places in game development where you re-use a lot of the same basic mechanics and build up variations through small changes in the data.  For example, the difference between a male barbarian and a female barbarian would be small stat changes, a different mesh, and a few other changes like name and the noise s/he makes when hurt.  The actual code that handles all these aspects does not change, all that changes is the data.

To this end, we can seriously cut down on the amount of coding required to make new content by using the data driven approach.  New characters are created purely through data files (and of course any new meshes/audio content that’s needed).  We don’t have to code a single line of new code to make a new character, instead we just write out a new data file and the character is done.  The time saved using this approach is enormous.

There is also one other major advantage to the data driven approach – it makes your game much more mod friendly.  Even people who can’t code to save their lives can write out some simple text-based data files.  This allows modders who are primarily artists to create new content without the need for a programmer.

The data driven approach can then be expanded to everywhere and anywhere within the game.  Another example is that modders can add new spells simply by writing a couple of new data files (one for the new spell information, and one for the new projectile information).  More time saved, and more options opened up to modders - win-win!

It takes a little extra time to code up a system that can read in the data files and apply them to the objects within the game, but the time saved in the long run is enormous and vastly outweighs the initial development time.  In addition, C#’s excellent reflection and conversion abilities allow for a one-size-fits-all approach, where the data files are read in and matched to variable names automatically.  One single class in the code of the game handles all of the file-to-variables conversions, I just pass in the name of the data file, and the object to be populated, and let C# work its magic.

Try it for yourself, there is no such thing as a game that can’t use the data driven approach, and the time savings are immense.  As an example, here’s some data from one of the character data files:
// names and base info
name=Sorceress
prefab=sorceress
isPlayerCharacter=true
theme=normal
personalName="Betty"
className="Sorceress"
portraitName="Sorceress"
team = TeamType.player
genus = GenusType.human
AIBehaviourType = AIBehaviour.blaster

// general/size info
tileSize=1
moveSpeed=3
height=22
health=100
mana=150
stamina=75
headHeight=25
turnSpeed=250
fallingWeight=75

// specific/behavioral info
isInteractive=true
canTakeCover=true
isWarmBlooded=true
isAlive=true
hasMind=true
hasBlood=true
isFearless=false
isFlammable=true
canKnockDown=true
canKnockBack=true
isSmallTarget=false
canDodge=true
canBlock=true
canMove=true

// starting attributes
baseAttrib[AttributeType.strength] = 50.0;
baseAttrib[AttributeType.intelligence] = 70.0;
baseAttrib[AttributeType.initiative] = 60.0;
baseAttrib[AttributeType.willpower] = 60.0;
baseAttrib[AttributeType.dexterity] = 60.0;
baseAttrib[AttributeType.perception] = 50.0;
baseAttrib[AttributeType.agility] = 50.0;
baseAttrib[AttributeType.endurance] = 50.0;
baseAttrib[AttributeType.charisma] = 60.0;
baseAttrib[AttributeType.initiative] = 70.0;
baseAttrib[AttributeType.luck] = 0.0; // NB luck is -100 to 100
baseAttrib[AttributeType.dodge] = 50.0;
baseAttrib[AttributeType.block] = 50.0;
baseAttrib[AttributeType.counter] = 30.0;
baseAttrib[AttributeType.morale] = 100.0;
baseAttrib[AttributeType.attack] = 50.0;
baseAttrib[AttributeType.critical] = 5.0; // NB critical is chance to crit


As you can see, the data to build a character is all there (in this case, the field ‘prefab’ is what tells the game which mesh to use).  The game loads in the data, and uses the name on the left side of the equal signs to determine the variable name, and the right side becomes the variable’s new data.  It’s a very simple system which is easy to implement and easy to use (for modders and for myself).

No comments:

Post a Comment