Ok, I know that this is a common topic, but I have no idea how this works. If I were to move bettercharactercontrol on a server, would I still have to use setWalkDirection in order for it to respond to collision? If so, how would I know when to apply changes in order to keep in sync with the client? And when I respond to the client, does the client set its position directly to the positon the server set?
In a nutshell your server does all the work, and your client represents the server state. So you would tell your server that you are pressing forward, and your server would return the position.
Think of the client as nothing more than a visual representation of the server state. That’s all it should be, really. Doing it that way ensures client-side hacks can’t really be done. For example, the client says it wants to travel in the +Z direction. That’s all it will need to know. It will know the velocity based on the player object (because the player object is also server-side) and will know it’s inventory or type (can it fly, is it flying, does it have any speed boosting inventory items active), etc. All of that should be worked server-side - and your client simply represents the output. It’s just a visual state of the server.
What jayfella said but you can use client-side physics for the local interpolation. So basically you’ll update all physics objects with the server state every x milliseconds but let the local physics do the steps in between. Then you just have to account for the latency between client and server. The Monkeyzone example did a relatively straight-forward version of that.
I never knew that MonkeyZone was that advanced. I have to check it again. Thanks for the hint!
The only thing I didn’t get around to do is applying user input information locally, its always relayed via the server. In a proper game you should probably apply it locally as well to reduce lag - but that also requires dealing with the connection latency and “debouncing” it.
I think a common way is to
- send the input instantly to the server
- let it process the update and broadcast the new state.
- meanwhile the update is applied with a little unnoticeable delay (to reduce a bit of the latency) to the local game of the client.
- When the client receives the new state and it differs too much from its own state it will be corrected the noticable way (with a warp).
If there are just minor differences they will be corrected unnoticable the next time in step 3.
There is another thread here about integrattng bullet with Zay-ES… that combined with something like SimEthereal and the network support already built into Zay-ES gives a pretty powerful entity-component-system based client/server architecture.
An example that integrates with Zay-ES:
The example uses the Valve approach… all physics is done on the server. The client is just sending input state, basically.
Thanks for all the responses! So lets say I hit w, the client predicts where the player will be and sets the charactercontrol.setWalkDir to [1,0,0]. The client then sends a message to the server that the w key is pressed and the server sets that players charactercontrol.setWalkDir to [1,0,0] and then sends the current position to the client. The client recieves the new position and sets it.
But with the internet, do I have to worry about how long the w key is pressed on the client and try to replicate the amount of time it was pressed on the server?
Also, I appreciate MonkeyZone but I find it hard for me to get to the classes with the information I need. Can someone point me in the direction that I need to go?
No. You should be polling the data at a presumably set rate, so no time is required.
Your life is simpler if you can get away with avoiding prediction. If you use a real time sync library like SimEthereal then the latency is pretty low already. Obviously not great for some kinds of games but given the way that the sync works and the fact that the user is viewing (very) slightly back in history… the latency of press-to-move will feel like less than you’d think with respect to ping times.
But play with the sim-eth examples and see how that feels local and remote. That ship has an acceleration and so the whole latency is generally eaten up anyway. The look direction is always user controlled so everything feels responsive anyway. Even for FPS shooter style games, there is always a little bit of acceleration from 0 to movement.
Edit: having look direction local is critical to avoiding motion sickness… if the mouse moves the view should move. (presuming mouse look)
A lot of competitive people remove any sort of prediction when playing competitively and let their brain get use to it. It really works very well and we are exceptionally adaptable this way (most older cars and even modern trucks have quite high latency with steering).
And for games that don’t work that, your kinda screwed anyway. aka a twitch based fighting game is very hard to pull off without just making sure players are local. Since even at the speed of light 100-200 pings are as good as it gets for around the world trip times.
BUT as pspeed said. You got to have head tracking etc match well since a lot of people have problems with this. But then again this isn’t really a “game state” thing per say.
Prediction for single player server side is in fact pretty easy. For ONE player. there is only so much you can do when you have more than one player on a different time base. That is there is no consistent “happens before” player. So things have to at some point “rubber band” or things don’t happen strictly as they appear to happen.