I have been trying to implement some lag compensation techniques for a real-time game, I've found some good resources online, but I don't think I fully understand the server-side part of the problem.
The game is a simple 2D game, where the player moves an entity around the map. There will be other entities with their own behavior that are controlled by the server, but I made it so that their movement can be easily interpolated. The player input is quite simple: an analog stick and some commands (pick target, loot objective, etc.). The game runs at a fixed 10 TPS (it's on mobile and it's not that action packed, 10 TPS will suffice). The client will send the input state every tick (even if no input is present, like the analog stick is in the default position).
It is worth mentioning that only one player is connected at the same time, so in a way this is not multiplayer, but I need to run this on the server as well to prevent cheating.
I understand client-side prediction and that's quite straightforward to implement. I am struggling with the server-side part. As far as I can see I have 3 options:
- The server waits for the input from the client then computes the new game state and sends it to the client. This is a viable option only because there is only one player.
- The server runs the game loop waiting up to 100ms (10 TPS -> 100ms / tick) for an input. If it gets one, it will be taken into consideration when computing the next state, otherwise it will be discarded. If an input arrives after the tick was done, it will be discarded. If an input arrives during this timespan, but the tick numbers don't match (client send input for tick 5, but server is at tick 7) it will be also discarded.
- The server runs the game loop waiting up to 100ms (10 TPS -> 100ms / tick) for an input. If it gets one, it will be taken into consideration when computing the next state, otherwise it will be discarded. In this case it will not care if the input is not for the current tick, it will apply it anyways.
Option 1 is the easiest to implement and will be more consistent. The biggest issue with this is that I believe it's easy to cheat. Since the server is waiting for input, the player might be able to "pause" the game, analyze the situation then dispatch the action, basically allowing a cheating player to play in slow-motion. The client-side reconciliation in this case seems easy, when the player moves, it will move instantly on the screen and when it received the updated state from the server it will do it's reconciliation.
Option 2 is a tad harder to implemented (not by much though), but it will be unplayable (literally, the player won't be able to move) if their ping is higher than 100ms.
Option 3 has the same complexity as Option 2. It will work with pings higher than 100ms but it will most probably lead to some frustration on the player's side since their inputs will not arrive in time.
Is there a better way to do this? What are your thoughts?