Answer the question
In order to leave comments, you need to log in
Delayed background events in an online game?
Let's say there is a browser game in which you can send an army to attack a neighbor. The army will come to the neighbor in an hour, without my participation, a battle will take place, the result of which will depend on the configuration of the neighbor's army. At the same time, a neighbor can change this configuration even at the last second.
Those. I generate an event that must be processed at a certain time and the result of processing will depend on the data that is relevant at the time of execution.
What is the best way to handle such events on the server?
The obvious comes to mind - add an event to the queue with the "time" parameter, the background script constantly checks the queue and if there are events that need to be executed, it processes them all in turn.
What worries me about this approach is that with a large number of participants, there can also be many events, including those scheduled for the same time. Their sequential processing may take time and at hour H, there will be no result yet (that is, the game will display something there, but not the results that the players are waiting for).
Perhaps there is some more logical solution for deferred events? or should you not worry about speed, but make it so that processing takes very little time?
Answer the question
In order to leave comments, you need to log in
What worries me about this approach is that with a large number of participants, there can also be many events, including those scheduled for the same time. Their sequential processing may take time and at hour H, there will be no result yet (that is, the game will display something there, but not the results that the players are waiting for).
But seriously - the fight should be instant? Here the army arrived and bam - did everyone die? Simply freeze the defense settings at the moment the enemy arrives and enter the battle time - depending on the number of troops or standard, for example, 15 minutes of real time. Those. you will have 15 minutes to calculate the result of the fight. I managed to count - it is saved and we are still waiting for the remaining time. If you ever encounter a performance limit, the battle time is simply extended, in case the result has not yet been calculated.
The army will come to the neighbor in an hour, without my participation, a battle will take place, the result of which will depend on the configuration of the neighbor's army. At the same time, a neighbor can change this configuration even at the last second.we throw the event: “the army came to the neighbor”, start time, configuration
we rake the events, select by time -> the time coincided:
“the army came to the neighbor” (configuration) -> initiation of the event: Battle (configuration 1, configuration 2, time)
Why not try a timer? It is triggered when the conditions for some actions occur at a certain moment. At this moment, the handler is called, the actors are blocked for the duration of processing, it worked - the data was shown.
I see a problem only if there are several servers and it will be almost impossible to synchronize them.
The question was somehow strangely asked, I didn’t understand what you still need ... So that all events are guaranteed to work out in a given time? Or that the internal state of the system is not disturbed?
I would solve this kind of task using the a-la RabbitMQ queue manager. They support deferred execution of tasks. Well, data on the state of the system can be obtained at the time of the start of the task.
The problem of a large number of users is solved in the classical way - by increasing the number of workers ... Several worker servers can receive tasks from RabbitMQ, so parallelization can be very wide.
For your example: queue up the "attack neighbor" pending event. At hour H, this task is launched on one of the workers, takes the current configuration of the enemy troops from the database and calculates the result of the battle. After the calculation, it saves to the database or informs the user or starts another task in the queue ...
1) We place all events in the queue.
Up to hour X
2.1) If time X has not arrived, and the processor is idle, we calculate the outcome of the battle, but save the result in a temporary table.
2.2) If the user has changed the conditions, we destroy the saved result in the temporary table.
Hour X
has come 3.1) If time X has come and there are calculated data in the temporary table, then copy them to the main state of the game.
3.2) If the time X has come and the temporary table is empty, then we calculate the outcome of the battle.
The task arrived - went to the database. Regardless of the player's authorization, the characters complete the task. Moves can be initialized and calculated by krone.
It is hardly possible to talk about any significant increase in resource consumption in this case, in comparison with the resource intensity, which in any case will be present with any other solutions.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question