Network input handling

Started by
123 comments, last by hplus0603 11 years, 2 months ago
The one thing I was wondering about though is if I should limit the rate input is sent to the server.[/quote]

You should absolutely run simulation at a fixed time step size, which should be the same on all clients and servers. (This means simulation stepping should be de-coupled from rendering.) Inputs should generally be time-stamped for the particular simulation step number (starting with 0 at beginning of game) they are intended for.

The corollary is then that it doesn't make sense to have more than one input state per simulation step. Additionally, you can trade off latency for packet overhead by packing N steps of inputs into a single packet. You can also compensate for occasional lost packets by pre-emptively including "older" inputs, too, in successive packets. For most kinds of inputs, these will either be very small, or at least RLE encode or compress very well.
enum Bool { True, False, FileNotFound };
Advertisement
So I should handle the input immediately on the local client and then queue up the commands and send them out to the server every 33ms? And then the server will execute them ... how? As soon as it gets them or what?

So I should handle the input immediately on the local client and then queue up the commands and send them out to the server every 33ms? And then the server will execute them ... how? As soon as it gets them or what?


At that point, your specific approach to consistency and lag hiding comes into play. There are a few possible options here, and which one you choose depends on what your trade-off between control lag and consistency and bandwidth is.
enum Bool { True, False, FileNotFound };
I'm kind of stuck with how to handle the input server side. I'm using BEPU for my physics engine in a minecraft type game. This article says the the way to handle client side prediction and server reconciliation is that you tag each input packet with a number when you send it out and then store it locally. The server processes it and sends back the results with that number included. When the client receives it, it sets the world state to what the server says, and then re-applies any further inputs that occurred after that point.

There's 2 problems with that though. First is that I can't just tell BEPU "hey, can you run the simulation for THIS ONE PLAYER". Second is that, even if I could simulate for a single entity, what about all the physics objects you could collide with that would change the resulting position? The valve network article also seems to be tailored for a game with 0 physics: "Then the server moves all other players - only players - back to where they were at the command execution time. The user command is executed and the hit is detected correctly. After the user command has been processed, the players revert to their original positions." Suppose you have a game with blocks falling that could intercept the shot. If you don't rewind them, the results are wrong.

I know getting all the clients synced up perfectly is pretty much impossible and I'm not looking for a perfect solution, and probably not even the best solution, but the valve article seems a bit dated and designed for a static game and the other article suggests a method that seems impossible to implement with my physics engine. I get the feeling minecraft itself doesn't do any of this stuff (I don't actually know if that's the case or not) and still manages to do a half decent job, so if you could give me some advice on what I *can* implement in this situation, I'd appreciate it.
Easiest is to only send the inputs to the server, and only run physics when you get back "here's all inputs for all clients at step X" to the client. This can be fully consistent, but will introduce some control lag. You can work to reduce this lag through UI and display tricks, as well as making sure you turn on TCP_NODELAY (or use UDP) and run at high simulation step rates, but not fully remove it.
enum Bool { True, False, FileNotFound };
I suggest taking hplus's route and trying to do latency masking for each client. Speaking from experience, distributed consistent physics is not easy.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

the main issue is lag. Our goal is to have 100+ player servers. I wouldnt want to go much higher since that would cause some serious requirements but a 100 player server would be ideal ( assuming you have the hardware to handle it )

From our previous network attempts we noticed that there was some serious delay on actions that were shown from client to client. Player A could break a block and player b wouldnt see it for 10 min later. While player b would modify a block and player a would see it miliseconds after it was done. I know, in part, this is due to our code but it also has much to do with our choices for how we are doing things. Since that time we have streamlined most of those issues out but we are really stuck when it comes to the physics and other information. Thanks for the help with this guys.
Since that time we have streamlined most of those issues out but we are really stuck when it comes to the physics and other information. Thanks for the help with this guys. [/quote]

If the difference in "seen time" is higher than the difference in round-trip latency, you're probably doing something wrong.
If the difference in round-trip latency is above, say, 300 ms, you're also probably doing something wrong.
Well-implemented networked games take networking into account in physics, input, rendering, and game design, which is why retro-fitting networking into an existing game can be hard.

All Points Bulletin does > 100 players per server using Unreal Engine as a Free to Play game.
Planetside did 500 players per server 8 years ago. (Planetside 2 is out not, but I haven't had a chance to check it out yet)
100 players per server is not at all an impossible goal to hit, assuming you build on top of solid principles and code. Sometimes, that's a bit of a stretch assumption, though :-)

enum Bool { True, False, FileNotFound };

Since that time we have streamlined most of those issues out but we are really stuck when it comes to the physics and other information. Thanks for the help with this guys.


If the difference in "seen time" is higher than the difference in round-trip latency, you're probably doing something wrong.
If the difference in round-trip latency is above, say, 300 ms, you're also probably doing something wrong.
Well-implemented networked games take networking into account in physics, input, rendering, and game design, which is why retro-fitting networking into an existing game can be hard.

All Points Bulletin does > 100 players per server using Unreal Engine as a Free to Play game.
Planetside did 500 players per server 8 years ago. (Planetside 2 is out not, but I haven't had a chance to check it out yet)
100 players per server is not at all an impossible goal to hit, assuming you build on top of solid principles and code. Sometimes, that's a bit of a stretch assumption, though :-)
[/quote]

Planetside 2 does reasonably well with 500+ players in a single region. I will admit there is some serious issues with network stuff but they are attempting to simulate some crazy stuff that we wouldnt even begin to attempt to manage.

I agree that with sound principles the 100 player mark would not be hard to reach... hence why we came here! We appreciate your help and your thoughts as they have helped us to get as far as we have thus far. I will have telanor and goss post up anymore information or status reports so we can see what else can be improved. Again thank you.
The world updates aren't that bad anymore. When we originally had it working, the server was sending out updates as fast as possible. But since I changed it to run at a tickrate of 66, clients are now seeing the block updates before you can even hear the other person say they placed it in vent.

We're having an issue with handling the player input on the server side though. The server typically ends up applying the player's input for a shorter duration than the client does. I can't really see what would be causing it. I'll describe how things are set up right now and maybe someone else can point out the issue. The client examines the input state every frame and checks to see if its different from the last state sent to the server, if it is, it sends the changes. Also, every frame it applies the input and runs the physics update, which is set to run at a fixed rate of 60fps. On the server side, the server runs at a tickrate of 66, which is done by sleeping for however long it calculates it needs to until the next tick. On each tick, it reads all the input that has accumulated, merges it into a single state for each player, applies it, and then runs the physics (which again has its internal update rate set to 60fps).

This topic is closed to new replies.

Advertisement