Jump to content

  • Log In with Google      Sign In   
  • Create Account


Sending actor events in an FPS networking model


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
11 replies to this topic

#1 fholm   Members   -  Reputation: 262

Like
0Likes
Like

Posted 10 July 2012 - 08:04 AM

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?

Sponsor:

#2 hplus0603   Moderators   -  Reputation: 5108

Like
1Likes
Like

Posted 10 July 2012 - 12:51 PM

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.

enum Bool { True, False, FileNotFound };

#3 0BZEN   Crossbones+   -  Reputation: 2011

Like
1Likes
Like

Posted 12 July 2012 - 02:10 AM

Another good article

http://gafferongames.com/game-physics/networked-physics/

Everything is better with Metal.


#4 Inferiarum   Members   -  Reputation: 731

Like
0Likes
Like

Posted 13 July 2012 - 03:03 AM

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?

#5 lawnjelly   Members   -  Reputation: 429

Like
0Likes
Like

Posted 13 July 2012 - 03:24 AM

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. Posted Image

#6 Inferiarum   Members   -  Reputation: 731

Like
0Likes
Like

Posted 13 July 2012 - 06:10 AM

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.

#7 lawnjelly   Members   -  Reputation: 429

Like
0Likes
Like

Posted 13 July 2012 - 06:42 AM

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.

#8 lawnjelly   Members   -  Reputation: 429

Like
0Likes
Like

Posted 13 July 2012 - 07:31 AM

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.

#9 fholm   Members   -  Reputation: 262

Like
0Likes
Like

Posted 13 July 2012 - 08:06 AM

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?

#10 lawnjelly   Members   -  Reputation: 429

Like
0Likes
Like

Posted 13 July 2012 - 08:57 AM

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?


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! Posted Image

#11 0BZEN   Crossbones+   -  Reputation: 2011

Like
0Likes
Like

Posted 15 July 2012 - 06:03 PM

Yeah, only the server is interested in the actual inputs of the client, for physics updates, verification and correction.

The remote clients will receive the occasional event message.and state updates, these get extrapolated / interpolated. Running and walking anims are either implicit (computed from the path of interpolation) or explicit (anim velocity replicated).

You can send each and every bullet event to remote clients, but that's rather inefficient, and clients are mostly interested in what 'looks good', bar things like grenades, rockets which would have to be replicated pretty accurately.

You can for example keep a count of the bullets to detect how many were fired since last update, or when to reload, or just flag the gun as firing, and only worry about simulating gun fire and reload anims regardless of what ammo is in the gun. The 'infinite gun firing' when a client drops for example.

Everything is better with Metal.


#12 hplus0603   Moderators   -  Reputation: 5108

Like
0Likes
Like

Posted 15 July 2012 - 06:24 PM

The server doesn't forward the input of clients to other clients.


It depends. It's certainly possible to build an FPS which is input-driven rather than state-snapshot-driven. Doing so will likely allow your server to scale to more players per map instance. I would be highly surprised if there is no "modern" FPS game that uses input update packets, perhaps with occasional "baseline" snapshots. I also think that, the more players per map are supported by the game, the more likely it is to use input forwarding instead of state forwarding.
enum Bool { True, False, FileNotFound };




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS