Preserving synchronization in a multi-player RTS game using floating point arithmetic

I am writing a 2D space RTS game in C #. Single player works. Now I want to add some multi-user features. I searched this for Google, and it seems that there is only one way to continuously move thousands of devices without a powerful network connection: send only commands over the network while running the same simulation for each player at the same time.

And now there is a problem that the whole engine uses doubles everywhere. Floating point calculations are heavily dependent on compiler optimizations and processor architecture, so it is very difficult to synchronize things. And this is not a grid at all, and they have a simple physics mechanism for moving spaceships (spaceships have momentum and angular -momentum ...). Therefore, recoding all the material to use a fixed point would be rather cumbersome (but probably the only solution).

So, I have 2 options:

  • Goodbye to current code and restart from scratch with integers
  • Make a gaming LAN only where there is enough bandwidth to have 8 players with thousands of units and send positions and orientation, etc. (almost) every frame ...

So, I'm looking for the best opinions (or even tips on moving the code to a fixed point, without ruining everything ...)

+7
floating-point c # network-programming multiplayer
source share
4 answers

Of course, all your clients will use the same binary, so optimizing the compiler does not affect synchronization problems.

In addition, if you only plan on targeting one architecture (or at least only allow people to play against each other if they are on the same architecture), that doesn't matter either.

I did the same thing using floating points in C # development games for the iPhone and the desktop, and they both give the same results, although the iPhone is ARM and the desktop is x86.

Just make sure that the game performs exactly the same calculations and you will be fine.

If all else fails, simply replace all float instances in your game with a standard fixed-point arithmetic class. Thus, you can be 100% sure that your calculations are determined by architecture, although the nature of fixed-point arithmetic can adversely affect your game.

+2
source share

I answer this a bit late, but from the point of view of the game’s security, the simulation should only be performed on the server / host (i.e., do not trust clients, they can be a hoax):

  • Clients should only send their movements / commands to the server (which discards bad inputs or pinches them within the game, so the client saying "I work at a speed of 10,000 m / s" is pinched by the server to say 10 m / s).

  • The server / host only informs clients about things happening in their field of view (i.e. the player at coordinates 0,0 does not receive information about two AIs fighting each other at 200.0 if he can only see a radius of 50 units around him).

This is the second part that saves bandwidth - a server / host simulation can have thousands of objects to manage, but customers only need to know about 100 or 200 things in their own field of vision.

The only wrinkle in the situation is such things as dynamic fire (bullets, missiles, etc.), whose range may be greater than the radius of the client's presentation. The server / host informs the clients about the origin and initial trajectory / target, then the clients simulate their path according to the same rules, but the killings are only valid in the simulation on the server / host.

Serializing the client world and compressing it before passing it can also be a huge victory, especially if your class properties are only Public, where necessary. (I usually avoid XML, but we greatly improved compression ratios in one application by serializing to XML and compressing it compared to binary serialization and compressing it. I suspect that the limited range of ASCII characters used was YMMV.)

+1
source share

A common technique is to periodically refer all clients to the current state of other clients.

When two computers do not agree with the state of the object, presumably due to a floating point error, there is a rule in the game to determine what is right, and all clients adapt to it.

0
source share

What do you use for doubling? Could you use decimal?

The shared server will store the state (position / oriantaion / type) of all player blocks.

When player1 moves the block either ... the move prompt is sent to the server or ... the updated state is sent to the server

When the client-client must display the scene, the server sends status information to the position of all units within the requested area.

0
source share

All Articles