11
\$\begingroup\$

I've seen a lot of games that define the entity components in script files, but when they configure each entity and specify what components it has, they use some other file format (like XML). Why do they do that?

I'm asking mostly to see what others' rationale was for this. I also configure my entities outside of scripts (though I chose JSON not XML). My reasons for doing this are to make it easier for me to implement save games and also because I think this kind of configuration is better organized in something like XML or JSON.


@Christopher Larsen's answer: Too long to post as a comment

I fear you might have deviated a bit from the subject of the question. The problems you are describing are more related to hierarchy-based entities; note in my question I mentioned I was talking about component-based entities.

Here's an example of what I wanted to ask. Below are two alternative ways to configure an entity: through the script and through an external JSON file. My question was, why do so many people prefer to configure the entity outside of scripts?

A base Entity class:

class Entity:
    def __init__(self, name):
        pass
    def addComponent(self, comp):
        pass

The script approach:

orc = Entity('Orc')
orc.addComponent(PositionComponent(3.4, 7.9))

The JSON approach:

{
    "name" : "Orc",
    "components":
    {
        "PositionComponent": {
            "x" : 3.4,
            "y" : 7.9
        }
    }
}

I already stated my reasons for using this approach, which are technical and organizational. I wanted to know why so many others (from what I've seen) use this.

\$\endgroup\$

5 Answers 5

13
\$\begingroup\$

The major advantage that comes to my mind is that it allows the configuration to be edited/managed by a non-programmer without requiring them to touch any of the game scripts.

\$\endgroup\$
2
  • \$\begingroup\$ This can be achieved by simply having two files (equalivilents of a .h and then a .cpp). I do wonder who would be a person who would want to create an object (besides saying this do-nothing looks like a vase and that do-nothing looks like a butterly) that also would not want to add in some logic to it (like if person covered in pollen from the flowers in the vase, attract butterfly). Human readable is great and one of my thoughts on why this is, but there again I move that JSON, Lua tables, and XML all have similar levels of human readability by non-programmers. \$\endgroup\$
    – James
    Commented Sep 13, 2011 at 8:51
  • 2
    \$\begingroup\$ Glest is a game modded with xml. Many non-programmers make mods for it. It is definitely more approachable to have xml/json than script. \$\endgroup\$
    – Will
    Commented Sep 13, 2011 at 15:54
6
\$\begingroup\$

One reason I usually use a config file rather than script for this is:

The only way to check a script for correctness e.g. specifying all values and such is to run it.

Writing code to allow scripts to configure the values means writing code to create skeleton objects for the scripts to fill the values in and then validating that the script did so and such. Its more code and buggier code than loading from a flat config file, often using a library that supports some kind of validation mechanism.

\$\endgroup\$
3
  • 5
    \$\begingroup\$ Back when mainstream software development was better, this was known as the Principle of Least Power: Nowadays we have to appreciate the reasons for picking not the most powerful solution but the least powerful. The reason for this is that the less powerful the language, the more you can do with the data stored in that language. \$\endgroup\$
    – user744
    Commented Sep 12, 2011 at 16:41
  • 1
    \$\begingroup\$ @Joe That actually describes pretty well one of the reasons I also use this approach. At first I tried to configure my entities in scripts, but found it hard to implement save-games (couldn't keep track of relationships between components). Using an external config file helps me a lot. \$\endgroup\$
    – Paul Manta
    Commented Sep 12, 2011 at 16:51
  • \$\begingroup\$ I actuLly see this as the other way around, if you are using a scripting interface already then you now also have to provide a data validation method for the config file instead of using the already defined scripting interface to do it for you. \$\endgroup\$
    – James
    Commented Sep 13, 2011 at 8:29
2
\$\begingroup\$

The entity configuration can be simply a serialisation of a specific entity. This lets you handle game editing and modding tools' output roughly the same way as you would a save game. In particular, for games where you can't predict in which state a given entity will be during game saving - for example because of their AI or because they are partially procedurally generated in the first place - it's useful to be able to dump the whole data defining what an entity "is" (as opposed to what it "does") as a byte stream to be saved.

\$\endgroup\$
1
\$\begingroup\$

The pattern you describe is an implementation of a Data Driven System.

Data driven systems are commonly used in game development as they allow for the definition of content to be encapsulated external to the source. This external representation can then easily be modified (and even updated in realtime by an application watching for modification) to change the way an entity behaves.

Once the data is defined externally, you have all sorts of possibilities in how the designers interact with it ranging from directly editing text files (ugh!) to sophisticated UIs that guide the designer's choices in a logical, consistent and even verified for correctness (from the perspective of game balance) manner.

If the data were embedded directly in the code, any changes would require a rebuild of the application which for large projects is moderately time consuming as well as the time required for deployment of the binaries (e.g. new binaries must be deployed to and installed on the server).

Let's take an example of a sterotypical entity the "orc"...

One way of implementing for our orc would be to write a complete description in code of all of the characteristics and logic for the orc.

  • maxhealth=10
  • damage=3 damage per second
  • runaway=true
  • runawaywhen=health < 10
  • aggressive=true

When we instantiate orcs, all of their values are initialized exactly the same (or perhaps are static). The issue that arises is some designer is going to come along and say "We need a different type of orc for newbie areas, that has less health, never runs away and is not aggressive. That will let new players get used to combat without the increased difficulty and confusion while learning the combat system".

Great, now you need a different class or (maybe we were forward looking) adjust the values we feed into the "factory" that creates orcs when creating them in a "newbie" area. So we make the changes, deploy new binaries. Only to have playtesters come back and say the new health values are too low as we kill the orcs in one hit.

If our systems were data driven (and bonus points for applications that support reloading when modifications are made), then the modifications necessary to satisfy the designer and play testers are simple data changes with no recompile/deployment required. This makes designers happy because they are not stuck waiting for code changes, and it makes programmers happy because we are constantly modifing the source code to tweak values.

Taking data driven systems to extremes allows everything from game levels, spells, and even quests to be implemented by simple changes to your data requiring no code changes at all. In the end, it is about making it easy to create, tweak and iterate on the game content.

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Scripts are also data by most definitions \$\endgroup\$
    – Will
    Commented Sep 12, 2011 at 16:05
  • 1
    \$\begingroup\$ -1. The question isn't about data driven vs. hard-coding, but about dynamic scripting vs. static declarations. \$\endgroup\$
    – user744
    Commented Sep 12, 2011 at 16:45
  • \$\begingroup\$ @Christopher I added a long reply in my OP. Please check it out. \$\endgroup\$
    – Paul Manta
    Commented Sep 12, 2011 at 16:48
0
\$\begingroup\$

In your example you are actually using two scripting languages already. This is the manner I would say in the long run works out better but I would suggest that you unify the scripting language you are using. If the script example you gave was done in Lua then instead of Json, I would say use Lua's tables to build your object up. The syntax would actually be similar and allow you to support one interface for exposing your components.

To touch on why people choose to do it usually in XML and then script in logic, is that this makes sense when you say it. Here is my definition of the object in data, what is a good data storage format? It's almost always XML (though I also go with JSON ;). And then when they want to add in logic, well that is either coded or put into a script file.

Its not wrong thinking but in my eyes people are just not going to the next step. Look at any full language, c/c++/c#,. You can define the objects and their logic all in one language, why not do the same in your scripting interface... It's almost like saying we should define our classes in XML and our methods in c# when you think about it. Maybe older game scripting languages were not powerful enough and it's still just holding on as the way it was done.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .