Advertisement

Server battle predictions?

Started by January 10, 2018 08:52 AM
2 comments, last by menyo 6 years, 10 months ago

I got a little client side auto battle game going, you pick some units and the battle progresses visually but automatically with a lot of random elements. However, I want need to verify the outcome by the server. I also want to be able to let clients duel other clients. So what is the best take on this problem?

  • Instead of heaving the complete battle play out on the server or check/compare every action from the client that is being played out randomly I figured it must be possible to just calculate the outcome quickly and once the client has finished the battle just verify that result with the server. I would just generate a seed on the server, pass that to the clients so the battle can be generated and played for them. In the meantime the server quickly calculates the outcome and checks that result with the client. Is this possible at all?
    • Would a seed generate the same random numbers on each and every machine when using the same Random() implementation?
    • Should I just loop trough the whole battle on the server side? Like moving each unit, detect hit, fight, damage, etc but instead of doing that each frame just in a single loop? Can I perhaps skip trough and interpolate these steps?
  • Just let the game play on the client and check each action with the server. Both clients would still need to get the same seed and the server needs the match the action with it's own "battle".
    • I expect the outcome of both clients to defer from the server outcome. Same as above.
  • Have the server run and dictate the battle and the client just displays what is happening.
    • Since the battle has random elements the client needs to ask the server each frame what to do which is a problem. 
  • I really cannot set the random aspect aside, units have to be able to "dodge" or "critical" every now and then. But perhaps this can be implemented in a different way since the battle outcome should be fixed.

 

As you see I'm having trouble wrapping my head around the whole concept. I have a fairly good understanding of network gaming. when the player controls a character you could let the client just do it's thing and occasionally checking variables and correcting the client based on server state. With my automatic battle the outcome of the game should be fixed and predetermined, especially when having clients PvP.

Easiest is to run the simulation on the server, once, and record the movement and actions of all entities. Then let players view this recording, a bit like a videotape. You can hide the fact that the outcome is already "determined" through UI.

Second easiest is to develop the simulation code such that it is deterministic. The exact same inputs, simulated through the same simulation engine/code, should lead to the exact same output. Initialize all random number generators with know seeds. Make sure all inputs are provided in the exact same order. Step the simulation the exact same way, with the exact same simulation step size. Ideally, use integer math rather than float/double math. This will let you start the simulation, and then view it, as many times as you want. To run it "fast" on the server, simply step it forward as fast as you can. On the clients, you'd just step it forward once per render frame, to show a "real time" playback.

Regarding "random" numbers used in games (and the default random library,) they really aren't random. If you seed a random number generator with a specific value, it will generate the same sequence of numbers in order, every time you re-seed it. If all other simulation bits are the same (the same objects, taking the same damage, going through the same code paths, ...) then the random number generator will generate the same random numbers.

Perhaps a good resource for this is the "1,500 archers on a 28.8 kbps modem" article series from Gamasutra. It talks about how Age of Empires implemented deterministic gameplay to support input-synchronous gameplay for an RTS. It sounds like your simulation engine has very similar requirements, with the added simplification of not allowing any real user input after the simulation starts.

enum Bool { True, False, FileNotFound };
Advertisement

Thanks, your first solution made me think about game replay's so I googled that. I think this is the best way to go, I guess all I need my game to be deterministic and start on all clients in the exact same state. If I ever want user interaction I could send input with it.

Edit: I found another great article to have fixed time steps for a deterministic outcome. Unity has the method 'FixedUpdate()' for this but some engines might not or even combine the draw and logic loop.

This topic is closed to new replies.

Advertisement