[Twisted-Python] Two main loops
jasper at peak.org
Mon Nov 12 18:18:15 EST 2007
glyph at divmod.com wrote:
> On 06:23 pm, jasper at peak.org wrote:
>> glyph at divmod.com wrote
>> In hindsight I see a separate process won't work (duh!) However, I
>> was thinking a thread might work, since the data I'm sending (players
>> get a filtered view of the game's true state) isn't used by anything
>> else, and the data isn't /that/ large. ;-) Am I missing something
>> low level here? Would this end up locking bits other than those
>> being serialized?
>> I suppose it's a bit moot, as I'm reluctant to fiddle with threading.
> If you've got a large object, let's say the state of the game world,
> and you need to lock it for use within a thread, it is likely that
> other things in your program will want to access it before long. You
> can only have so many "large" objects in a program, after all, and
> they tend to be shared. The one you referred to, "the game's true
> state", is obviously going to be accessed by a lot of code unless you
> have a very strange game indeed.
I don't send the players the "True State", I first calculate a trimmed
and altered copy of it, according to what they can perceive. I then
send this, which in practice isn't used by anything else on the server.
>> Optimizing my program (e.g. by sending a bunch of smaller data
>> chunks) feels like the wrong way to go... Wouldn't it make more
>> sense to hack PB's callRemote() to do this in a more general manner?
>> I'm thinking somewhere around jelly._Jellier.jelly()'s recursive
>> calls to itself; perhaps using generators, although I'm fuzzy on the
>> implications of recursion + generators...
> callRemote *can't* do this in a general manner and remain compatible
> with PB's existing semantics. It would be extraordinarily difficult
> to come up with semantics that would make sense for this. Consider:
> bob = Mob(hitPoints=3)
> jethro = Player()
> jethro.callRemote("enterSensoryRange", bob)
> bob.hitPoints += 1
> How many hit points does Jethro think Bob has? Probably 3, but if PB
> might be breaking up serialization work into separate reactor turns
> for you behind your back, then maybe 4. Given that there's no way to
> know, you don't know whether you have to send Jethro an update to
> bob's hit points or not.
> If you can figure out how to answer this question in a way that makes
> sense (i.e. never uses the word "maybe") then you might be able to
> implement something very cool and useful. I certainly can't think of
> a way to do it, though. Good luck!
For my game, that's actually pretty straight forward, as I don't allow
such complex situations. I allow 3 things though PB:
1) Ask for status
2) Request current state
3) send actions for the current turn
Clients never actually /do/ anything (eg "enterSensoryRange), but
instead schedule actions for the game server to carry out on their
behalf at a later time (simultaneously with other players' actions).
The only time a client get a large chunk of data is when it's asked for
it, and clients know enough to wait for a response. It's possible for
the client to send actions based on an old turn right before a new turn
is processed, but these are simply tossed out with a warning that
they're out of date, and the client should update it's state.
Reworking the above example, Jethro would always see that Bob has 3
hitpoints on turn X, and 4 hitpoints on turn X+1. Jethro's
"enterSensoryRange" attempt would be made for a specific turn, say X.
If it arrives before turn X+1 is calculated, he gets his result on turn
X+1. If it arrives late, well then Jethro was too slow.
For a more general case perhaps it's more complicated...
More information about the Twisted-Python