2-player game, client and server at localhost

Michael Rybak accepted at ukr.net
Tue Aug 2 03:16:13 EDT 2005


sorry for emailing privately, pressed the wrong "reply" button

>> Each player controls a snake, which is 2 to 12 balls connected to each
>> other with ropes; by mouse motions you move the snake's head, and the
>> rest of the body moves adhering normal physics. The objective/gameplay

DLB>         For purposes of the motion this snake -- the game rendering side
DLB> (the client) probably should handle the physics. The only part being
DLB> actively controlled is the head, and only the head movement needs to be
DLB> sent -- the clients respond to head movement and compute the effect on
DLB> the rest of the body. IOW, the head and /attached/ balls are ONE object
DLB> for purposes of server I/O, not "2 to 12".
 Well, that's exactly how I think of it.

>> is unimportant here, but if you're curios - all the balls of your
>> snake are bullets, and right-clicking releases current tail. So, you
>> have to spin around, and release the tail in appropriate moment so it

DLB>         At this point, you've added another object to track -- but it
DLB> sounds like all you need to send is a vector (start position, direction,
DLB> speed). The server, on each "input" can compute -- based on the
DLB> situation at that moment -- if an intersect will occur, and when. That
DLB> state doesn't change unless on or the other player inputs some new
DLB> command (the target player, most likely, trying to avoid impact).
But that happens all the time, and lots of times per second! If you
played Quake, CS or even UT :), you know that you hold your "forward"
key pressed all the time, and you also move your mouse aiming on
target almost all the time. And when I play Quake, I *see* how my
opponent's model aims at me, I mean, his mouse motions are transferred
to me.
 Well, I suppose that Quake doesn't send mouse motion, clients
probably retrieve the resulting aiming direction from server, but in
my case, as you said yourself, client side should do physics'
computations.

DLB> Upon the new input, the server interpolates all moving objects -- that is,
DLB> its prior update (time T0) says an intersect will occur at time T0+t,
DLB> and the player response came in at t/2 (halfway, for simplicity). The
DLB> server would compute positions for tracked objects at (T0+t/2), then
DLB> apply the new motion vectors (player changed heading), transmit all this
DLB> to all clients, and determine the next intersect time. The server
DLB> doesn't have to do anything until either this intersect time or a play
DLB> input comes in.
 That's the problem - "or a player input comes in". As I've explained,
this happens a dozen of times per second :(. I've even tried not
checking for player's input after every frame, but do it 3 times more
rare (if framecount % 3 == 0 : process_players_input()). Well, I've
already got it that I shouldn't tie this around framerate, but
nevertheless...

>> So, you see - server will have to send current status as much time per
>> second, as much fps I want, and that's quite a lot of data.
>>
DLB>         No... Frame rate is independent. Each client should perform some
DLB> tests to determine what frame rate they can support, and adjust their
DLB> internal time-steps to that. The server should probably send a
DLB> time-stamp so clients can adjust for running over (might result in small
DLB> jerks on slow machines, say). Of course, the server will need to check
DLB> its clock speed to determine what size a time step will be (and maybe
DLB> send that to clients so clients can compute a clock factor for internal
DLB> calculations -- especially if the server is using a "simulation clock"
DLB> for speed rather than wall clock time)
 I'm afraid I'm loosing it. Let's consider your example:

DLB>         Say the "snake" is moving left to right at 100 pixels (or some
DLB> game internal unit) per second, and client one can only run 5FPS; that
DLB> means each rendering pass uses the head position as:
DLB>         P(f) = P(T0) + (100/5)*f.
DLB> {P(f) is Position(frame); P(T0) is the position at the start, the last
DLB> status received from the server; 100/5 is the speed divided by the frame
DLB> rate = speed per frame}

DLB>         The other client may be running 50FPS... For that client, the
DLB> same status turns into:
DLB>         P(f) = P(T0) + (100/50)*f

DLB>         The first player sees the snake move 20 pixels per frame. The
DLB> second player will see it move 2 pixels per frame, but will see 10
DLB> frames in the time the first player sees one.

This sounds transparent, but my slow client isn't able to process
networking fast enough, so even if it's able to work at 30 fps, it
can't draw those 30 frames, because input from other player comes
instantly, about 10 times per second, and server tries sending this to
all clients. So my slow client simply can't know current true status,
thus has nothing to draw, because it can't handle 10 transfers per
second. And if server doesn't send user motions equal number of times
to all clients, while they compute the world's status, they will
happen to have different pictures :(



-- 
Best Regards,
 Michael Rybak                       mailto:accepted at ukr.net




More information about the Python-list mailing list