Incomplete game entity Design

Source: Internet
Author: User

Incomplete game entity Design

2006-11-26

In the game engine, entity is often translated into entities, and often used names such as gameobject, actor, simulationobject, unit, and character. Compared with the enthusiasm for the image sound engine, the entity layer has been unpopular for many years. However, with the development of large games in recent years, the importance of the entity layer design has reached the same level as that of image sound, moreover, a variety of general entity architectures have emerged. Of course, there are disputes and disagreements.

Direct mode (the C approach)

This is the earliest and simplest model that anyone can think of directly. In this way, the next entity is a simple struct:

Struct mob
{
Int level, HP, MP, attack ,...;
};

In this case, you often need to define different struct types for different entity types, such as player, mob, item, and doodad. Entity databases can directly use existing database systems or read data files, such as CSV files. You can select EXCEL to edit the database and then export the CSV file. Excel's powerful table and statistical computing functions are powerful tools to balance game data. As a result, this oldest and simple entity model has lived to the present with its powerful vitality.

So why do developers need to explore other methods? The biggest problem is that different entity types are completely different in this method. For example, player, mob, and doodad all have locations and must perform collision detection. However, they are of different types and cannot use the same code. Both player and mob have HP and MP, there are also basically the same processing logic ...... Of course, this can be solved using the hack method: as long as the previous several member types and sequences of each struct are identical, the pointer cast can be processed as a unified entity type. However, anyone can think of a better way to use classes!

Inheritage)

This is also the origin of entity, gameobject, and other names. They are base classes. So we can get an inheritance relationship tree, for example:

Entity

Character

Player

Mob

Missile

Laser

Guidedmissile

Item

...

The logic of Entity objects is mostly directly included in the class. However, some people use the separation of Data Objects and logical objects. The advantage is that different logics can be replaced for the same data. However, I personally doubt whether such separation is worthwhile, because the derivation of classes itself can have different logics.

In addition to standard direct access, entity interaction often uses message mode. Message mode is similar to message mode in windows. entity interacts with messages. Although Window Programming has drawn many years to get rid of the message processing mode of the heavy switch, it makes sense to use the message mode at the Entity layer, because messages are easy to broadcast and can be sent directly on the network. Those who are obsessed with OO will write the message as a command object, but the principle is still the same.

In addition, when online games appear, pointers cannot identify objects on different machines. We must use stable IDs to identify objects. Therefore, we have entitymanager to allocate IDs and manage object sets, or gameobjectmanager or objectmanager. This has almost become a perfect solution for a period of time.

With the rapid expansion of the richness of game content, the traditional mode of implementing the game logic functions by programmers is becoming increasingly inadequate. The integration of scripting language took most of the creative work from the programmer's burden and handed it back to game designers. In order to provide sufficient control to the script, the entity structure must be sufficiently flexible.

Data-driven)

The only thing that remains unchanged is change. (The only constant is change.) "data drives minimize the impact of changes on the engine. Data-driven is not an independent entity model. It is better to say that it is a design idea. Its purpose is to separate content production from game engine production. Unlike the above-mentioned entity attribute filling database, it also needs to be able to design game logic through data.

One of the most basic functions required by game designers is to customize character attributes. Therefore, instead of writing an attribute member to a class, it is better to use Attribute tables (attributes/properties ). Generally, a hash table (hashtable), STD: map, or dictionary, or an array is used as a key-value ing table. Then, you can operate the Attribute Table for the script and editor.

The dynamic logic mainly depends on scripts, and enough events and methods must be provided for the scripts. I personally recommend using Lua scripts because it is the most widely used scripting language in the gaming field. Its engine is small, fast, and easy to integrate, although its syntax is too loose. Do not be superstitious about using a large, extremely slow, and difficult to integrate python. Provide events for the script, that is, calling the functions in the script. If the message mode described above is used, you only need to call a script method, you just need to pass different message parameters. Of course, some people think this is ugly and prefer to register different functions for different events.

With data-driven, the inheritance tree of entity is basically meaningless, because an entity is no longer determined by the program, but designed through data and scripts. However, data and scripts are not all. The core content of an entity and the part that needs to be processed efficiently, such as collision detection, must be completed by a program. So we need to re-design the entity class, and the difficult situation starts from this.

An intuitive idea is a unified and unique entity class that includes all basic functions such as display, collision detection, motion, and backpack, data determines which components are enabled. For example, a player role may enable most components, while a tree only enables the display and Collision Detection components. But it is also accompanied by disadvantages: 1. This class is too big; 2. For simple entity such as trees, the memory occupied by private data of other components should also be wasted. A simple compromise is that some use of inheritance and some use of data customization. For example, entity only provides the most basic components, and then sends charactorentity to provide components that are sufficient for character roles.

Component-based entity)

When talking about components, it is natural to transition to the component mode, that is, to make basic functions such as display, motion, attack, backpack, team, and sound into independent components, the data determines which components are added to the entity. In this way, we can get another extension, that is, since there can be built-in engine components, there can also be script-making components to achieve reuse of the script module. This model was officially proposed in gdc2002 and has been applied to mainstream engines.

This mode is perfect in theory, but there are still many questions in practice. The most common problem is the dependency between components. Ideally, each component is completely independent, but it must be dependent in practice. For example, the Movement speed and attack intensity are related to the basic attributes of the role. The motion component requires the role's surrounding box to test whether a collision exists. The AI component needs to analyze the current status of the role and issue the motion and attack commands, when the role action status changes, the display component properties are changed. The attack component needs to access the team information component to prohibit attacks on teammates. To handle this dependency, we need to solve two problems:

I, Who depends on who. For example, whether the agile attribute changes to the moving speed, or whether the motion component reads the agile attribute to calculate the moving speed. If you want game designers to define basic attributes freely, You need to select the former, because the basic attribute component will be a script component.

II, How to obtain the pointer/reference of another component. A common method is to provide a unique ID for each component type, and then use this ID to query the registered component on the entity. If the registered component is found, its pointer/reference is returned. Otherwise, null is returned. Of course, this query is a waste of CPU resources for each access. If entity components are not dynamically added or deleted at runtime (unless in the editor, few will do this ), after entity initialization, each component can cache other component pointers it uses. What if the dependent component does not exist? In general, it is ignored silently.

When entity is composed of many components, interactive messages need to be sent to each component. Once again, this shows the advantages of the message mechanism. You do not need to write a loop for each event function in entity to call the corresponding event function of the component. But there is also a problem here, the order in which messages arrive at each component. In many cases, this sequence does not affect the development of logic.

In addition, the serialization storage of entity has become more complex, and the classic Excel export CSV mode is difficult to work, because structured storage is required here, so structured data files such as XML need to be stored, or you can use a script to completely include all the data and construct the entity.

According to my personal experience, when using the data-driven inheritance model, I look forward to the component model. I feel that it is a very natural extension direction, but I have no worries about the extra complexity it introduces, in particular, game designers are required to have certain programming capabilities, so they have never dared to take over all of them. However, the component concept is still used in the engine, but the composition of entity components is fixed during compilation, which can achieve some compromise, which is similar to the compromise between inheritance and data-driven.

Mix-in)

This is another common compromise mode, that is, the multi-inheritance of c ++ is used to mix each component class into an entity class. For example:

Class mob: Public gameobject, public renderable, public movable, public attackable
{
...
}

This method is used by many engines because it is simple and highly compatible with the Multi-inheritance design idea. Of course, the disadvantage is that it can only be used in languages that support multiple inheritance, and when the components are rich, dynamic_cast becomes a costly operation.

Functionality vs complexity)

One of the oldest principles in the programming field is "simple and fast ". But with the complexity of the problem, the program becomes more and more complex. A good method can effectively reduce or hide complexity. However, no silver bullet. brings additional complexity when it comes to more powerful features. We need to make trade-offs and sacrifice some features when necessary, that is, to estimate the cost effectiveness.

Generally, game content producers do not or are not very familiar with programming, and programmers are not good at game content creation and value balancing. a complicated system will lead to talents that need both sides, this greatly increases the difficulty of making a game.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.