Server side is implemented in the multiplayer online games
I have never met a programmer during my short life, who would not love the games. Moreover, a programmer that has never written them.
Someone begins with “Tetris”, the other one with the “Snake”. Someone loses the interest, and the other one gets “sick” and turns that illness in a favorite work or entertaining hobby.
In the era of the Internet and social networks to play alone is boring, we want to communicate and play with friends.
We do not want just to communicate, but to go underground with the group or to show who is boss at the arena.
In this article I would like to tell about my approach to the server implementation of such interaction.
Let us consider the example of a simple game application in which the player controls a character, which can buy \ sell items, fight at the arena, and go alone underground or with the friends.
For example, a player creates a group to go underground. The player sends a request to our server which adds a new group to the list of available groups to go underground, and then the other players are able to obtain this list and join it. When the group is formed by pressing a button, the creator sends it underground to meet the dangerous monsters.
It would seem simple. We create a table in the database, enter willing people there and send them underground.
The most beginning programmers think just like that, but they forget about the most important problem of multi-tasking systems - race condition.
It is logical to assume that the correct implementation of such interaction would be a server daemon that is responsible for the condition of the gaming world, taking requests from the players (in turn order), would process them, and gave back the result.
In our case, the server must store the current condition of the players that should correctly process the results.
Schematically it looks like this:
Perhaps, the most interesting is the query processor.
It contains the basic logic of the server:
- Storing the condition of players (free, underground in a group, etc.)
- Storing and processing of the information about the game world (the battle at the arena, going underground, the group to go underground)
We need to store the condition of player in order, for example, while a character is engaged in genocide against the monsters underground, we could not go to the arena or buy some new armor.
In addition, the server should not process the game world.
Suppose we went underground for 5 minutes. The server should process the battle with monsters for 5 minutes, count up the experience, drop, and change the condition of player.
We should not forget that the number of players can be very large and server will receive a big load.
In order to implement this demon was chosen a language PHP 5.3 with the expansion of libevent, as the most familiar to the author.
There are many articles about libevent that are created by well-known phpDaemon, so there is no sense to go deep into its work.
We only need to note the possibility of creation delayed events (flag EV_TIMEOUT), which takes care of a lot of problems in this case.
However, among other things the server should actively work with the database to record the results, purchases of things etc.
As known, the database is the bottleneck of any serious application, and the server can “hang” from a large number of queries.
Therefore, processing the “heavy” queries can provide an additional server daemon with the necessary number of threads (thread / workers), who will gladly do all the hard work.
It should be noted that queries to work daemon also wait in line and they are not processed until we get the answer.
The mode of operation of the work daemon is the same as the main daemon, except for the presence of a few threads (thread / workers) to process the queries.
The advantages of this approach are as follows:
- we reset to work daemon all the hard work, and the processing of players’ conditions, we leave on the main daemon, which makes it very lightweight and fast
- work daemon can be taken to the separate server, if necessary, and the number of workers vary depending on the hardware
- there is possibility of ranging
Now, let us discuss the disadvantages.
The main disadvantage of implementation: PHP flows. Even the new garbage collector does not solve all problems in 5.3. We have:
Solution: periodically overload the worker when memory usage reaches a certain limit.
I see the most appropriate solution that is using the programming language Erlang \ OTP.
The task perfectly fit into its concept of FSM / gen_server.
I hope that article will help the beginning game developers do not make these mistakes and properly design the application.
P.S. If this kind of subject is interesting for the users of umumble.com, I am willing to tell more particularly about each of the components of such system.
“Translated from another resource”
|Vote for this post
Bring it to the Main Page