2000-03-14: Movement discussion with Sal
05:52:39 *** You are now known as aloril
06:02:03 Aloril!!!
06:02:05 * Sal cheers
06:02:14 I need your help :)
06:12:51 hi Sal!
06:12:53 what?
06:31:40 I got libatlas compiling last night,
06:31:59 and then updated xclient. It connects to cyphesis now, as
before...
06:32:22 an its sending movement request, and cyphesis is logging them,
so I know its recieveing them,
06:32:36 but I can't seem to control the character...
06:32:44 its like he moves on his own
06:33:09 I'm using observerclient to watch while I move around in xclient
06:33:11 hmm.. uups forgot that auto flag...: is this at first connect
or second one?
06:33:42 hmm... I dont remember which connect...
06:34:42 it was happening after the first connect, that's for sure
06:34:49 hmm... it should not by default do anything ... hmm
06:35:28 well... what you receive from server?
06:35:45 should receive first: current pos+velocity
06:36:03 then after a while: new position+zero velocity
06:36:10 if you used target location
06:36:14 if you used velocity only:
06:36:25 then you should receive every 3s : pos+velocity
06:37:27 ok, I'll have xclient dump position responses. hmm
06:37:59 isn't there another cyphesis client that prints out coords, so I
can verify that its recieveing my requests?
06:38:24 yes... displayMovement.py I think
06:38:56 for verifying receiving... hmm.. certain log file should show
that:
06:39:05 don't use observerClient.py at all:
06:39:19 then everything that happens at world.log is from you
06:39:56 ahh ok.
06:40:03 hmm.. there should be per/connection log too: use connection
number+".log" to view it
06:52:09 hmm... the .log says its recieving my pos info.
06:52:47 hmm.. what does it reply?
06:52:50 (in logs)
06:53:01 connection_num.log should give reply too
06:53:57
06:53:58
06:54:08 accnt_2
06:54:09
06:54:23
06:54:24
06:54:36 [...]
06:54:39
06:55:08 hmm, the response pos is different from the request?
06:55:28 weird..
06:55:45 it would be ok if velocity was nonzero, but not now.. hmm..
06:57:43 start server from fresh, connect only using xclient and send
connection_num.log to me?
06:57:53 ok
07:02:26 ok its sent
07:02:36 in xclient I logged in,
07:02:48 then moved forward for some units, stopped,
07:03:01 then moved straight up some units, then logged off.
07:08:22 quite good compression ;-) :
07:08:23 255546 Defl:N 8989 97%
07:08:34 1/28 ratio
07:08:45 good 'ol zip :)
07:09:53 255k is a lot though, I was onle in xclient for a few seconds...
we have some optimization to do there...
07:10:52 seems I have forgotten flush from logging but should not be
problem: I think there is enough
07:10:58 * aloril nods
07:11:18 both in how much info attributes it uses and binary1
07:11:26 9K is not that much though?
07:12:11 hmm thats 72 kbits...
07:12:34 I'm on a 28.8 kbit per sec connection,
07:12:55 its cutting it a tad close, but it should work.
07:13:10 we could make it much smaller though, with a custom binary
layer
07:15:00 hmm.. removing unneeded attributes and binary3 should be much
smaller too
07:15:21 * Sal nods
07:15:32 ie for movement request we only need something like:
07:15:52 {byte}{float}{float}{float}
07:16:05 and binary3 should practically provide that
07:16:15 and we need it only once / second
07:16:22 even {byte}{short}{short}{short} if we really wanted to optimize
07:16:56 and byte only allows 255 possible messages, but we could do:
07:17:16 {byte=255}{byte2}{... ... ...} for more expansion.
07:17:51 how often you send movement?
07:18:01 um... lemme check
07:18:32 every 300ms
07:19:05 and only if the position is changed...
07:19:16 ahh.. hmm.:
07:19:27 when you send movement, then it starts moving
07:19:48 so if xclient does this: I'm here now: then it will intepret
reply wrong
07:20:01 oh I just ignore replys now...
07:20:13 I only send stuff...
07:20:13 because sending only coords (or coords+velocity) means: I
want to be there
07:20:44 hmm
07:20:45 so if you send current position:
07:21:05 it sends first you your real position in world and velocity
toward requested position
07:21:24 and when you reach it then it sends you requested position (+
zero velocity)
07:21:33 (and every 3s it sends updates)
07:22:03 so ... it lags because xclient opinion and server opinion
about position differs
07:22:07 hmm..
07:22:28 ahh
07:22:37 gotta replace python libatlas with C++ one though: python one
is quite slow: lots of abstract layers + it's in python
07:22:44 so C++ should be quite speedup
07:22:51 that is another reason for lag
07:23:04 well the best way would probably be if the clients send they're
current position, plus current velocity.
07:23:22 yeah... but you can't really move faster than server allows
;-)
07:23:26 that would be best suited for prediction/collision
07:23:29 * aloril nods
07:23:34 and cyphesis should support it
07:23:46 or even better:
07:23:48 yep... that's how quake1 works too
07:23:59 read what cyphesis sends about your position and send only
velocity
07:24:05 otherwise it might be jerky
07:24:19 server->client responses for all entities are the same way in
quake
07:24:25 let server handle all position handling you control it by
changing velocity: except when you stop
07:24:31 * aloril nods
07:26:18 811 bytes/msg now and 30 bytes/msg with zip
07:26:47 actually now that I think about it... does server really need to
know clients velocity at all?
07:26:58 843+1=65 bytes
07:27:02 uups
07:27:19 432+1=25 bytes
07:27:28 Sal: yes
07:27:34 so it can send it to other clients
07:27:47 so other clients can predict your movement too
07:28:05 it only needs the positioning... and if the client moved to an
invalid location it should respond with the correct position
07:28:06 hmm...
07:28:06 and of course it needs to move you the way you are yourself
thinking you do
07:28:19 so this is how I think it should be:
07:28:26 but I could send fals velocity no? and it would disrupt other
ppl's view of me...
07:28:26 you get your current position
07:28:41 C: sends velocity to direction you start moving
07:28:59 server can calc velocity from the last two positions...
07:29:04 S: comfirms your request (if it was ok)
07:29:16 S: after a while sends you changed pos+velocity
07:29:31 Sal: yes.. but only after fact
07:29:37 and thats too late ;-)
07:29:55 and of course it takes some time to move to new position
07:30:08 but wait,
07:30:09 so when you request new position, then it starts moving
07:30:16 server knows the initial position...
07:30:20 so it will always be behind
07:30:30 so after it recieves the first movment request, it has a
velocity...
07:30:31 yes it know so you only need to send velocity
07:31:02 Sal: what velocity? it currently uses 'max allowed for this
char'
07:31:30 it knows you position and client request: "I want to move
here"
07:31:51 hmm... well we move it there using max velocity then and tell
it that it started moving
07:32:03 and when it reaches: tell it that it reached and stopped
moving
07:32:24 thats how it works now
07:32:57 and if you use velocity + target location: same as above but
using given velocity
07:33:23 if you use only velocity: it moves using given velocity until
something happens (you give new orders or collision)
07:33:52 I see what you're thinking...
07:34:18 I had something totally different in mind, which I stole from
the quake 1 src code :) Wanna hear it?
07:34:39 btw.. 30 bytes for zip compression vs 25 bytes for
pos+velocty+byte is not much difference ;-)
07:34:58 so I think that suitable removing of attributes and suitable
codec we can achieve that
07:35:03 sure
07:35:17 that's pretty good, 30 bytes
07:35:18 anyhow
07:35:22 in quake:
07:35:49 client moves anywhere it wants, and every X ms tells the server
its current position
07:36:17 the server checks the line from pos1->pos2 for any obstructoin,
and if there is, it send the point of collision
07:36:37 if there is no obstruction, the server makes no response at all,
and client keeps moving.
07:37:07 however, when the server sends the client info about other
players,
07:37:26 it sends they're postion and velocity, not just position.
07:37:42 (so that your client can do prediction)
07:38:25 and if the entity's velocity is the same, the server just sends
the new position...
07:38:45 its very minimal communicate for the sake of bandwidth,
07:39:25 hmm. does it check for speed too... ie distance between
pos1,pos2 ?
07:39:42 yep! it does
07:39:59 checks the distance vs. time, makes sure the client isn't
cheating.
07:40:25 if the clients ducked, underwater, etc. Then the allowable
distance is even less, because they are not allowed to move as fast.
07:41:10 that's it :) pretty simple no?
07:42:49 what about initial movement? what speed it sends to other
clients?
07:45:33 well updates are only 333ms apart,
07:46:08 so it is too crucial. plus if you take the initial position +
request, you get a pretty accurate velocity
07:46:24 isn't too crucial I meant
07:47:32 the reason I like this, is that the client could move a very far
distance, with no server responses,
07:47:43 its very efficient...
07:48:02 only if hte client makes an illegal move does the server
respond.
07:49:06 hmm.. there is kinda lag for client->server->another client:
07:49:32 another client needs position before it know about change of
direction
07:52:20 hmm... the other client would recieve the new position+current
velocity together, from the server
07:53:02 al, imagine this:
07:53:16 there is a bird flying around in a circle, around a tree...
07:53:19 hmm... there is slight lag in changing direction... about
333ms
07:53:26 * Sal nods
07:53:51 with my method there no lag at all (except CPU+network of
course)
07:54:07 now if there is a lag inbetween packets, the client will
interpret the bird as flying around in the wrong location...
07:54:35 and the server doesnt know really that the client has the
incorrect coordinates for the bird...
07:55:18 so this causes problems. the most accurate way would be to send
the birds positioning instead...
07:55:28 this way there is minimal error, no?
07:56:11 you're absolutely right though, sending a velocity instead of a
position gives the server a head start by a few ms
07:58:18 Aloril: can you hack cyphesis to work with my status updates?
07:58:25 you can trust the client for now...
07:58:38 just so I can get basic movment/prediction working
07:59:21 hmm.. you mean just move it to where you want it to be?
07:59:30 yep...
07:59:47 and send that position to the other clients...
08:00:05 hmm... you can use change operation but... that woulnd't
update others using movement then :-(
08:02:53 gotta go for 1h
08:03:33 Sal: I think about some flag for now (ie keep current
behavior but setting some flag you can bypass it)
08:03:47 *** You are now known as aloril_away_1h
08:03:48 ah, that would be great!
08:03:54 or make just another message...
08:04:00 loc2? I dunno
09:10:52 * kosh is now known as koshbed
09:25:48 * You are now known as aloril
09:26:08 or coords2... gotta test though which is eventually best
method:
09:26:33 and it might be that this is temporary thing that is later
removed
09:28:05 hmm... couldn't xclient send immediately when user starts
moving velocity?
09:29:13 yep, I could do that
09:30:00 but then it requires that I read responses to make sure that the
server has my positioning right...
09:30:45 I'm afraid the network mismatch will cause the server->client to
go out of sync, sending the position info seems more dependable no?
09:31:22 ahh... yes
09:31:31 have you read unreal network paper?
09:31:44 nope...
09:31:54 I got the url once, didnt get around to it though
09:32:09 do you have it? I'll look at it...
09:32:09 http://unreal.epicgames.com/Network.htm
09:32:29 seems there client does more complicated prediction
09:35:34 reading...
09:36:54 hmm... I think that paper has influenced how I did
09:37:46 In a typical low quality 28.8K ISP connection, unreliable data
is generally received 90%-95% of the time. In other words, it is
very frequently lost.
09:37:54 so...
09:38:10 in a UDP game there is much packet loss,
09:38:30 what if a velocity packet is skipped? wouldnt the entity be
moving in the wrong direction?
09:39:30 ahh... well I have somewhat combined ideas from there but
assumed TCP ;-)
09:39:42 :-)
09:39:42 UDP will be there later
09:39:51 but I don't think we need it yet
09:40:00 but still, even with TCPIP...
09:40:15 what happens is packets come in bunches,
09:40:30 they arent spaced apart as even as the server sent them, so...
09:41:17 the client will rotate two '90 degree left' packets too close to
each other, when it was supposed to do it further apart...
09:41:30 the result: entities are severly in the wrong position...
09:41:40 Al, one more thing,
09:42:02 Sal: well.. each packet has time stamp about when it was sent
09:42:06 when I was coding XServer for Warforge demo1, I did just what
you said, only sent velocities...
09:42:50 and it cause the problems that I speak of, I would just like to
let you know :) sending the positioning info really made things much
easier.
09:43:52 Al: yep, we'd have to send timestamps... its difficult to
synchronize. positioning packets would make it easier on us, I
promise :)
09:43:59 time+velocity or pos+velocity should handle above problem
09:44:19 sure positioning is easier.. but unoptimal I suspect ;-)
09:44:22 but just pos would work too :)
09:44:44 it is optimal... really, only need to send one vector...
09:44:50 * Sal begs Aloril
09:45:05 pleeeease :) It would make this easy on me
09:45:36 hmm... well I think with velocity you can send less packets,
so it's optimal in both sense: bandwidth and lag
09:45:44 but I'll add it temporary there
09:45:53 thanks!
09:46:10 and then test things on what is good so we have more info
09:46:18 but wait... temporary? I think atlas should be able to have
this feature...
09:47:03 no?
09:47:29 then people can choose which one they would like to use...
09:47:43 ie maybe Karsten wants to do it your way...
09:47:51 hmm... well.. it is kind of cheating: client tells: "I'm
here" server replies: "Seems reasonable, I agree, you can have your
333ms advantage"
09:47:58 and I could still do it my way. It would make a good atlas
feature :)
09:48:17 well client doesnt really have an advantage...
09:48:35 because the world is simulated serverside.
09:48:59 client does have 0.3s movement change advantage
09:49:17 ie: server simlates movement after it has happened
09:49:27 in fact its better if the client 'lies' about its position to
the server (like quake does) depending on ping... so that the user
sees something more accurate
09:50:16 hmm.. good point
09:51:03 I've been playing with xclient + xserver for a long time, this
works best, you gotta trust me :)
09:53:48 besides, I don't think we can go wrong by implementing both
methods. 'Tis a compromise
09:58:58 Sal: search for "Player Prediction" in that paper
10:04:04 reading...
10:06:32 yep, this is how xclient+xserver works now,
10:06:37 quake also...
10:07:00 the server sends 'adjustmove message' if the client moves
incorrectly
10:08:16 their method is a bit less efficient thatn quake because they
send all info all the time it seems.
10:08:34 ie the client send pos+vel+timestamp for every move.
10:08:58 +viewpitch +viewyaw
10:09:01