Game entities, logics and rules representation in MMORPG

Started by
5 comments, last by pcwlai 20 years, 1 month ago
I am currently working on a MMORPG project. We are currently seeking a way in representing entities, logics and rules for the server codes which will carry out all the simulations and game rule enforcements. C++ is our main development language and Python will be used as our scripting language. In the first thought, we choose to use C++ classes to represent all the entities in the game, from player characters, monsters, items to abnormal conditions and skills. In order to simulate the game logics and game rules, we decided to use single inheritance with interface inheritence paradigm. Whenever there is state changes, buff the entity, abnormal states occured upon the entity, etc., we will try to register the changes to the entity''s appropriate event queue. Evet queues for different allowed game commands are evaluated before that command is carried out. e.g. When a player tries to attack another player, his buff''s, weapon''s buff''s and poision status''s attack interface will be called accordingly. The interfacces will affect the current state of the character and give out the attack power or even block the attack if our game rules set to prevent an attack if poisoned. After working on changing the design concepts to real C++ member data and member functions (interfaces), we found that, it is somehow not flexible enough for an MMORPG. This is because, whenever we create a new entity, we need to make it a derived class of the "base" class in order to have default processing of those unused interfaces. And in order to store the entities in event queue, object pointers are needed and this results in a lot of virtual functions. Another problem is that, the order of evaluation between items in event queues are somehow difficult to define. If we fixed all the sequences, it will be really difficult to add new entities as this woudl require a new order list in evluation priorities. The last question is, how to represent a player character in different classes (job) and allocate the memory for their specific attributes and skills? Here, I would like to ask for help in how others do the above things. Thanks very much.
The poorest programmer in the game industry!!
Advertisement
I''ll try to describe how I resolved some of those problems in my own engine; hope it helps.

There is a base class that maintains the most common attributes of game entities: name, type, location (3D coordinate in space), size, hit points, etc. Eight classes are derived from the base class to encapsulate specialized code for certain entity types. Every entity also has an attribute map that serves two important purposes: it exposes class members to the script interpreter, and it allows scripts to create new attributes at runtime. So far I haven''t found a problem that this system isn''t robust enough to handle.

quote:After working on changing the design concepts to real C++ member data and member functions (interfaces), we found that, it is somehow not flexible enough for an MMORPG. This is because, whenever we create a new entity, we need to make it a derived class of the "base" class in order to have default processing of those unused interfaces. And in order to store the entities in event queue, object pointers are needed and this results in a lot of virtual functions.


I''m not sure what the problem is here. Can you elaborate?
Post Extant Graphical MUD
I guess the issue is that the base class has to have a lot of virtual functions in order to support entities higher up the inheritence chain which require that functionality yet need to be called via a base pointer.

Assuming this is the case then you''ve got a problem, as if you want to call ALL entities via a base class pointer you have to have them inherit that base class, so you are either going to have to accept the virtual problem or possibly work on some sort of slimmer interface and handle the extra data in some other way, maybe via scripting inside the entity to handle what it should be doing.
In theory, this could be doable via a msg system, msgs of a certain type go into the class, if the class needs to act apon it it does so via its script, if it doesnt it doesnt and control is returned. This could probably be used in turn with the aformentioned attribute map to let the scripts dynamicaly reprogram the entities without changing the code at all.

An other option, is to try to refine the types you have and deal with them via different base classes, this will cut down on the number of base virtual functions you''ll have to maintain, however you then cant put everything in the smae event queue.

A possible 3rd idea has just spung to mind, place ''event objects'' in the event queue which have weak pointers (I''m thinking boost::weak_ptr but anything like that would do), when it comes to process the event, get a shared_ptr from the weak_ptr and call some common interface.... which kind of loops back to the message system idea now i consider it.

(It should be noted when reading the above that (a) i''ve been awake since 7:30am Sunday morning after only 3h sleep and its now 4:15am monday morning, so i might not make sense... and (b) I''ve never tried anything as big as a MMORPG before so i could be talking total dren... however, feed back on those ideas from others, maybe expansion/refinement would be welcome coz this is as much for my own useage later as for now and frankly, i have all my best ideas sleep deprived )
The problems on defining classes and algorithms in defining entities, game logics and game rules are, we need to have flexabilities for game designers to change and update game contents during the service time (life span) of the game.

In order to allow for sophisticated interaction between players/players, players/monsters and monsters/monsters, a generic entity definition is prefered. This is especially true for having lots of classes on player characters.

In order to accomodate largely different class/skill set attributes, there may be a lot of C++ classes defined to derive from the base class.

In the basic game logics and rules, common attributes and statuses are defined in the base class. This should be fine for most of the time. Somehow when skills and abilities are considered, special cases arises a lot. Like some skills and abilities will require special states and storage of the skills and abilities. This makes is very difficult to lay out memory footprint of the entity and difficult to make them well suited in the event queue.

Another issue is that, because of the vast contents and interlocking of game logics, it is quite difficult to well define which skill''s or ability''s event should be processed. It is posssible but not feasible to create a large map between skill/ability event priority. And this will also make the addition of new contents extremely difficult and buggy.

The best way is to work out everything in the scripting language but this would be far too slow and the game designers will be over exhausted by the programming tasks.

So, I would like to hear some new ideas or how others are doing it.
The poorest programmer in the game industry!!
quote:Original post by pcwlai
In the basic game logics and rules, common attributes and statuses are defined in the base class. This should be fine for most of the time. Somehow when skills and abilities are considered, special cases arises a lot. Like some skills and abilities will require special states and storage of the skills and abilities. This makes is very difficult to lay out memory footprint of the entity and difficult to make them well suited in the event queue.

Another issue is that, because of the vast contents and interlocking of game logics, it is quite difficult to well define which skill''s or ability''s event should be processed. It is posssible but not feasible to create a large map between skill/ability event priority. And this will also make the addition of new contents extremely difficult and buggy.


It sounds like you want a more robust solution than what my engine does. Any time a character uses a skill, only that particular skill''s use() function is processed. Other skills can modify that skill (for example, a character''s Chemistry skill could boost his Alchemy skill), but those other skills'' use() functions don''t actually get executed.

quote:The best way is to work out everything in the scripting language but this would be far too slow and the game designers will be over exhausted by the programming tasks.


How about letting the script process the rules for using the skill, and passing a value to the engine that tells it whether the requirements have been met? In my engine, every skill can have an onuse script that returns a boolean. If the script returns false, the skill cannot be used. A crude example:

# sample onuse script that limits use of a skill to a particular# locationset p [getparent $user] # Get the user''s current locationif {[getattrib $p "name"] != "the magic school"} {  # User is not in the magic school.  Cannot use the skill.  msg $user "You have to be in the magic school to do that."  return false} else {  # User is in the magic school.  Use of the skill is permitted.  return true}


That way, the script can handle special-case game rules, but the engine itself still handles the use() function.
Post Extant Graphical MUD
The scripting method provides game content designers a lot of flexibilities in changinging the game logics but this will give a lot of performance penalty in our current hardware and software limitations.

Another problem on this is, due to the large amount of skills, abilities and inter mixed situations (e.g. a player with the skill, 100% hit while the other player woth the skill, 100% flee, we decided the hit will override the flee, just an example), if we put all combinations in the scripts, it will beome and nightmare for game content designers and they will suffer from lots of programming which may turn out to be not feasible.

I would like to seek a solution which can turn all the logics into data or rules such that, the core engine can handle them appropriately.

Inheritance seems to partition classes and encapsulate data (which solved the memory allocation problem in general and specific player / monster classes) in a good manner but it will need to update a lot of things in order to make a small change in game logic.

Abstract interface seems to be a good method but this will make a lot of hardcoded derived classes.

Windows message processing method seems to be a good way of building a very flexable system but this will make a lot of type casting and exceptional cases in derived classes.

It is a very good idea to hardcode every possible combinations in single player RPGs but it is a very bad idea to do so in MMORPG.

This is what we are facing in the server codes we never have experience on single player games.

Thanks for the above replies and wish to get some more ideas and discussions.
The poorest programmer in the game industry!!
After looking around in this forum and inspired by some other programming and pattern design articles, I have the following questions as well,

Is using abstract class to define action interfaces better or using windows message processing method by passing the action command better?
The poorest programmer in the game industry!!

This topic is closed to new replies.

Advertisement