• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Telanor

Network input handling

124 posts in this topic

I suppose that could work if we set a max supported number of actions. I'm still not sure whats causing the issue with the server simulating the input state for a shorter period of time than the client though.
0

Share this post


Link to post
Share on other sites
You could also make the bitmask more flexible to allow for an arbitrary number of actions, you have to know if it is worth the effort.

If you time stamp the input states with the simulation tick they should be used for, there is a one to one mapping between input state and simulation tick, and, as long as the input packets arrive at the server in time, the same input should be used for the same simulation tick. So if this is what you are doing then I am not sure where the issue is.
1

Share this post


Link to post
Share on other sites
The states aren't being tagged with the simulation tick. I'm not sure I understand how that's supposed to work either. If I assume both the server and client are perfectly in sync and the client sends out a "move forward" command for tick 150, by the time the server gets it, it will already be past that point. If the client is meant to be behind the server, as some articles have suggested, then it still doesn't make sense, because the server will have already simulated the tick before the client has even issued the command. Edited by Telanor
0

Share this post


Link to post
Share on other sites
If you want to do client side prediction, the client actually runs ahead of the server (for something slightly more than half the round trip time) because like you mentioned you want the input packets to reach the server in time.

If you get a game state update from the server, you simulate up to the current client time with local inputs and if you are the only player both client and server come to the same result for the game state at the same tick (assuming client does a full simulation).

Of course if there is a lot of interaction with other players (like in an multiplayer FPS) you get a problem because you have no information about the inputs of other players. That is why in this type of game the predicted state is only used to determine the camera position, and all other players are rendered based on information in the past.

E.g. if we have client time CT, round trip time RTT then the camera is placed using the predicted state at time CT but all other players are placed using the state at time
CT - RTT - IP, where IP is the interpolation time (https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking).

You could also try to predict the input of the other players and draw everything at time CT (http://www.gamasutra.com/view/news/177508/The_lagfighting_techniques_behind_GGPOs_netcode.php#.UMB7HdPjlh4).
This is possible if actions have something like a charge-up.
0

Share this post


Link to post
Share on other sites
How do you place the client ahead of the server? Do you just set the clients time = server time + round trip time when the client joins? What happens if their round trip time fluctuates? Or if they happen to connect in the middle of a lag spike, giving them a 400ms ping which later settles down to 50ms?

Also, that valve article doesn't seem to be feasible in my situation. They're relying on being able to rewind the state of all the players to do calcuations: "This doesn't mean you have to lead your aiming when shooting at other players since the server-side lag compensation knows about client entity interpolation and corrects this error." What do you do when it proves to be too expensive to rewind and resimulate the entire state, and when you have to deal with more then just players in the simulation?

Edit: I'd like to add that I while I haven't tested to see if we can actually afford to rewind and resimulate the entire state, the author of the physics engine advises against it in [url="http://www.bepu-games.com/forum/viewtopic.php?f=4&t=1633"]this thread[/url] Edited by Telanor
0

Share this post


Link to post
Share on other sites
Considering the timing problem here is how I do it:

Every time you get an update from the server you can calculate the server time ST corresponding to the update. The target client time targCT would be
targCT = ST + RTT + c
where c is a constant that accounts for jitter in the RTT (such that input packets arrive in time with high probability) and RTT is the current estimate for the round trip time.
The actual client time CT is updated with the internal clock between each server packet and then adjusted according to something like
CT = 0.99*CT + 0.01*targCT

Note that these calculations are done in (more or less) continuos time.

Considering the client side prediction, I guess if you have an expensive physical simulation, it might be infeasible to calculate the prediction steps. In this case, as mentioned by hplus, you could just render everything at a render time
RT = CT - RTT - IP
and try to mask the control delay somehow. Edited by Inferiarum
1

Share this post


Link to post
Share on other sites
The main issue is our interaction with the world. The player has the ability to modify the worlds contents via blocks, while it must maintain the player(s) locations and interactions as well. To create a responsive combat system ( which we hope to do ) and manage all of that seems to be a daunting task. Maybe if you knew what we were doing you would better know how to help. Btw, thank you for all of this help... it is simply amazing to have this much guidance and knowledge to assist.

[b]Game goal:[/b]
Our main drive is to have players fighting it out over land. This land is the same land that is near 100% dynamic and can be modified. So instead of a player vs a player you have to calculate and manage a player vs a player with block entity interaction as well. Depending on how we render things this could be several thousands functions firing at one time if a player used an explosive that blew up x blocks and all players in the area of the blast. Not saying that whatever was already discussed wont manage that just giving you a bit of scope. We want war and land control to be the central focus.
0

Share this post


Link to post
Share on other sites
Here's how I'd approach this:

[list][*]All clients report at a fixed rate, say 20-30Hz
[*]Client and server contain the exact same prediction/extrapolation logic
[*]As clients report to the server, the server corrects its local simulation (moving forwards only!) to account for the inputs
[*]There is no requirement for timing lockstep; the server waits for no one
[*]Once the server has received some inputs for a tick, it relays the results of its simulation to the appropriate clients
[*]This relay happens at the end of the server tick regardless of who has reported in
[*]The server tracks the delay between when it expected inputs to be reported and when it actually sees them
[*]This is used to inform extrapolation on both the server and other clients
[*]Since everyone does the same extrapolation logic, all clients will appear to be in sync but actually lag behind the server due to relay time[/list]

When major state changes are relayed from the server to clients, you compute the last known transmission delay (based on the tracked latency) and tell [i]clients[/i] to fast-forward their simulation to match. The result is that you might "miss" the first few rendered frames of the world state changing, but the result will be accurate and mostly correctly timed.

The solution to this is to [i]delay[/i] local actions by the transmission delay factor, and hide the delay using animations. For example, suppose you have a rocket launcher that can radically alter terrain/buildings/etc. When player A fires a rocket, he sees an [i]instant[/i] animation/sound effect/etc. of the launcher charging up to fire. At the same instant, you tell the server to fire the rocket. When the server responds that it has done so, you actually do the rocket/explosion calculations on the client.

This keeps everyone in sync, keeps the game [i]feeling[/i] fast, and accurately hides the latency issues involved in distributed simulation.
0

Share this post


Link to post
Share on other sites
[quote name='ApochPiQ' timestamp='1354813321' post='5007809']
Here's how I'd approach this:
[list]
[*]All clients report at a fixed rate, say 20-30Hz
[*]Client and server contain the exact same prediction/extrapolation logic
[*]As clients report to the server, the server corrects its local simulation (moving forwards only!) to account for the inputs
[*]There is no requirement for timing lockstep; the server waits for no one
[*]Once the server has received some inputs for a tick, it relays the results of its simulation to the appropriate clients
[*]This relay happens at the end of the server tick regardless of who has reported in
[*]The server tracks the delay between when it expected inputs to be reported and when it actually sees them
[*]This is used to inform extrapolation on both the server and other clients
[*]Since everyone does the same extrapolation logic, all clients will appear to be in sync but actually lag behind the server due to relay time
[/list]
When major state changes are relayed from the server to clients, you compute the last known transmission delay (based on the tracked latency) and tell [i]clients[/i] to fast-forward their simulation to match. The result is that you might "miss" the first few rendered frames of the world state changing, but the result will be accurate and mostly correctly timed.

The solution to this is to [i]delay[/i] local actions by the transmission delay factor, and hide the delay using animations. For example, suppose you have a rocket launcher that can radically alter terrain/buildings/etc. When player A fires a rocket, he sees an [i]instant[/i] animation/sound effect/etc. of the launcher charging up to fire. At the same instant, you tell the server to fire the rocket. When the server responds that it has done so, you actually do the rocket/explosion calculations on the client.

This keeps everyone in sync, keeps the game [i]feeling[/i] fast, and accurately hides the latency issues involved in distributed simulation.
[/quote]

Not bad, I suppose the only fear now is what people will come up with for hacks. I suppose that is a problem to address when the system is in place and being tested! :P
0

Share this post


Link to post
Share on other sites
Not that i am going to do this, but say I wanted to hire somebody to just look over our stuff, do you have any estimates that i should expect to pay to have somebody look at it? like a consultant? I mean we may just figure it all out from just talking like this but I like to have backup plans just in case.
0

Share this post


Link to post
Share on other sites
[quote]As clients report to the server, the server corrects its local simulation (moving forwards only!) to account for the inputs[/quote]

Corrects it how? Can you explain in more detail what happens here?

[quote]This is used to inform extrapolation on both the server and other clients[/quote]

Can you expand on this point too? I don't understand what you mean by "inform extrapolation".

[quote]The solution to this is to delay local actions by the transmission delay factor, and hide the delay using animations.[/quote]

We can do that for some things, but some might need to be instant actions. What do you do about that then? Even world of warcraft has some instant-cast spells, so how do they handle that?
0

Share this post


Link to post
Share on other sites
[quote name='Inferiarum' timestamp='1354800585' post='5007748']
Considering the timing problem here is how I do it:

Every time you get an update from the server you can calculate the server time ST corresponding to the update. The target client time targCT would be
targCT = ST + RTT + c
where c is a constant that accounts for jitter in the RTT (such that input packets arrive in time with high probability) and RTT is the current estimate for the round trip time.
The actual client time CT is updated with the internal clock between each server packet and then adjusted according to something like
CT = 0.99*CT + 0.01*targCT

Note that these calculations are done in (more or less) continuos time.

Considering the client side prediction, I guess if you have an expensive physical simulation, it might be infeasible to calculate the prediction steps. In this case, as mentioned by hplus, you could just render everything at a render time
RT = CT - RTT - IP
and try to mask the control delay somehow.
[/quote]

I keep trying to figure out how this would play out and I can't see how it could work:

Client A has RTT of 200ms
Client B has RTT of 200ms
Interpolation time of 50ms

Server Tick: 200, Client render: 150, Client Tick 400: Client B moves forward
Server Tick: 300, Client render: 250, Client Tick 500: Client B moves forward again. Server receives move command for tick 400
Server Tick: 400, Client render: 350, Client Tick 600: Server applies move and sends out world state. Server receives second move command for tick 500
Server Tick: 450, Client render: 400, Client Tick 650: At this point client A should see client B move, but the world state still has another 50ms before it reaches client A
Server Tick: 500, Client render: 450, Client Tick 700: Client A receives world state for tick 400. Now what?


Valve defaults to an interpolation time of 100ms. In this situation if the interp time was set to that, the client would have just barely received it in time. If the packet took a little longer than 100ms, it would have still been too late.
0

Share this post


Link to post
Share on other sites
[quote name='Telanor' timestamp='1354861614' post='5008008']
[quote name='Inferiarum' timestamp='1354800585' post='5007748']
Considering the timing problem here is how I do it:

Every time you get an update from the server you can calculate the server time ST corresponding to the update. The target client time targCT would be
targCT = ST + RTT + c
where c is a constant that accounts for jitter in the RTT (such that input packets arrive in time with high probability) and RTT is the current estimate for the round trip time.
The actual client time CT is updated with the internal clock between each server packet and then adjusted according to something like
CT = 0.99*CT + 0.01*targCT

Note that these calculations are done in (more or less) continuos time.

Considering the client side prediction, I guess if you have an expensive physical simulation, it might be infeasible to calculate the prediction steps. In this case, as mentioned by hplus, you could just render everything at a render time
RT = CT - RTT - IP
and try to mask the control delay somehow.
[/quote]

I keep trying to figure out how this would play out and I can't see how it could work:

Client A has RTT of 200ms
Client B has RTT of 200ms
Interpolation time of 50ms

Server Tick: 200, Client render: 150, Client Tick 400: Client B moves forward
Server Tick: 300, Client render: 250, Client Tick 500: Client B moves forward again. Server receives move command for tick 400
Server Tick: 400, Client render: 350, Client Tick 600: Server applies move and sends out world state. Server receives second move command for tick 500
Server Tick: 450, Client render: 400, Client Tick 650: At this point client A should see client B move, but the world state still has another 50ms before it reaches client A
Server Tick: 500, Client render: 450, Client Tick 700: Client A receives world state for tick 400. Now what?


Valve defaults to an interpolation time of 100ms. In this situation if the interp time was set to that, the client would have just barely received it in time. If the packet took a little longer than 100ms, it would have still been too late.
[/quote]

what i meant was that the difference between the client time and the time corresponding to the latest update from the server is the RTT, the difference between client time and the simultaneous server time is RTT/2. With this timing, assuming constant RTT, the client input packets arrive at exactly the tick, when they are needed.

At the server you do not necessarily have to take the time stamp of the input packet into account, you can also just use the latest packet of each user for the update (edit: you still use the time stamp to detect out of order packets). The RTT tells you how far you have to extrapolate at the client (If you want to use prediction). Edited by Inferiarum
1

Share this post


Link to post
Share on other sites
[quote name='Telanor' timestamp='1354859291' post='5008004']
[quote]As clients report to the server, the server corrects its local simulation (moving forwards only!) to account for the inputs[/quote]

Corrects it how? Can you explain in more detail what happens here?

[quote]This is used to inform extrapolation on both the server and other clients[/quote]

Can you expand on this point too? I don't understand what you mean by "inform extrapolation".

[quote]The solution to this is to delay local actions by the transmission delay factor, and hide the delay using animations.[/quote]

We can do that for some things, but some might need to be instant actions. What do you do about that then? Even world of warcraft has some instant-cast spells, so how do they handle that?
[/quote]


It's not magic. The server simply changes its state according to received inputs. There's no rewinding, no bizarre math, nothing like that; when you get an input, you change your state to match the input, as if you'd just gotten the keystrokes/etc. from the local game loop.

Extrapolation is correspondingly simple. If you are told "I'm moving North at 2 m/s" then you assume that that remains true until you are told otherwise.

"Instant actions" are a mythological beast in networked games. They do not exist. You can have actions which trigger as fast as you can relay the data around, but nothing is instant. Your design should accommodate this fact.
1

Share this post


Link to post
Share on other sites
[quote name='ApochPiQ' timestamp='1354910241' post='5008208']
"Instant actions" are a mythological beast in networked games. They do not exist. You can have actions which trigger as fast as you can relay the data around, but nothing is instant. Your design should accommodate this fact.
[/quote]

How do you explain actions that have a 0 cast time and 0 delay? Obviously those can only go as fast as the network can transfer them but they do exist. So the method of hiding the delay with animations falters when that comes into play. For example, say we have a boss fight where one of the mechanics is to cast an interrupt on the boss. To do this you use an instant cast spell that blocks his ability, if the boss's ability has a long timer than you should be good despite network delays but say you have less than 1 or 2 seconds or even half a second to get it all done... what then? Priority timing? track when the boss started his skill when the player started his skill and time it out from there?
0

Share this post


Link to post
Share on other sites
It's either using various techniques to mask latency, or doing retroactive cancels (e.g. you cast an "instant" interrupt on a spell with a 0.5-second windup and a 0.5-second effect time, and if the interrupt registers anywhere during that 1 second window, the entire thing is nullified even if it "hit" at, say, 0.75 seconds).

Keep in mind that updating the UI to show damage numbers/etc. is also an opportunity to mask latency.
1

Share this post


Link to post
Share on other sites
[quote]How do you explain actions that have a 0 cast time and 0 delay?[/quote]

You say "bad, designer, no cookie!" and smack them over the fingers with a ruler.
After ten or twelve times, they start learning!
:-)
1

Share this post


Link to post
Share on other sites
[quote name='hplus0603' timestamp='1354931918' post='5008316']
[quote]How do you explain actions that have a 0 cast time and 0 delay?[/quote]

You say "bad, designer, no cookie!" and smack them over the fingers with a ruler.
After ten or twelve times, they start learning!
:-)
[/quote]

*nods* well.. okay sounds like a plan. Thanks again we should have something this weekend worth showing for all of this information.
0

Share this post


Link to post
Share on other sites
[quote name='Inferiarum' timestamp='1354904633' post='5008185']

what i meant was that the difference between the client time and the time corresponding to the latest update from the server is the RTT, the difference between client time and the simultaneous server time is RTT/2. With this timing, assuming constant RTT, the client input packets arrive at exactly the tick, when they are needed.

At the server you do not necessarily have to take the time stamp of the input packet into account, you can also just use the latest packet of each user for the update (edit: you still use the time stamp to detect out of order packets). The RTT tells you how far you have to extrapolate at the client (If you want to use prediction).
[/quote]

Sorry if I'm being dense, but I'm still not getting it. If the server time is 300 and the client time is 500 and it takes 100ms for the update to get to the client, then when the update from tick 300 arrives, the client's time will be 600. You're saying that the RTT = CT - time stamp on last update. So RTT = 600 - 300 = 300. And you said that CT - current server time = RTT / 2. When the client is at 600, the server is at 400, so RTT/2 = 600-400 = 200. But RTT = 300, RTT/2 should be 150...
1

Share this post


Link to post
Share on other sites
Let's assume that the client and server time are sycnhronised, thus at the same time in the real world they equate to each other.

If the inputs are sampled at t=100, and the server receives them at t=200 then assuming they were sent at sample time, upstream_latency = recv_time - sample_time.
We can then predict that these inputs will be received by the server at sample_time + upstream_latency
On the client, we will rarely be told this by the server, so instead we can use the RTT time (time after sending an ACK that we receive a reply) to get the total trip time and halve it for a rough approximation of upstream latency. We can use the same method to determine when the inputs will be received.

What has been said is that if the client runs its local simulation at server_time + (rtt / 2) then the inputs will be received in time for intended processing on the server.
1

Share this post


Link to post
Share on other sites
You have to estimate the RTT separately (e.g. include the latest time stamp of the input packets from the client in the server packet). If the server time is 300 and it takes 100 ms for the update to get to the client, then the client has the update with time stamp 300 when it is already 100 ms old, now he adds the RTT to the packet time stamp and is now 100 ms ahead (if the estimate is correct). If the actual client time differs from this target time you adjust it slightly.

Ok, so here is how I do it (slightly different from what I described above since I do not use the RTT explicitly)

On the client we have the internal clock CLK and an offset OS, such that ideally the client time CT = CLK + OS = ST + RTT/2

Client sends input packet with current time stamp CT1
server receives input, updates simulation, sends out new game state, includes the current server time ST, and the stamp of the latest input packet CT1
Now ideally CT1 and ST should be the same
When we receive the game state update on the client (which includes CT1 and ST) we update
OS = OS + alpha*(CT1 - ST )
with some small alpha > 0
and the new client time would be
CT2 = CLK + OS

You can still keep an estimate of the RTT if you need it somewhere
RTT = (1-alpha)*RTT + alpha*(CT2-CT1) Edited by Inferiarum
2

Share this post


Link to post
Share on other sites
Ok, I think I finally understand. This will mostly keep the clocks in sync, but I'm not sure that will help with the issue I'm having of the server and client not computing the same result. I've done some more testing and I believe the issue is coming from the fact that the input isn't being applied for the same duration of time. For example, in the test I just did, the client moved for 5468.7882ms while the server only moved for 5438.1314ms. Should I just accept that that's how things are going to work out and correct the error with some interpolation or is this something that needs to be fixed?
1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0