I am developing a tile-based online multiplayer game, but I am stuck. Players can move across the grid in the four cardinal directions, as can enemies, but two players/enemies cannot occupy the same tile at the same time. Positions of all players/enemies are synced for all clients.
My current implementation of movement: Clients send a 'request to move' to the server whenever they are stationary on a tile.
I have implemented client prediction. When a button is pressed to move, the client shows their character immediately moving in that direction, as opposed to waiting for confirmation from the server, preventing lag between player input and visible results.
The issue arises when the player attempts to move to a position that will soon be occupied. For example, the player presses up when an enemy is very close to entering the tile above the player (though they can't currently know that the enemy will choose that tile next). Locally this is confirmed and the upwards animation begins, but by the time the request to move up arrives at the server, the tile is no longer free, and the player is not moved up on the server.
This creates a situation where the player's local position is out of sync with that of the server. My current solution to this is snapping the local player back to the server's position when this happens, but this looks awful. It seems to be happening a lot, making the game nearly unplayable.
Is there a way around this? Any help would be very much appreciated, thanks.
Some other notes: I send updates from the server 10 times a second, which consist of every object's position (and other stuff). When a movement event is processed, the object's position is updated immediately, even though an animation follows.