As we transition from internal developments to content creation, let us first present an overview of how most of that content is organized.
Cogmind is an example of the “open data” model, wherein as many content-specific parts of the game are exposed in public files anyone can open up and read/edit with a text editor. Data-driven design gives access to the parameters of game objects and more as a way to both speed up development and greatly simplify modding.
Like the 7DRL prototype from 2012, the game comes with two versions of the data: One is the default set, encrypted to prevent tampering during competitions (oh there will be competitions!), and the other is that same default set but available as plain text. Changes small and large can be made to the latter set, then instruct the game to use that instead of the default set--bam, you have a mod.
There are other data directories, but a majority of the interesting contents that make up the “game” are currently found in the objects directory: Cells (terrain), props (terrain objects like machines), entities (robots), and items (parts) are the four basic types of objects used to subdivide the world in pretty much every game I’ve ever made. At the most basic level it’s easy to tweak the parameters of a specific weapon or change a given robot’s loadout, but the data files are far more powerful than that, allowing complete control of sound effects, particle effects, and even the animated interface (the appearance of which is mostly scripted, not hard coded).
Aside from objects, another important candidate for externalization is mechanics. Mechanics are often based on formulas, and these formulas in turn contain static values (e.g. Damage = Strength x “2.0″). Source code that leaves these values peppered throughout is a pain to deal with, and makes tweaking for balance difficult. To streamline the iterative design process these static values are always given names instead (e.g. Damage = Strength x “DAMAGE_MULTIPLIER”), and in code I keep almost all of them in a single file. (That file is literally 17% of the project’s code, by line count…) When it comes time to release, it’s pretty trivial to move them all to external files, thereby partially exposing a lot of mechanics.
Although theoretically any text editor will do, I use Notepad++ for multi-row editing (a huge time-saver), syntax highlighting (I maintain a highlighting scheme for Cogmind’s .xt data files), and the ability to be in more than one place in a single file at the same time (plus synchronized scrolling).
Because xml/json require annoying markup that gets in the way of what’s important (data) no matter how nicely you format it, Cogmind .xt files use a clean tab-delimited chart format. We like our data pure. After all, the game knows what kind of data to expect and comes with a fairly robust error checker that points out any unexpected/incorrect data when parsing the files, so why bother with all that unnecessary syntax?
Keyword highlighting is more apparent in files like the particle scripts:
Internally the entire game is centered around data. How data is stored and represented is always the first and most important part of implementing a new feature.
Rather than risk the headaches and code bloat caused by inheritance (I’ve been there), the more complex Cogmind data objects are just a large collection of variables that are only partially used depending on the object’s subtype. Non-weapon items, for example, still have variables for damage and combat-related values, but these are ignored by the game. This is more straightforward to work with than the generic approach that is the composition model; it also doesn’t waste much memory because these extra variables only occur in static reference data.
All static reference data is read in at the beginning of the game and stored in “compendiums” for each type of object (from robots to sound effects). Unique instances of an object, such as dozens of robots of the same type roaming the map, need only store a reference to their static data that the game should access when it needs one of those values. Unique instances need only store dynamic data, so even ridiculously huge amounts of parameters describing a base object (or huge numbers of objects period) won’t consume exponential amounts of memory in use. This is a common method of handling data in games.
This can be taken a step further by allowing data files to specify “minor variations” of a base object by referencing the original object and indicating what specific values to assign to what variables (usually just a handful), while the game’s data loader automates the process of creating a new compendium entry. While not implemented on a large scale for Cogmind, a majority of particle variations use templates to generate the full particle definitions, thus simplifying recoloring and minor behavioral tweaks.
There are still plenty of aspects about data that haven’t been covered here, so feel free to ask any questions!