pygame and socket.recv

Aaron Brady castironpi at gmail.com
Thu Apr 2 15:50:16 CEST 2009


On Apr 2, 4:13 am, Tim Wintle <tim.win... at teamrubber.com> wrote:
> On Wed, 2009-04-01 at 18:45 -0700, Aaron Brady wrote:
>
> > My game loop looks like this:
>
> > poll events, get 1 at most
> > send to server
> > wait for server reply
> > render entire frame
>
> The look I'm suggesting is:
>
> poll events
> write to (non-blocking) socket
> render frame
> check non-blocking socket and add events to the event queue
>
> > Yes, I am blocking for the data to come down the network.
> > Unfortunately, if I use any "prediction," I will have to go back and
> > un-render the previous frame, then redraw with the new information.
>
> Sounds like that may have to be re-factored slightly, afraid this is why
> real-time networked games are tough to make.

+1 understatement of the week.  Are you saying that there aren't that
many out there?  I.e., if average and worst-case packet times were
faster, there would be more?

> > 40 transmissions per second in each way can't be too much to ask, it's
> > just that they have to alternate, up one, down one.
>
> IMO It's very unlikely to be a bandwidth issue. It's more likely to just
> be a latency issue.

The actual mechanics can't be that hard.  If I had a dedicated pathway
that the OS didn't even intervene in, 40 fps would be a trifle; and I
would also have a custom OS.  'Doom 25: Now including operating
system!'

> > I don't understand your solution.  I can't picture it for my favorite
> > RTS game or the one I'm writing.  Are you saying that the slower
> > machine just jumps ahead, and its user just doesn't have the
> > opportunity to make moves on the omitted frames?
>
> a) How much to move etc. is decided based on some real-time solution
> (not on the number of frames). Ideally all movement methods take a
> parameter that is a delta in time. (i.e. 1/40th of a second)
>
> b) That time is the time that is synced across machines - if machine B
> has to put it's timer forward 1/50 of a second, you call all the methods
> above with a timedelta of 1/50 before continuing.

I must be writing a very peculiar game.  Frame-for-frame matching is
important.  The game space is a grid, a logical space, zero mass, not
a real one.  I started to tell Terry yesterday that arbitrary
discontinuities in position and momentum are possible.

Your method ensures than an object is moving at a constant rate,
distance over time, as it is perceived by the player.  I want
something like it, so that if I'm anticipating an upcoming turn, I can
press the key at the time I want, and the model on every machine is
informed, regardless of what the graphics did in the interim.

> c) Obviously things like which frame a sprite is on isn't really
> necessary for the sake of a game, it's only game state variables that
> would be required.

Yes, this.

> d) If you end up with jumping objects then you can create "ghost"
> objects for the other player's objects. When you get the state of a
> foreign object, update the real object with the properties, but draw the
> sprite at the position of your ghost object - and every frame move the
> ghost object towards the real one a little bit. That gets rid of the
> effect of jumping from one place to another, but keeps collision
> detection etc. correct wrt the other player.

It's just that if you register a collision in between the time that
one object has changed its position and momentum, and the time you
learn about it, you have to retroactively edit the collision, restore
hit points, and recalculate the other object's position and momentum,
to name a few.  For example, if you hit some kind of power-up that
warps your position to another place, you can't get hit by a weapon
that is colliding with your old extrapolated place.  Maybe each
collision has to take a branch: if the collision turns out to have
succeeded, proceed from state X->Y1, else from state X->Y2.  That
sounds combinatoric, when multiple collisions may or may not be
interacting.  { (X,Y)->(X1,Y1), (X,Y)->(X1,Y2), (X,Y)->(X2,Y1), (X,Y)->
(X2,Y1) }.  Or, you could just freeze the models of some objects
pending update, and continue with the models of the rest.

This is all not to mention the balance between pre-transmission and
post-transmission calculations, which is a time-space trade-off IMCAC
if my calculations are correct.



More information about the Python-list mailing list