U
U
undeadter2016-10-04 14:15:59
Game development
undeadter, 2016-10-04 14:15:59

How is multithreading organized in RTS games?

Please explain how RTS is organized or where you can read about it. Interested in the part that is responsible for the actions of units in games where there are several teams and each of them has 50+ characters, not counting buildings. Each character is independent and can walk around the map in any direction, "form up", attack/defend, etc. Example: Age of Empires, Cossacks, total war, etc. Purely theoretically, I can organize several threads: drawing graphics and a pipeline of actions for units like FIFO, but is this enough for a smooth game with so many actions? I myself have not experimented yet, but I have not found what to read about this.

Answer the question

In order to leave comments, you need to log in

6 answer(s)
R
romy4, 2016-10-04
@romy4

One option is to have time to invest in one step. All units move between grid cells. They may be small enough to be invisible to the user. And the movement of units is not instantaneous, each step still takes 50-100ms. At this time, the AI ​​must meet the calculations of the next step.

M
Mercury13, 2016-10-04
@Mercury13

You can do without parallelism - and at first it's better to do it.
If you really want to do a lot of threading, I would break it into two threads, intelligence and graphics.
Each unit has three identical structures, renderInfo, bufferedInfo and aiInfo. There can be coordinates, a heading, HP, a link to the next one - anything. The link to the next one is important, because units can appear and disappear.
Intelligence flow works with aiInfo; somewhere here is the multiplayer code. Having finished the step, the thread captures the mutex and for all units (the concept of "all" is determined by aiInfo) gives bufferedInfo = aiInfo.
The rendering thread grabs the same mutex and for all units ("all" by bufferedInfo) gives renderInfo = bufferedInfo. And then, after releasing the mutex, he does what he wants with this renderInfo.
We will sit under the mutex very little: there is neither drawing nor multiplayer.
Since a unit disappears from memory only when references to it in all three structures disappear, either an object pool must be created (that is, a unit, once created, remains forever, but later this memory block can be used for another unit), or some "garbage" pointers like std::shared_ptr.
This system is similar to triple buffering in rendering. Only in video triple buffering do monitor frames and renderer frames act asynchronously; we have game clocks and renderer frames.
Splitting intelligence into streams is frankly hard, and in a game with multiplayer, I just don’t know how. RTSs usually send short packets over the network like "select units in the square (X,Y) - (X,Y)", "add unit 1234 to selection" and "go to point (X, Y)". These commands, when executed on different computers, are executed in the same way.
If you combine these two constructs - repeatable calculations and asynchronous rendering - inaccuracies are possible, and I hope they will be acceptable - on the screen (renderInfo) the unit falls into the marked square, but in aiInfo it is no longer there, since it has moved.
A separate issue is ping compensation in games over the Internet. Haven't thought about it yet. Probably have to have officialAiInfo and lagCompensatedAiInfo...
PS. They suggest that the game cycle in such a situation lasts about 0.1 s, i.e. may take several frames. Then in all these …info it is necessary to describe the movement in such a way that at any moment you get an intermediate x(t), y(t), yaw(t)… For a tank — bodyYaw(t) and turretYaw(t), for a little man — the animation phase …
ZZY. If the game is 3D and the view is somehow customizable, one of the game commands will look like "select units in the square (X,Y) - (X,Y) with transformation matrix A".
ZZZY. In order for the game to be repeatable (important for multiplayer), all calculations that affect the course of the game should be carried out in a fixed point. All variables associated with this, anything, at least zero, but initialize.

D
Dark Hole, 2016-10-04
@abyrkov

but is that enough for a smooth game with so many actions

If you lick the code, then yes. The main thing is to avoid unnecessary calculations.
As for the threads - you can experiment with the number of units per thread, you can't say specifically here.

A
Alexey Yeletsky, 2016-10-04
@Tiendil

Two threads: graphics and logic.
The logic is step-by-step in steps of 0.1-0.2 seconds, depending on the needs. Step-by-step means that real time is not taken into account in it, the game goes in turns: 1, 2, 3, 4 ...
Logic sends commands to the graphics that control the display. For example, if a unit has moved X meters, then the logic sends a command to the graphics: "move the unit X meters in 0.1 seconds". The command is executed on each redraw and gradually shifts the unit's sprite/model to the desired position (at 60 FPS it will be shifted in 6 redraws, x/6 meters each time). Several commands can change the display of a unit at the same time, for example, one moves the tank, and the other rotates its turret.
The stream can be and one, but the same remains. This is how it is done in most AAA games, in particular, in Order of War.

V
Vladimir Kuts, 2016-10-19
@fox_12

Install the package already compiled for windows from here www.lfd.uci.edu/~gohlke/pythonlibs/#numpy Or install
and configure Visual Studio for compilation

S
sergsh, 2016-10-19
@sergsh

You can install Ubuntu as a second system, pip will definitely work there.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question