Vidiot_X Posted June 19, 2014 Report Posted June 19, 2014 Hi,I have been working on the server and now have a complete client correction system in place. Basically what this is a way for the server to correct a connected clients position (game state) and more. This prevents clients from cheating and allows the server to be completely authoritative meaning it can control a connected client. Because clients now only send move/options data (left, right, thrust, fire and so on) there is no way for a client.For the more technically inclined the Phoenix USC server uses a method outlined in Gabriel Gambetta wonderful tutorial on fast paced multi-player games which you can find here. This method works really well and when coupled with an 'Unreal engine" like buffer for lag compensation yields a smooth client correction (from server) and can handle high latency. In fact the client and server are in almost perfect sync using this method allowing for very few corrections to the client aside from when the client is sending inputs. This means for example when the ship is coasting in your client it requires virtually no corrections from the server even when it hits a wall. This is possible because the client and the sever both run exactly the same code for movement and such.I will be working on getting remote ships appearing in a client to move smoothly. I have a working method and I am applying it now. Once that is done the networking code will pretty much done and I can finaly move on. http://www.phoenixusc.com/board/images/smilies/happy.png I have also started to add a ship selection interface that will allow hundreds (that's right 100's) of ships to be available. Here is a early draft of what the interface will look like. I'll post some more media as soon as I get the next build done.Rock on,- Rich - Quote
Vidiot_X Posted June 29, 2014 Author Report Posted June 29, 2014 ^LOL.. more late nights at coding. @allI have implemented a method that handles positioning of remote ships appearing in a client. It seems to be working well and I think I can get it to handle high ping rates of 150ms-200ms average. That said PUSC will run best at latencies of 100ms or less and support for higher ping rates in general is not recommended but possible. I have added in support for bots into the server and client. It is just the support end for them and I still need to add a bot script framework but that is relatively easy. The bots should be pretty kind to bandwidth as data is only one way (from server to client) for bots and testing 30 bots here locally (server and two clients) yielded only a small increase in bandwidth. I have also added in more option to the HUD to make it easy to access the options you need. The HUD (for now) folds to a smaller footprint (clicking the H/S button) so that the buttons can be hidden. The design is not final but works really well. I have also added a real-time dynamic net/system status window that shows the current, high/low, average ping rate as well as packet loss. Here is an image showing it and the HUD. I will be testing my next build here shortly and it is looking good. - Rich - Quote
Cheese Posted June 30, 2014 Report Posted June 30, 2014 how much trouble was implementing trailing state Quote
Vidiot_X Posted July 1, 2014 Author Report Posted July 1, 2014 how much trouble was implementing trailing stateNot sure what you mean. Can you elaborate? Quote
JoWie Posted July 1, 2014 Report Posted July 1, 2014 Although he has never read it , he means this paper.An Efficient Synchronization Mechanism for Mirrored Game Architectures.pdf Quote
Vidiot_X Posted July 1, 2014 Author Report Posted July 1, 2014 Aww. The 'trailing' state is handled via a stack or state buffer ( circular buffer) that records some game state "snapshot" information up to 1.5 seconds of past states. When a client sends a packet of moves/commands the server uses a time stamp included in the packet to look through the state buffer and reset the current client actors state (server side, state buffer includes position, velocity and more) to the state at that time stamp and replays commands/moves through to the current server state. The remaining commands/moves (if any) get played out in real time and a verification packet is then sent from the server to the client. The client uses a similar state buffer to apply the server verification (which includes position and velocity) and will reset the clients actor state, replay moves, apply some interpolation (if needed) and finally include any state corrections into the state buffer. It actually is not a great deal of trouble to get going and with a one to one exchange of packets the method allows for fairly low bandwidth as the system only sends a server correction every one second outside of the exchange. - Rich - Quote
JoWie Posted July 1, 2014 Report Posted July 1, 2014 So the server keeps a state for each individual actor to verify his actions?Does that state not only contains position & velocity but also things like health, energy, weapon fire delay, ammo, et cetera (which are all rollbacked)? Does it handle inconsistencies that arise because of interaction between players? Suppose the following occurs (where Pt = packet timestamp; At = arrival time) : At=100, Pt=50 : Player A fires a weapon costing 1000 energy (player has 1200 energy at this point)At=120, Pt=40 : Player B fires a weapon that hits Player A and it instantly damages that player for 600 energy. Does the server at this point rollback so that Player A never fired his weapon (because he does not have enough energy)? Quote
Vidiot_X Posted July 2, 2014 Author Report Posted July 2, 2014 Hi, The server uses a state buffer that includes velocity, position, angle, turn speed and time stamp. This buffer is only used in rolling back to a previous state using the time stamp and resetting the above variables to the a past state. But, this buffer is in addition to the actors 'object' general state that includes all of the variables like energy, weapons, ship, fire delay and really all of the variable associated with a map as the server plays/process it's own copy of the map and is really the only state that matters. So if a client actor fires a weapon at remote actor the server is going to make the call on if it was hit or not despite what you may see on a particular client. It does this by using the above method where it receives a client actors packet, rolls back to the position when the packet was sent and then processes past moves/options/commands immediately (up to the the current server state time stamp). While processing these moves/options/commands it factors in collision, resources use (wepaons, bombs, warp, so on) and updates any state variables. At this point the server also limits a players action based on the client actors server state. If a client actor for example is firing a weapon and is out of sync for some reason or is cheating (say unlimited weapons fire) the server will not let it fire more then the rate predetermined by the weapons specifications, the client may send lots of fire commands but the server will ignore them and only fire the weapon as expected. This also applies to any other possible command issued by a client actor. I will be adding some packet checking to make sure packets forwarded to other server connected clients are clean and valid which will also help. Additionally the server also makes the call on a kill, energy state and more by sending updates to the client. In the case of an energy state the server sill let the clients calculate it between server updates, so the energy states for actors on on a client or the client actor itself will all be server controlled. In the case of a kill the client will wait for a kill command from the server before a actor is destroyed. I should also note that the clients also look for cheating and sync errors by also limiting remote actors in a similar way. Since the best performance is going to be to immediately forward packets to clients connected to the server the clients will also check to see if a remote actor is for example firing a weapon at a given predetermined rate of fire in the same way the server does. Possible because the clients and server use the same code to run the game. For out-of-order, missing or malformed packets the server is ignoring them for now, but this will change here soon. The best reason for handling them is for a better simulation mainly when it comes to weapons and hits/kills. Positioning is not as effected but if packet loss gets excessive will be a problem. Generally the server is ahead of the clients and can correct or account for some packet loss information. At=100, Pt=50 : Player A fires a weapon costing 1000 energy (player has 1200 energy at this point)At=120, Pt=40 : Player B fires a weapon that hits Player A and it instantly damages that player for 600 energy. So, this is where I am at now hooking the remote actors and managing them. As it stands now player 'A' would be able to fire the weapon. I will probably deal with this by expanding the state buffer and comparing past actor states, but I am not sure yet. The solutions i have researched involve lagging the client actor by a given time (similar to trailing state) and having the server process client actors from the past. This would work in this scenario but at a cost to latency performance. But, I am working on it now and experimenting with a few different methods. My overriding concern is latency performance so I am trying to solve this without resorting to past state reconciliation. In general an authoritative server is difficult to implement in a twitch style inertia based game like PUSC or SS. Because the clients 'do not' send position or velocity data it can be difficult to accurately reflect actor states especially when server correcting a client actors position (with no snap back). But aside from a few little issues the model I have in place works well and does prevent cheating. One of the last issues to deal with is the above. - Rich - Quote
JoWie Posted July 2, 2014 Report Posted July 2, 2014 If I recall correctly, a lot of valve games (FPS) lag players on purpose by a fixed amount like you mentioned.One thing some games also do is that the server tries to simulate the point of view for each player. Suppose your lag averages at 150ms, the server will then simulate a state with you as the context at 150ms (using identical code as the client). If you then fire a sniper rifle on an enemy, the server will then know if it was a hit on _your_ screen. (instead of relying on a kill yes/no determination generated by the enemy, such as in continuum).I am using a method that is based on that pdf I linked. The result of this method is a "server authoritative" protocol that does not need any server->client syncing packets as long as you can guarantee that no player ever lags more than a certain amount (for example 1500ms). (I do have some syncing packets in case that restriction is violated, I also employ redundancy to combat minor packetloss (the same move is sent many times (which is okay since a move is only 5 bits))).This means I can predict everything, even deaths of other players. These deaths are also reversible if it turns out to be incorrect (because you receive more packets that cause this conclusion).This took a large amount of work though, more than I first anticipated. I am not sure if I would pick this method if I started over haha.Something I also want to do later on is support P2P to reduce latency by sending your packets to nearby players directly. At=100, Pt=50 : Player A fires a weapon costing 1000 energy (player has 1200 energy at this point)At=120, Pt=40 : Player B fires a weapon that hits Player A and it instantly damages that player for 600 energy.So, this is where I am at now hooking the remote actors and managing them. As it stands now player 'A' would be able to fire the weapon. I will probably deal with this by expanding the state buffer and comparing past actor states, but I am not sure yet. The solutions i have researched involve lagging the client actor by a given time (similar to trailing state) and having the server process client actors from the past. This would work in this scenario but at a cost to latency performance. But, I am working on it now and experimenting with a few different methods. My overriding concern is latency performance so I am trying to solve this without resorting to past state reconciliation.In general an authoritative server is difficult to implement in a twitch style inertia based game like PUSC or SS. Because the clients 'do not' send position or velocity data it can be difficult to accurately reflect actor states especially when server correcting a client actors position (with no snap back). But aside from a few little issues the model I have in place works well and does prevent cheating. One of the last issues to deal with is the above. It could also be valid to simply not handle such cases, which effectively mimics what such a case would look like in continuum. Quote
Cheese Posted July 3, 2014 Report Posted July 3, 2014 Something I also want to do later on is support P2P to reduce latency by sending your packets to nearby players directly. badbadbad bad badbad badbadbad badbadbadbadbadbad badbad bad badbad badbad badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad bad badbad badbad bad badbadbad Quote
JoWie Posted July 3, 2014 Report Posted July 3, 2014 the engine used can handle that cheat freefreefree Quote
Vidiot_X Posted July 5, 2014 Author Report Posted July 5, 2014 @JoWie I was reading over that pdf link and this sounds very similar to the way I am approaching this: referred to as states, each execute every command, but after diering synchronization delays. Only the leading state, which has the shortest synchronization delay, is rendered to the screen, while the other trailing states are used to detect and correct inconsistencies. I essentially do the same thing, using a state buffer that records 'key state' variables for every frame ( 16.66ms frame time ) for 1500ms. The leading state (least delay or past time) is rendered to the screen. This state buffer is used to calculate any corrections based on past 'slices' of frame state. It appears to me that we are closer in design then not. Anyway I will read through the rest of it. Interesting read. It could also be valid to simply not handle such cases, which effectively mimics what such a case would look like in continuum.Which has crossed my mind but only briefly. - Rich - Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.