Zen of Networked Character Physics

Started by
20 comments, last by DirectXFreak 19 years, 3 months ago
Quote:the maximum size of the redundant input is bounded nicely


My only point was that, in the case of 2-second congestion, you need to bound the amount of data to a copy of the last 2 seconds sent. You're seldom constrained on the upstream anyway, and this data compresses well, so I think we agree. (I know other games do the same thing, too)

Regarding interactions and time-steps: you can subtly adjust the time step at which you display and interact with objects to hide a lot of the interaction latency and ownership ambiguity. We started doing this in 1999, and it's worked pretty well for us (we do have a patent on that technique, btw, so anyone can read up on what we do: 6,628,287).
enum Bool { True, False, FileNotFound };
Advertisement
Quote:Original post by sharkyx
Why is it necessary to completely eliminate the client side prediction? As in most cases, you still have some possibilities between using and not using csp. Lots of players influencing a stack of boxes is an extreme example, IMHO. In games, how often does it happen that two players directly influence the same object at the same time? You can always use client-side prediction, but instead of just predicting the player itself, you predict the whole world. If another player is moving in the clients direction, it knows that they will collide, unless the collision is caused (or avoided) by simultaneous user input on both sides. So it does (and will) depend largely on the type of game if csp can be performed.

You could even go one step further and use csp on an object while it is under direct control of the client (think HL2's gravity gun) and as soon as the object is released, you turn it off, smooth the object into a non-predicted state. If you incorporate all the game's knowledge into the network system, you can minimize the snapping by just using prediction where it is safe, and waiting for the roundtrip where it is not safe (e.g. when the game knows already that two players are influencing the same object). The only problem I see here are the possible side-effects of turning csp on and off all the time, which will result in little snaps in itself.

RFC, I have never tested anything like this.
Regards


client side prediction is the fundamental cause of the snapping, remember, its the error in your prediction being snapped back by the server. yes if you could maintain locks on the objects perfectly somehow an only predict when you had the lock then it would be ok, but if you are predicting ahead and other clients *can* acquire the same object (as it my stack of blocks with multiple players), then eventually two players will aquire the lock while predicting ahead then get snapped back.

i'm just talking a severe case here, but just think if every player affected each other player then client side prediction cant be used. if running around on a static level very occasionally bumping into other players is your game, then client side prediction works very well -- eg. fps which is the technique i describe in my talk

cheers
Quote:Original post by hplus0603

Quote:the maximum size of the redundant input is bounded nicely

Regarding interactions and time-steps: you can subtly adjust the time step at which you display and interact with objects to hide a lot of the interaction latency and ownership ambiguity. We started doing this in 1999, and it's worked pretty well for us (we do have a patent on that technique, btw, so anyone can read up on what we do: 6,628,287).


ah, there inc. nice work

do you know of any fps type network games that send mouse input as deltas (these real values i was talking about), instead of sending the raw orientation yaw/pitch?

the reason i ask is that one of the things i'm playing around with is making the server authoritative over orientation with the client driving it by sending mouse deltas - would completely fix aimbot hacks, and if you were able to perfectly delta encode the important moves, you'd never get packet loss snaps for orientation

i know current unreal games use say 2-3 approximate important moves, but they dont go to the length of *really* encoding all the important input since the server ack. actually, its quite primitive really compared to what you can do, and of course, they still send raw yaw/pitch... =p

cheers
Quote:do you know of any fps type network games that send mouse input as deltas


Well, we do :-) I'm working on the military product which is more FPS-like than the online Club Med-like experience (we are not affiliated with Club Med, the real-world travel company).

I think all others I've heard of just send orientations. It really is the easiest to deal with, and lead to smaller (and sometimes fewer) corrections in the case where there is packet loss to the viewing clients (i e, proxies in your demo). Perhaps the best way is a hybrid: send mickeys to the server, but the server then sends orientations to the proxies.

Note that you still won't get rid of aimbots, unless you want to limit the player's rate of turn per physics step. And you may find that a FPS where you can't wrist-snap 180 degrees in a single frame may be reveiwed as "sluggish" or "difficult to control." Wasn't this one of the problems with Halo and the console controller, for example?

[Edited by - hplus0603 on December 29, 2004 11:47:46 PM]
enum Bool { True, False, FileNotFound };
Quote:Original post by hplus0603
Quote:do you know of any fps type network games that send mouse input as deltas


Well, we do :-) I'm working on the military product which is more FPS-like than the online Club Med.

I think all others I've heard of just send orientations. It really is the easiest to deal with, and lead to smaller (and sometimes fewer) corrections in the case where there is packet loss to the viewing clients (i e, proxies in your demo). Perhaps the best way is a hybrid: send mickeys to the server, but the server then sends orientations to the proxies.

Note that you still won't get rid of aimbots, unless you want to limit the player's rate of turn per physics step. And you may find that a FPS where you can't wrist-snap 180 degrees in a single frame may be reveiwed as "sluggish" or "difficult to control." Wasn't this one of the problems with Halo and the console controller, for example?


heheh. club med :)

nice to hear somebody else is doing it, seems a lot of the standard fps these days are caught in the quake/unreal does it this way, i'm not going to think how i can do it better rut...

what i do is the hybrid method at the moment, client streams mickeys and important moves to server, and the proxies receive 8bit encoded yaw/pitch for orientation, which is good enough for the proxy - its just an approximation after all.

and yeah you are right about not fixing the aimbot, doh :)

[Edited by - Gaffer on December 30, 2004 2:59:52 AM]
Quote:Original post by hplus0603
Quote:do you know of any fps type network games that send mouse input as deltas


Well, we do :-) I'm working on the military product which is more FPS-like than the online Club Med-like experience (we are not affiliated with Club Med, the real-world travel company).

I think all others I've heard of just send orientations. It really is the easiest to deal with, and lead to smaller (and sometimes fewer) corrections in the case where there is packet loss to the viewing clients (i e, proxies in your demo). Perhaps the best way is a hybrid: send mickeys to the server, but the server then sends orientations to the proxies.

Note that you still won't get rid of aimbots, unless you want to limit the player's rate of turn per physics step. And you may find that a FPS where you can't wrist-snap 180 degrees in a single frame may be reveiwed as "sluggish" or "difficult to control." Wasn't this one of the problems with Halo and the console controller, for example?

a combination solution would be to send deltas as a 3 or 4 bit lookup in a table, with values like [-pi/2, -pi/4, -pi/8, -pi/16, pi/16, pi/8, pi/4, pi/2], giving those trying to create an aimbot an interesting time in that they have to generate good motions for SEVERAL time steps which add up to the correct aim. <br><br><a href="http://www.gamasutra.com/features/20040204/wagner_01.shtml">inspiration</a><br><br>thus complicating things significantly, if running &#111;n the local machine. If another machine [intercepting and modifying the packets] knew how to change the orientation it probably will not have as challenging of a time.<br><br>I wonder what humans aiming with such a system looks like if you plot the motions… Although a touchy subject a human would probably not aim accurately in a small number of timesteps [say, 4 or 5, with 30 a second] very frequently, but a cheater [who uses their aimbot a lot] would. What are skilled players like?
sit you are right, but thinking about it now i think that all that can be done is some security through obscurity - fundamentally if a local user can aim, then with varying degrees of difficulty, an automated aim bot could do so also.

i guess its such a serious in counterstrike problem because of their instant hit weapons and their lag correction for weapons (ie. aim at target intead of leading), and i'm guessing that they send orientation yaw/pitch directly as well

so if you make it a bit harder (ie. send mickeys instead of direct orientation, dont have lag correction, dont have instant hit) then it gets harder, but its always possible to make an aim bot unfortunatly :(
You know, there's no reason you should have to 'snap' when a client-side prediction disagrees with the server. In Zap (www.zapthegame.com) all clients interpolate all objects, including the player controlled object to their predicted locations.

The real "problem" I've had with networked physics and client-side prediction is that the server will receive input/time advance from different clients at different times, so that if two objects are touching, each controlled by different clients, the input/passage of time will be simulated for each seperately.

Also, for reference, Tribes 1 and 2 sent pitch/yaw deltas rather than absolute camera positions with each move. Each move would also be sent until acknowledged by the remote host, but as hplus points out, these delta compress really well, and are quite small, so it's unlikely to overflow the maximum size of a client->server packet. In practice, if you have that much packet loss, the client is going to notice it anyway.
nice work on tribes netcode mark, that really set a benchmark for the rest of the industry to follow. i've compared TNL, and Unreal style networking, and when it comes to the core physics replication, TNL is simply much more advanced.

and i didnt know you guys encoded the mouse deltas all the way back then, thats pretty impressive :)

regarding interpolation mark, my preferred technique is to use an exponentially smoothed moving average - however i keep it completely separate from the physics. point is when i snap physics, i want the determinism of an extrapolation from the exact server snap physics state and input, so i just 'snap' the primary simulation, i have a separate smoothed object that follows with an exponentially smoothed moving average for the primary quantities (eg. smoothed position, orientation, i snap everything else)

this technique works very well for the cube, and i can even change the smoothing tightness adaptively to smooth over large snaps nicely, without introducing too much latency in the smoothed cube following the real snapping physics under normal conditions.

unreal does a similar technique for its "simulated proxies" of characters, except it only does a basic linear or physics + gravity approximate physics + collision, instead of running the same physics sim for characters on the proxy side. the main difference in its smoothing is that it doesnt seperate the main physics and smoothed physics, but just exponentially smooths towards the target snap by say 0.5 if the difference in position is above some threshold (say 10cms or so). this ends up introducing more error in the sim proxy physics which needs more smoothing over time, but for them its just a rough apporimation, you can do much better.

mark, how does your ghost stuff work in TNL, also, did you guys use integer time (eg. fixed physics timestep) for tribes, or variable? one of the biggest things i've learned just recently is that integer time for networking really simplifies a lot, especially on the proxy/ghost side. running at 100fps integer time and your time goes from 1000->1004 you know you've lost two packets for example. etc.

also, mark - how hard would it be for me to strip down TNL and use it as a low level layer, eg. unreliable, reliable ordered and nat punchthru only, plus your bitstream and compression etc. what i want to do is build my own rpc/network object layer in LUA or Ruby. i'm currently using RakNet for my personal project because i could easily discard most of its simple rpc and network object stuff -- tnl seemed at first glance much more framework like, and harder to strip down. but i'd be interested in using instead it if this is possible

cheers =)

[Edited by - Gaffer on December 31, 2004 1:44:48 AM]
Quote:
regarding interpolation mark, my preferred technique is to use an exponentially smoothed moving average - however i keep it completely separate from the physics. point is when i snap physics, i want the determinism of an extrapolation from the exact server snap physics state and input, so i just 'snap' the primary simulation, i have a separate smoothed object that follows with an exponentially smoothed moving average for the primary quantities (eg. smoothed position, orientation, i snap everything else)

Yes, we also extrapolate from the exact server position -- but the player never sees the snap - since the player sees the interpolated object positions. I haven't actually played around with many different smoothing algorithms -- mostly I just dorked with it until the interpolation looked good. As far as latency goes, eventually the interpolation catches up with the extrapolated position, at which point it just extrapolates (until the next server correction).

Quote:
mark, how does your ghost stuff work in TNL, also, did you guys use integer time (eg. fixed physics timestep) for tribes, or variable? one of the biggest things i've learned just recently is that integer time for networking really simplifies a lot, especially on the proxy/ghost side. running at 100fps integer time and your time goes from 1000->1004 you know you've lost two packets for example. etc.

With Tribes we used a fixed 32 ms timestep, with Zap I changed it to be whatever framerate the client is running at. But there is no notion of time encoded in the network protocol itself, rather each connection just tracks a running round trip time, and this information can be used in the interpolation and extrapolation of the higher level objects.

Quote:
also, mark - how hard would it be for me to strip down TNL and use it as a low level layer, eg. unreliable, reliable ordered and nat punchthru only, plus your bitstream and compression etc. what i want to do is build my own rpc/network object layer in LUA or Ruby. i'm currently using RakNet for my personal project because i could easily discard most of its simple rpc and network object stuff -- tnl seemed at first glance much more framework like, and harder to strip down. but i'd be interested in using instead it if this is possible


Actually, in TNL it is very easy to strip out layers you don't need. The basic (game) connection class hierarchy looks:

NetConnection -> EventConnection -> GhostConnection

NetConnection provides an unreliable "notify" protocol -- it simply tracks which of the packets were successfully received by the remote host and which ones were dropped.

EventConnection adds "events" - unguaranteed ordered, guaranteed and guaranteed ordered messages. RPCs are just "syntactic sugar" on top of events.

GhostConnection manages object replication, partial object state updates, prioritization, scoping, etc.

You can derive a new class at any point in the hierarchy - for example, in Zap, we derive a GameConnnection from GhostConnection for game communication and a CommServerConnection from EventConnection for the community login server.

This topic is closed to new replies.

Advertisement