No active sessions yet.

No games yet.

No conversations yet.

No characters yet.

Cooperation

How plugins meet without depending on each other — flat fields, events, and asking first.

Plugins never call each other. They meet through state the engine owns.

That is what makes them removable: if hunger called into rest directly, deleting rest would break hunger. Instead they meet in three places, none of which require either to exist.

1. The field bag is flat

Any plugin can read any declared field:

$.field('satiety')

No namespacing, no imports. Which means you must ask before you rely:

$.hasPlugin('hunger') && $.field('satiety') < 20

Without that guard, a game with no hunger plugin reads null and your rule behaves as though everyone is permanently starving — or never hungry, depending which way your comparison points. See Missing values.

2. Engine events

One plugin's $.damage() fires onDamage, which another plugin's hook catches. Neither knows the other exists; they both know the engine.

3. Declared events — offering a say

An event is what your plugin offers other plugins a veto over.

The rest plugin publishes rest:sleep. Hunger answers it:

// hook on rest:sleep
if ($.field('satiety') <= 0) {
  $.veto("they are too hollow with hunger to settle")
}

Hooking an event no installed plugin declares is inert, not broken. So a rule that answers an optional system simply does nothing when that system is absent — which is exactly the behaviour that lets both plugins ship independently.

Use veto, not refuse, when answering an event. refuse stops the player's action; using it here tells a player standing still that hunger clawed them out of a sleep they never started.

The test

Delete either side of any pairing and the other still works.

Hunger without rest: still drains, still starves, never vetoes a sleep because nothing proposes one. Rest without hunger: still restores, never gets vetoed. Both coherent.

If deleting one side leaves the other broken or nonsensical, they are not cooperating — one is depending on the other, and you have built one plugin in two pieces.

Next

Formulas and dials — sharing tuning numbers correctly.