📜 ⬆️ ⬇️

Magic data-driven design

Note from the translator
Due to the lack of concise translation of some terms that came to us from the English language, I would prefer to leave them in the original language. I think that those who are interested in this industry will not be annoyed.


Games consist of two parts: logic and data. Reviving the game when connecting them together, but useless separately. Logic defines the basic rules and algorithms of the game engine, while the data describes the details of the game content and its behavior. The magic is that both of these components are separated from each other and can develop separately.


Thought 1: Basics


First of all, you need a system that can read text files on demand (and not just when the program is initially loaded). It is necessary to follow the data-driven paradigm underlying the whole process. Each game requires a way to read data from files, and although the game should ultimately work with binary files, it is much more convenient to work with text files during the development process. After all, they are simple to the impossible! And they also allow you to organize work for your entire team more efficiently - without changing a single line of code, any member of the team (including testers and game designers) can try new things and experiment with different versions of the existing one. Thus, an easily implemented function quickly becomes an indispensable tool in the work.
')

Thought 2: Minimum Required


It is not necessary to set constants in the code. Put them all in a text file (or files) so that they can be easily modified without recompiling the code. For example, basic functionality, camera behavior, etc. can be fully described in this way. And if so, then the game designer, producer, boy from the next entrance - everyone will be able to change the behavior of the game, simply by editing the desired file in notepad. And not all team members can be close to programming and get along well with it, so it’s important to keep this in mind, because playing with the values ​​of the permanent, game producers and game designers can achieve the desired behavior in the game without worrying about the programmers.

Thought 3: Limit Nothing


Suppose anything can change (most likely it will be so). If the game requires a split-screen mode, you do not need to strictly specify exactly two. Write your game, which can support any number of screens with its own logic for each camera. The amount of work from this, with the right approach to business, will not greatly increase. With the help of the magic of text files, you will determine how many screens there should be in the game - one, two, four or more. The files will also set the initial data for the cameras: position, direction, angle of coverage, and slope. The best part is that your game designers also have direct access to changing these parameters.
The game develops in full force, with a flexible code design. The process of abstraction and making the core of the game will greatly help in its design and development. Instead of designing the game for one specific goal, you can design each of its components and its overall functionality. The effect of this approach will be that you will better understand what you really need to do, and you will not blindly follow the described behavior in the project documentation for the game.
For example, if a game requires only four types of weapons, you can program a perfect system that describes all of them individually. However, if you abstract from the functionality of each of the weapons, using the data defining the behavior, you can later add countless types of weapons to experiment with new ideas and dynamics of the gameplay. Such thinking, ultimately, allows the game to improve and develop.
Did you believe me when I said “Nothing”?
The truth is that games must be customizable, and big games must evolve from the original version, following the plot. Your game should be able to work with changing rules, characters, races, weapons, levels, control schemes and objects. Without this flexibility, any change in the game becomes costly, and even a minor change involves the participation of the programmer - which is essentially just a waste of resources. If the changes turn out to be difficult, then this may lead to a slight improvement in the original game design, and the game will not survive until the disclosure of all its possibilities.

Thought 4: Master Controlling Scenario


A script is simply a way of defining behavior outside of program code. Scripts are great for determining the sequence of steps that should occur in a game, or for game events that need to be triggered. For example, a scenario for a game scene that describes a simple causal logic, such as “what will happen if the quest is completed” or “which trigger will work for a given environment.” All these examples relate to the data-driven design paradigm.
When designing scenarios, you need to decide on the logic of branching and how it will be organized. There are two approaches. The first is to continue to use variables inside the script and compare them with comparison operators: equality (=), less than (<), etc. The second approach is to directly call the evaluating function, which compares variables that exist within the code, for example, isLifeBelowPercentage (50). You can use a combination of these methods, but at the same time try to keep the scripts simple. A game designer will find it much easier to work with rating functions than with declared variables, their updating and comparison. Also, the second approach will simplify debugging.
Unfortunately, an appropriate language is required to describe the scripts. This means that you must create an entire syntax to define the behavior of the game. The scripting language includes the creation of a script parser and, possibly, a compiler to convert scripts to a binary file for faster execution later. Another option is to use an existing language, such as Java, but in this case, a large number of additional components may be required. In order not to spend a lot of time on a scripting language, you need to win by designing systems easier. In general, there is a tendency to impart unnecessary power to the scripting language. The following thought explains some of the pitfalls of a complex scripting language.

Thought 5: When Good Scripts Go Bad


Using scripts to describe behavior in data-driven design is a natural consequence of this methodology. However, we should not forget about common sense and remember the key idea: the separation of logic from data. Complex logic is sent to the program code, and the data remains outside.
The problem arises when the desire to base data goes too far. At some point, you will want to describe the complex logic within the script. When a script begins to contain the state of something and requires branching, it becomes like a state machine. As his fortunes increase, the innocent script writer (as well as some poor game designers) will have to work as a programmer. If the scenarios become too complex, the work returns to the programmer, who must describe all the difficulties in his strictly limited language. Scenarios should make people's work easier, not more difficult.
Why is it important to store complex logic in code? The issue of functionality and debugging. Since scripts are outside the code, they duplicate many of the concepts that exist in programming languages. The natural tendency is to give more and more functionality to scripts until they become real programming languages. More complex scenarios appear, and more information needs to be tracked when debugging, which complicates the initially simple idea of ​​working with scripts.
As you probably guessed, the scripts can have non-trivial logic, and then it can take months to write a script parser, compiler and debugger. This would happen if programmers did not understand that there was already a fairly good compiler in front of them.
Blurred border
There is no doubt that the boundary between code and scripts is blurred. In general, it’s a bad idea to put artificial intelligence (AI) behavior in scenarios, while placing the system triggers in scripts to make the world more interactive is a good idea. The following rule is obtained: if the logic is complex, then it should be in the code. Scripting languages ​​should remain simple so as not to devour your game (and all your programmer resources).
However, some games were designed with the ability for players to write their own AI. Often, this first-person shooter, allowing you to add bots. When the goal is exactly the same, the similarity of a scripting language to real programming languages ​​is simply inevitable. As an example, consider Quake C. Since the creation of bots is embedded in the game itself, resources and energy have been spent on creating a scripting language that is as convenient as the C language. A scripting language of this magnitude is rather laborious and should not be treated lightly.
First of all, remember that you do not want game designers and screenwriters to program the game. Sometimes programmers try to evade responsibility by creating scripting languages ​​to lure game designers into game programming. In the ideal case, programmers should solve serious problems and create a significant part of the control logic. Otherwise, what else do they get so much money?

Thought 6: How to avoid data repetition syndrome


A common programming practice is to never duplicate code. If you need some behavior (for example, common functionality) in two different places, it should only exist in one place. The idea is applicable to the description of data with the help of links to global data blocks. In addition, by using references to datasets and changing some of their values, you end up approaching the concept of inheritance.
Inheritance is a huge idea to apply to your data. Imagine that your game is inhabited by goblins living in dungeons. Your data determines where each goblin stands with all its properties in each dungeon. It will be correct to encapsulate the global definition data into each goblin instance. In order for each goblin to become unique, the link may be accompanied by a list of redefined properties. This approach will allow each goblin to have their own behavior, while not duplicating data.
The idea can be applied at several levels, allowing each data set to have a link. Using this technique, you can make a global definition of goblin, which is inherited from the basic type of goblin. Inside the definition, regular or fast goblins can be specified for each dungeon. The figure demonstrates this concept of inheritance using links and redefining values.


Thought 7: Make a data tool


In any big game, text files end up becoming unmanageable and it becomes hard to work with them. The solution to this problem is to create a tool for working with them. Let's call this tool the game editor, level editor, or script editor, it will speed up the development of the game. Possession of the tool does not change the data-driven methodology, but only makes it more reliable and efficient. The time saved with these tools justifies the cost of their development and implementation.

Conclusion


Getting started using data-driven design is easy, but it’s pretty hard to imagine the amazing possibilities that come with this approach.
Total Annihilation is a good example of this approach. Designer Chris Taylor laid two races: Arm and Core. Although the whole game is focused on two races, they were not tightly programmed into the game. In theory, one could add data to add a third race, even after the game was released. Although this feature was not used, Total Annihilation remains fully customizable in this regard. Since all units are determined by data, new units are published weekly on the game website. In fact, many people created their own units with functionality that shook the game developers themselves.
Data-driven design helped Total Annihilation support loyal fans of the game in an already crowded genre. The idea implemented in Total Annihilation has been further applied in other games, such as The Sims, which also distribute additional game content through the web site. Without developers' commitment to the data-driven design philosophy, such extensions would be impossible.

Source: https://habr.com/ru/post/204298/


All Articles