Tale (10): heartbeats en deferreds

Sunday 22 April 2012, 15:32:00 | mud / i.f.

Tot nu toe was alles 'statisch' en gebeurde er alleen iets als je een commando intypte op de command line. Maar de server heeft nu een main loop gekregen en de user input/output gebeurt onafhankelijk daarvan. De main loop doet periodiek (1 keer per seconde op dit moment) een 'server tick' waarbij alle geregistreerde taken worden bijgewerkt.

Die taken kunnen zijn het bijwerken van de game clock (loopt op dit moment 5x zo snel als realtime dus 1 minuut in het echt is 5 minuten in game). Verder kunnen objecten een 'heartbeat' registreren en dan wordt deze elke server tick aangeroepen. (een handige shortcut hiervoor is de @heartbeat class decorator). Objecten kunnen echter ook een 'deferred' registreren bij de driver, dit is een functie die op een gegeven moment in de toekomst uitgevoerd wordt (je bepaalt zelf op welk moment).

Omdat objecten nu vaker iets met de driver moeten kunnen doen heb ik wat verbeterd aan de globale context zodat de driver overal globaal beschikbaar is.

Wait commando toegevoegd: wacht een bepaalde tijd (in-game). De server tick wordt als het ware vooruit gespoeld.

Flee: vlucht in een willekeurige richting

!return (stuurt iemand terug naar waar hij vandaan kwam voordat hij ge-teleport werd), !server (toont wat technische info over de toestand van de server), !events (toont alle geregistreerde heartbeats en openstaande deferreds).

Nog een paar codematige verbeteringen: er is nu een living.tell_others shortcut methode, omdat vaak dezelfde code werd gebruikt om een bericht te sturen aan alle andere personen in de locatie. Verder hebben alle objecten een init() method gekregen die door de echte __init__() wordt aangeroepen. Hierdoor is het vaak niet meer nodig om moeilijk te doen met het overriden van __init__ en het doorgeven van alle standaard parameters aan de base class.

Tenslotte: op unix platforms is er nu command line editing en history dmv readline.

Voor binnenkort: omdat ik eigenlijk ook wil dat deze code gebruikt kan worden om een single-player spel mee te maken (zeg maar een soort interactive ficition text-adventure) zal er op enig moment ook een save mogelijkheid beschikbaar moeten zijn die de hele game wereld opslaat. En bij load weer terug inleest zodat je kan doorgaan waar je was. Een simpele pickle van de driver of de player objecten werkt op dit moment niet omdat er functie objecten hier en daar zitten die niet gepickled kunnen worden (alsmede WeakSets). Maar toch wil ik proberen heer eerst meer aandacht aan te geven dan aan eventuele mud (multiplayer) zaken.

De code is trouwens allemaal GPL en hier in svn beschikbaar.

Stukje dialoog van hoe een paar npc's nu werken met hun heartbeat en deferred volgt hieronder:

>> s
<mudlib.base.Location 'Essglen Town square' @ 0x24d9630>
[Essglen Town square]
The old town square of Essglen. It is not much really, and narrow
streets quickly lead away from the small fountain in the center.
There's an alley to the south.
A long straight lane leads north towards the horizon.
You see a black gem, a blue gem, a bag, a box1 (a black box), a box2 (a white box), a clock, a newspaper, and a trashcan.
Laish the town crier, ant, blubbering idiot, and rat are here.

>> Laish the town crier yells: welcome everyone!

Blubbering idiot drools on rat.

examine clock
<mudlib.items.basic.WorldClock 'clock' @ 0x24d9830>
You see a clock.
The clock reads 2012-04-19 14:00:35

>> examine clock
<mudlib.items.basic.WorldClock 'clock' @ 0x24d9830>
You see a clock.
The clock reads 2012-04-19 14:01:00

>> !events
Pending events overview. Server tick is 1.0 sec.
Heartbeat objects (2):
  <mudlib.rooms.town.VillageIdiot 'idiot' @ 0x24d9910>
  <mudlib.rooms.wizardtower.Drone 'drone' @ 0x24d9d50>

Deferreds (1):    (server tick: 1.0 sec)
  due     | function         | owner
  0:00:01 | do_cry           | <mudlib.rooms.town.TownCrier 'laish' @ 0x24d9890>

>>
Laish the town crier yells: welcome everyone!

>> take clock
You take a clock.

>> n
<mudlib.base.Location 'Lane of Magicks' @ 0x24d9650>
[Lane of Magicks]
A long straight road leading to the horizon. Apart from a nearby small tower,
you can't see any houses or other landmarks. The road seems to go on forever though.
The town square lies to the south.
To the west is the wizard's tower. It seems to be protected by a force-field.

>> Someone nearby is yelling: welcome everyone!
The sound is coming from the south.

>> exa clock
<mudlib.items.basic.WorldClock 'clock' @ 0x24d9830>
You're carrying a clock.
The clock reads 2012-04-19 14:05:30