[Twisted-Python] Two main loops

Jasper 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...

-Jasper





More information about the Twisted-Python mailing list