I have implemented the networking model described in this, by now very well known, document: https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking Everything is working above my expectations. However, I seem to have hit a little bit of a snag.
The client collect input at 15ms intervals, which is used to locally predict the clients actions but is also sent to the server in groups of 2+ every ~30ms. From the server I send out snapshots of the world state to the clients every 50ms. Since the input interval is lower then the snapshot interval (and I can't really change them to match each-other without effecting game-play), I will receiver several input packets (2+ or more, usually 3) to the server for every snapshot it sends out,
It's here my problem lies, say that in the first of the three input packets I receive I see that the "Fire" is key is down, but in the second or third it's not. This needs to be recorded in some event-queue and sent to the remote clients. How is this usually solved? The fact that the snapshot rate is lower then the game rate, and "over-writing"/"conflicting" things can happen between the snapshots?
Sending actor events in an FPS networking model
You'll need to forward a copy of the inputs for each step; at least for inputs that "matter," which it sounds like firing does in this case.
Would it be too expensive to roll back the simulation on the server until before the inputs happend and then simulate again with the new inputs?
Counterstrike afaik introduced the idea of rollback to interpret firing to prevent cheating.
i.e. You can do a hit check on the client and see whether the shot hit another player, but the server shouldn't blindly trust this, because you might be cheating. So the server winds back player positions and animations (bone positions) to do a hit check to determine as the authority whether the hit actually happened. Once there's a hit, the server can just fire off a packet to the other clients to tell them that the player has been hit, play the appropriate animations, blood particle effects etc. The server doesn't actually have to reverse the simulation other than to determine whether there's a hit or not.
It doesn't actually matter that the client doing the shooting has seen a 'client side predicted' hit earlier than the other players will see it, just as long as the game is consistent. Smoke and mirrors.
i.e. You can do a hit check on the client and see whether the shot hit another player, but the server shouldn't blindly trust this, because you might be cheating. So the server winds back player positions and animations (bone positions) to do a hit check to determine as the authority whether the hit actually happened. Once there's a hit, the server can just fire off a packet to the other clients to tell them that the player has been hit, play the appropriate animations, blood particle effects etc. The server doesn't actually have to reverse the simulation other than to determine whether there's a hit or not.
It doesn't actually matter that the client doing the shooting has seen a 'client side predicted' hit earlier than the other players will see it, just as long as the game is consistent. Smoke and mirrors.
Yes, this is also described in the article. But for movement input you would have to rewind either at the client or the server for the best results, but i guess in most scenarios this is prohibitively complex.
And i guess this was not even the question in this tread
If you have multiple inputs that happen on the same time considering the server simulation, you should probably process all inputs in the input queue and then do a simulation step. So you do not miss inputs which result in an immediate action, like shooting.
And i guess this was not even the question in this tread
If you have multiple inputs that happen on the same time considering the server simulation, you should probably process all inputs in the input queue and then do a simulation step. So you do not miss inputs which result in an immediate action, like shooting.
Yes, this is also described in the article. But for movement input you would have to rewind either at the client or the server for the best results, but i guess in most scenarios this is prohibitively complex.
If you have multiple inputs that happen on the same time considering the server simulation, you should probably process all inputs in the input queue and then do a simulation step. So you do not miss inputs which result in an immediate action, like shooting.
It's a few months since I worked on the network code of my current FPS but from memory:
For movement input on the server, I think I just simulate the physics for each actor as far as I've got the client input up to. So there's no rewinding or extrapolation. So each actor *could* be on a different tick, depending on how up to date it is with input from its client. Whether this is the best way, I don't know, but it works for me, and looks alright with multiple clients, under varying conditions of lag / packet loss / packet reordering. Remember you can have quite a bit of smoothing client side to provide the rendered positions of the other players. There may also be some other jiggery pokery I did elsewhere to compensate for this.
The main rewinding stuff I do is in the client side prediction code, if the server reported position is different from that of the client prediction, the client rolls back and reruns its simulation from the server reported 'authority' position.
So essentially, if you've got a rubbish connection, the server can only simulate you as far as its got input for, and you'll suffer competitively against the other players. Which is what you'd expect really.
And sorry, got a bit sidetracked there, I'm a bit of a loon.
To answer the original question .. I don't send the fire as a normal input packet. The client normal input packet is stuff that will affect the physics - pressing left, right, forward backward etc. I just send these as off and on for each physics tick (with a history of past input up to the last acknowledged receipt from the server). You could go for sub tick accuracy if you wanted, and e.g. estimate the percentage of the tick the key was pressed .. I currently don't bother.
Firing a gun for me has no reason to be tied to the tick rate, and for accuracy of server checking you actually don't want it to be. So I just send a packet when you fire.
To answer the original question .. I don't send the fire as a normal input packet. The client normal input packet is stuff that will affect the physics - pressing left, right, forward backward etc. I just send these as off and on for each physics tick (with a history of past input up to the last acknowledged receipt from the server). You could go for sub tick accuracy if you wanted, and e.g. estimate the percentage of the tick the key was pressed .. I currently don't bother.
Firing a gun for me has no reason to be tied to the tick rate, and for accuracy of server checking you actually don't want it to be. So I just send a packet when you fire.
I think I explained myself poorly, hplus0603 gave me the response that I was looking for. But I think the rest of you misunderstood me. Basically, I'm not talking about sending input from the controlling client to the server, but rather how to properly propagate this to the remote clients without overwriting conflicting input states, and it was obviously as simple as just forwarding the input state as soon as it gets to the server (and allowing the server to modify it before hand in case some actions are not valid, like shooting when you have no bullets, etc.).
Lawnjelly: Do you run your input on a fixed timestep? How do you deal with rendering a smooth display of movement? I feel that when I run input on a fixed time-step the rendered movement ends up getting a little choppy when the frame render speed don't line up with the fixed time-step. Do you do some sort of local interpolation or just live with the slight choppy-ness?
Lawnjelly: Do you run your input on a fixed timestep? How do you deal with rendering a smooth display of movement? I feel that when I run input on a fixed time-step the rendered movement ends up getting a little choppy when the frame render speed don't line up with the fixed time-step. Do you do some sort of local interpolation or just live with the slight choppy-ness?
I think I explained myself poorly, hplus0603 gave me the response that I was looking for. But I think the rest of you misunderstood me. Basically, I'm not talking about sending input from the controlling client to the server, but rather how to properly propagate this to the remote clients without overwriting conflicting input states, and it was obviously as simple as just forwarding the input state as soon as it gets to the server (and allowing the server to modify it before hand in case some actions are not valid, like shooting when you have no bullets, etc.).
Now this is confusing - this isn't how modern FPSes work at all. The server doesn't forward the input of clients to other clients. The server uses the input to drive the physics, and it sends on the physics positions of the actors at each tick. It may also send packets to drive animations, play sounds, put the actors into certain states etc. The client doesn't know or care what the input of each other client is, it's only interested in what the actor is doing, and that is determined by the server. Client side prediction only needs to be run on the PLAYER not all the other players, it's there to hide lag.
Lawnjelly: Do you run your input on a fixed timestep? How do you deal with rendering a smooth display of movement? I feel that when I run input on a fixed time-step the rendered movement ends up getting a little choppy when the frame render speed don't line up with the fixed time-step. Do you do some sort of local interpolation or just live with the slight choppy-ness?
[/quote]
Stuff like mouse clicks can be done when the user clicks. Keyboard input can either be monitored / done at the time the key is pressed / depressed, or with an asynchronous check. View angles are sampled at each client tick and sent with the input packet along with left right forward backward. Smooth display of movement - interpolation.
There is an article 'fixing your timestep', I think this explains about interpolation. You have interpolation for your client stuff, and interpolation for your other player positions, possibly a different codepath (I have a different codepath, but the idea is similar).
If you write your stuff properly your game will work whether your tick rate is 100 ticks per second or 5, or 1 tick a second, and still look smooth (it's just the input / physics are more dodgy the lower the tick rate, I'm using 10-20).
Sorry would write more but have to go out!
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement