Message codes
Every event carries a message code — dotted snake_case, namespaced by subsystem — and
format_message maps each code to a default English line.
The table lists all shipped codes: the event class that emits each one, that class's default
visibility, and the default template. Templates are code (each receives the typed event),
so the template column shows the registry source verbatim; the named helper functions it
references appear in full at the bottom of the page.
The visibility column is the event class's field default — there is no per-code visibility. Specific emissions may override it: the referee's door-state command, for example, emits the door open/close codes at referee visibility so scripted changes stay hidden until discovered.
A code with no template formats to the code string itself, and unknown codes never raise, so logs from newer engine versions stay printable.
adjudication.*
| Code | Event | Default visibility | Default template |
|---|---|---|---|
adjudication.dice_rolled |
DiceRolledEvent |
referee |
lambda event: ( f"Referee rolls {event.expression}: [{', '.join(str(die) for die in event.rolls)}] — total {event.total}." ) |
battle.*
| Code | Event | Default visibility | Default template |
|---|---|---|---|
battle.ended.defeat |
BattleEndedEvent |
player |
lambda event: "The party is defeated." |
battle.ended.fled |
BattleEndedEvent |
player |
lambda event: "The party flees the battle." |
battle.ended.victory |
BattleEndedEvent |
player |
lambda event: "The battle is won." |
battle.group.moved |
GroupMovedEvent |
player |
lambda event: f"{event.group_id} is now {event.distance_feet}' away." |
battle.monster.defeated |
MonsterDefeatedEvent |
player |
lambda event: f"{event.monster_id} ({event.template_id}) is {event.outcome}." |
battle.round.started |
BattleRoundEvent |
player |
lambda event: f"Battle round {event.round} begins." |
battle.side.fled |
MonsterFledEvent |
player |
lambda event: f"{event.group_id} flees the battle!" |
battle.side.surrendered |
MonsterFledEvent |
player |
lambda event: f"{event.group_id} surrenders." |
battle.spell.declared |
SpellDeclaredEvent |
player |
lambda event: ( f"{event.caster_id} begins casting {event.spell_id}" + (" (reversed)" if event.reversed else "") + "." ) |
battle.started |
BattleStartedEvent |
player |
lambda event: "Battle is joined!" |
combat.*
| Code | Event | Default visibility | Default template |
|---|---|---|---|
combat.attack.auto_hit |
AttackRolledEvent |
player |
_attack_auto |
combat.attack.hit |
AttackRolledEvent |
player |
_attack_hit |
combat.attack.missed |
AttackRolledEvent |
player |
_attack_missed |
combat.damage.absorbed |
DamageAbsorbedEvent |
player |
_absorbed |
combat.damage.dealt |
DamageDealtEvent |
player |
_damage |
combat.death.died |
DeathEvent |
player |
lambda event: f"{event.target_id} is killed." |
combat.death.permanent |
DeathEvent |
player |
lambda event: f"{event.target_id} is permanently destroyed." |
combat.drain.drained |
LevelDrainedEvent |
player |
lambda event: ( f"{event.target_id} loses {event.levels_lost} level(s) " f"({event.hp_lost} hit points), now level {event.new_level}." ) |
combat.drain.slain |
LevelDrainedEvent |
player |
lambda event: f"{event.target_id} is drained of all levels and dies." |
combat.equipment.destroyed |
EquipmentDestroyedEvent |
player |
lambda event: ( f"{event.target_id}'s equipment is destroyed: " + ", ".join(event.item_names) + "." ) |
combat.healing.applied |
HealingAppliedEvent |
player |
lambda event: f"{event.target_id} regains {event.amount} hit points ({event.source})." |
combat.healing.blocked |
HealingAppliedEvent |
player |
lambda event: f"{event.target_id} cannot be healed by {event.source} means." |
combat.initiative.rolled |
InitiativeRolledEvent |
player |
_initiative |
combat.morale.broke |
MoraleCheckedEvent |
referee |
lambda event: _morale(event, "they flee or surrender") |
combat.morale.exempt |
MoraleCheckedEvent |
referee |
lambda event: ( f"Morale check for {event.subject} (ML {event.score}): no roll — " + ("they never check morale." if event.score == 12 else "they never fight.") ) |
combat.morale.held |
MoraleCheckedEvent |
referee |
lambda event: _morale(event, "they fight on") |
combat.save.auto |
SavingThrowRolledEvent |
player |
lambda event: f"{event.target_id} automatically saves versus {event.category}." |
combat.save.failed |
SavingThrowRolledEvent |
player |
lambda event: _save(event, "fails") |
combat.save.passed |
SavingThrowRolledEvent |
player |
lambda event: _save(event, "passes") |
combat.state.hit_points |
HitPointsReportedEvent |
referee |
lambda event: f"{event.target_id} is at {event.current_hp}/{event.max_hp} hit points." |
combat.targeting.selected |
TargetsSelectedEvent |
referee |
lambda event: f"Targets ({event.mode}): {', '.join(event.target_ids) or 'none'}." |
effects.*
| Code | Event | Default visibility | Default template |
|---|---|---|---|
effects.condition.gained |
ConditionGainedEvent |
player |
lambda event: f"{event.target_id} is {event.condition}." |
effects.condition.removed |
ConditionRemovedEvent |
player |
lambda event: f"{event.target_id} is no longer {event.condition}." |
effects.effect.attached |
EffectAttachedEvent |
referee |
lambda event: f"Effect {event.effect_id} ({event.kind}) attached to {event.target_ref}." |
effects.effect.expired |
EffectExpiredEvent |
referee |
lambda event: f"Effect {event.effect_id} ({event.kind}) on {event.target_ref} expires." |
effects.effect.released |
EffectReleasedEvent |
referee |
lambda event: ( f"Effect {event.effect_id} ({event.kind}) on {event.target_ref} is released." ) |
effects.effect.ticked |
EffectTickedEvent |
referee |
lambda event: f"Effect {event.effect_id} ({event.kind}) ticks on {event.target_ref}." |
effects.regeneration.revived |
MonsterRevivedEvent |
player |
lambda event: f"{event.target_id} regenerates and rises to fight again!" |
encounter.*
| Code | Event | Default visibility | Default template |
|---|---|---|---|
encounter.ended |
EncounterEndedEvent |
player |
lambda event: f"The encounter ends ({event.outcome})." |
encounter.evasion.pursuit |
EvasionEvent |
player |
lambda event: "The monsters give chase!" |
encounter.evasion.succeeded |
EvasionEvent |
player |
lambda event: "The party slips away — the encounter is evaded." |
encounter.exhaustion.gained |
ExhaustionEvent |
player |
lambda event: "The party is exhausted from running: -2 to attacks, damage, and AC." |
encounter.exhaustion.recovered |
ExhaustionEvent |
player |
lambda event: "The party catches its breath — exhaustion fades." |
encounter.npc_party.spawned |
NpcPartySpawnedEvent |
referee |
lambda event: ( f"An NPC party ({event.party_kind}, {event.alignment}) takes the field: " + ", ".join( f"{npc} ({cls} {level})" for npc, cls, level in zip(event.npc_ids, event.class_ids, event.levels, strict=True) ) + "." ) |
encounter.pursuit.caught |
PursuitEvent |
player |
lambda event: f"Pursuit round {event.round}: the monsters catch the party!" |
encounter.pursuit.distracted |
PursuitEvent |
player |
lambda event: ( f"Pursuit round {event.round}: the monsters stop for the dropped bait." ) |
encounter.pursuit.escaped |
PursuitEvent |
player |
lambda event: f"Pursuit round {event.round}: the party escapes." |
encounter.pursuit.round |
PursuitEvent |
player |
lambda event: f"Pursuit round {event.round}: the gap is {event.gap_feet}'." |
encounter.reaction.rolled |
ReactionRolledEvent |
referee |
lambda event: ( f"Reaction roll: {event.roll}{event.modifier:+d} = {event.total} — {event.result}." ) |
encounter.stance.changed |
StanceChangedEvent |
player |
lambda event: f"The monsters' bearing: {event.stance}." |
encounter.started |
EncounterStartedEvent |
player |
lambda event: ( f"Encounter: {event.count} × {event.monster_name} at {event.distance_feet}'" + (" — the party is surprised" if event.party_surprised else "") + (" — the monsters are surprised" if event.monsters_surprised else "") + "." ) |
encounter.surprise.rolled |
SurpriseRolledEvent |
referee |
lambda event: ( f"Surprise ({event.side}): " + (f"rolled {event.roll}" if event.roll is not None else "no roll") + f", surprised on 1-{event.threshold} — " + ("surprised." if event.surprised else "not surprised.") ) |
exploration.*
| Code | Event | Default visibility | Default template |
|---|---|---|---|
exploration.detection.rolled |
DetectionRolledEvent |
referee |
lambda event: ( f"Detection roll ({event.kind}" + (f", {event.character_id}" if event.character_id else "") + f"): {event.roll if event.roll is not None else 'no die'} vs {event.chance}-in-6 — " + ("success." if event.passed else "failure.") ) |
exploration.door.closed |
DoorEvent |
player |
lambda event: f"The door {event.direction} of ({event.x}, {event.y}) closes." |
exploration.door.forced |
DoorEvent |
player |
lambda event: ( f"{event.character_id} forces the door {event.direction} of ({event.x}, {event.y}) open." ) |
exploration.door.opened |
DoorEvent |
player |
lambda event: f"The door {event.direction} of ({event.x}, {event.y}) opens." |
exploration.door.stuck |
DoorEvent |
player |
lambda event: ( f"The door {event.direction} of ({event.x}, {event.y}) won't budge" + (f" — {event.character_id} strains in vain" if event.character_id else "") + "." ) |
exploration.door.swung_shut |
DoorEvent |
player |
lambda event: ( f"The door {event.direction} of ({event.x}, {event.y}) swings shut behind the party." ) |
exploration.door.unlocked |
DoorEvent |
player |
lambda event: ( f"{event.character_id} unlocks the door {event.direction} of ({event.x}, {event.y})." ) |
exploration.door.wedged |
DoorEvent |
player |
lambda event: ( f"An iron spike wedges the door {event.direction} of ({event.x}, {event.y})." ) |
exploration.fatigue.gained |
FatigueEvent |
player |
lambda event: "The party is fatigued: -1 to attack and damage until they rest." |
exploration.fatigue.recovered |
FatigueEvent |
player |
lambda event: "The party recovers from fatigue." |
exploration.item.acquired |
ItemAcquiredEvent |
player |
lambda event: ( f"{event.character_id} acquires " + (", ".join(event.item_ids) if event.item_ids else "") + (" and " if event.item_ids and event.coins_gp_value else "") + (f"{event.coins_gp_value} gp in coin" if event.coins_gp_value else "") + "." ) |
exploration.item.dropped |
ItemsDroppedEvent |
player |
lambda event: ( f"{event.character_id} drops " + (", ".join(event.item_ids) if event.item_ids else "") + (" and " if event.item_ids and event.coins_gp_value else "") + (f"{event.coins_gp_value} gp in coin" if event.coins_gp_value else "") + "." ) |
exploration.light.expired |
LightEvent |
player |
lambda event: ( f"The {event.source}" + (f" carried by {event.character_id}" if event.character_id else "") + " gutters out." ) |
exploration.light.extinguished |
LightEvent |
player |
lambda event: f"{event.character_id} extinguishes the {event.source}." |
exploration.light.failed |
LightEvent |
player |
lambda event: f"{event.character_id} fumbles with the tinder box — no flame." |
exploration.light.lit |
LightEvent |
player |
lambda event: f"{event.character_id} lights a {event.source}." |
exploration.listen.heard |
ListenedEvent |
player |
lambda event: ( f"{event.character_id} hears something beyond the {event.direction} door." ) |
exploration.listen.silent |
ListenedEvent |
player |
lambda event: f"{event.character_id} hears nothing beyond the {event.direction} door." |
exploration.location.entered |
LocationEnteredEvent |
player |
lambda event: ( f"The party enters {event.location_kind} {event.location_id}" + (f" (level {event.level_number})" if event.level_number is not None else "") + "." ) |
exploration.party.moved |
PartyMovedEvent |
player |
lambda event: f"The party moves to ({event.x}, {event.y}), facing {event.facing}." |
exploration.party.turned |
PartyMovedEvent |
player |
lambda event: f"The party turns to face {event.facing}." |
exploration.provisions.consumed |
ProvisionsEvent |
player |
lambda event: f"{event.character_id} consumes the day's {event.kind}." |
exploration.provisions.short |
ProvisionsEvent |
player |
lambda event: f"{event.character_id} has no {event.kind} for the day." |
exploration.rest.interrupted |
RestedEvent |
player |
lambda event: f"The party's {event.kind} rest is interrupted!" |
exploration.rest.rested |
RestedEvent |
player |
lambda event: f"The party rests ({event.kind})." |
exploration.search.found |
SearchCompletedEvent |
player |
lambda event: ( f"{event.character_id} searches ({event.kind}) and finds: {', '.join(event.found)}." ) |
exploration.search.nothing |
SearchCompletedEvent |
player |
lambda event: f"{event.character_id} searches ({event.kind}) and finds nothing." |
exploration.trap.found |
TrapEvent |
player |
lambda event: (event.character_id or "The party") + f" finds a trap ({event.trap_ref})." |
exploration.trap.removed |
TrapEvent |
player |
lambda event: ( (event.character_id or "The party") + f" removes the trap ({event.trap_ref})." ) |
exploration.trap.safe |
TrapEvent |
player |
lambda event: f"The known trap ({event.trap_ref}) does not go off." |
exploration.trap.sprung |
TrapEvent |
player |
lambda event: ( f"A trap springs ({event.trap_ref})" + (f" on {event.character_id}" if event.character_id else "") + "!" ) |
exploration.wandering.checked |
WanderingCheckEvent |
referee |
lambda event: ( f"Wandering check: {event.roll if event.roll is not None else 'skipped'} vs {event.chance}-in-6 — " + ("an encounter!" if event.encounter else "nothing comes.") ) |
items.*
| Code | Event | Default visibility | Default template |
|---|---|---|---|
items.curse.revealed |
CurseRevealedEvent |
player |
lambda event: ( f"{event.instance_id} reveals its curse ({event.template_id}) — {event.character_id} cannot be rid of it." ) |
items.device.activated |
ItemUsedEvent |
player |
lambda event: f"{event.character_id} activates {event.instance_id}." |
items.item.identified |
ItemIdentifiedEvent |
player |
lambda event: f"{event.instance_id} is identified: {event.template_id}." |
items.potion.drunk |
ItemUsedEvent |
player |
lambda event: f"{event.character_id} drinks {event.instance_id}." |
items.potion.mixed |
ItemUsedEvent |
player |
lambda event: ( f"{event.character_id} mixes potions — both effects cancel and sickness takes hold!" ) |
items.scroll.cursed |
ItemUsedEvent |
player |
lambda event: f"{event.character_id} looks upon {event.instance_id} — a curse takes hold!" |
items.scroll.read |
ItemUsedEvent |
player |
lambda event: f"{event.character_id} reads {event.instance_id} — the words disappear." |
magic.*
| Code | Event | Default visibility | Default template |
|---|---|---|---|
magic.book.added |
SpellBookUpdatedEvent |
player |
lambda event: f"{event.caster_id} adds {event.spell_id} to their spell book." |
magic.cast.cast |
SpellCastEvent |
player |
_cast |
magic.cast.disrupted |
SpellDisruptedEvent |
player |
lambda event: ( f"{event.caster_id}'s casting of {event.spell_id} is disrupted — the spell is lost." ) |
magic.cast.no_effect |
SpellCastEvent |
player |
_cast_no_effect |
magic.dispel.resolved |
MagicDispelledEvent |
player |
lambda event: ( f"{event.caster_id} dispels {len(event.released_effect_ids)} effect(s)" + (f"; {len(event.surviving_effect_ids)} survive(s)" if event.surviving_effect_ids else "") + "." ) |
magic.memorize.prepared |
SpellsMemorizedEvent |
player |
_memorized |
magic.memory.forgotten |
SpellForgottenEvent |
player |
lambda event: f"{event.caster_id} forgets {event.spell_id}." |
magic.turning.destroyed |
UndeadTurnedEvent |
player |
lambda event: _turning(event, "undead are destroyed") |
magic.turning.failed |
UndeadTurnedEvent |
player |
lambda event: _turning(event, "the turning fails") |
magic.turning.turned |
UndeadTurnedEvent |
player |
lambda event: _turning(event, "the undead are turned") |
session.*
| Code | Event | Default visibility | Default template |
|---|---|---|---|
session.flag.set |
FlagSetEvent |
referee |
lambda event: f"Flag {event.key} = {event.value!r}." |
session.game_over |
GameOverEvent |
player |
lambda event: f"The game is over: {event.reason}." |
session.monsters.spawned |
MonstersSpawnedEvent |
referee |
lambda event: ( f"Spawned {len(event.monster_ids)} × {event.template_id}: {', '.join(event.monster_ids)}." ) |
session.time.advanced |
TimeAdvancedEvent |
referee |
lambda event: f"Time advances {event.n} {event.unit}(s), to round {event.rounds_total}." |
session.xp.adventure_award |
AdventureXpAwardEvent |
player |
lambda event: ( f"The adventure ends: {event.monster_xp} XP from monsters and {event.treasure_xp} XP from treasure — " f"{event.share} XP to each of {len(event.survivors)} survivor(s)." ) |
session.xp.awarded |
XpAwardedEvent |
player |
lambda event: ( f"{event.character_id} gains {event.modified_award} XP (base {event.award}), now level {event.level_after}." ) |
town.*
| Code | Event | Default visibility | Default template |
|---|---|---|---|
town.healing.purchased |
HealingPurchasedEvent |
player |
lambda event: ( f"{event.character_id} purchases {event.service} at the temple for {event.cost_gp} gp." ) |
town.treasure.sold |
TreasureSoldEvent |
player |
lambda event: ( f"{event.character_id} sells {len(event.instance_ids)} valuable(s) for {event.gp_value} gp." ) |
treasure.*
| Code | Event | Default visibility | Default template |
|---|---|---|---|
treasure.hoard.generated |
HoardGeneratedEvent |
referee |
lambda event: ( f"Treasure generated at {event.cache_ref}" + (f" ({', '.join(event.treasure_types)})" if event.treasure_types else "") + f": {event.coins_gp_value} gp in coin, {len(event.valuable_ids)} valuable(s), " + f"{len(event.magic_item_ids)} magic item(s)." ) |
Template helpers
The named helpers referenced above, verbatim:
def _absorbed(event: DamageAbsorbedEvent) -> str:
by = f"{event.attacker_id}'s attack" if event.attacker_id else "The attack"
return f"{by} has no effect on {event.target_id}."
def _attack_auto(event: AttackRolledEvent) -> str:
return f"{event.attacker_id} strikes the helpless {event.defender_id} with {event.attack_name} — no roll needed."
def _attack_hit(event: AttackRolledEvent) -> str:
natural = " (natural 20)" if event.natural == 20 else ""
return (
f"{event.attacker_id} hits {event.defender_id} with {event.attack_name}: "
f"rolled {event.roll}{event.modifier:+d} = {event.total}, needing {event.required}{natural}."
)
def _attack_missed(event: AttackRolledEvent) -> str:
natural = " (natural 1)" if event.natural == 1 else ""
return (
f"{event.attacker_id} misses {event.defender_id} with {event.attack_name}: "
f"rolled {event.roll}{event.modifier:+d} = {event.total}, needing {event.required}{natural}."
)
def _cast(event: SpellCastEvent) -> str:
spell = f"{event.spell_id} (reversed)" if event.reversed else event.spell_id
at = f" at {', '.join(event.target_ids)}" if event.target_ids else ""
manual = " — the effect is narrated, not automated" if event.manual else ""
return f"{event.caster_id} casts {spell} [{event.mode}]{at}{manual}."
def _cast_no_effect(event: SpellCastEvent) -> str:
spell = f"{event.spell_id} (reversed)" if event.reversed else event.spell_id
return f"{event.caster_id} casts {spell} [{event.mode}] — it has no effect."
def _damage(event: DamageDealtEvent) -> str:
by = f" from {event.attacker_id}" if event.attacker_id else ""
return f"{event.target_id} takes {event.amount} damage{by}."
def _initiative(event: InitiativeRolledEvent) -> str:
rolled = ", ".join(f"{entry.key} {entry.total}" for entry in event.entries)
return f"Initiative ({event.mode}): {rolled}. Order: {', '.join(event.order)}."
def _memorized(event: SpellsMemorizedEvent) -> str:
prepared = ", ".join(f"{copy.spell_id} (reversed)" if copy.reversed else copy.spell_id for copy in event.prepared)
return f"{event.caster_id} memorizes: {prepared or 'nothing'}."
def _morale(event: MoraleCheckedEvent, outcome: str) -> str:
return f"Morale check for {event.subject} (ML {event.score}): rolled {event.roll}{event.modifier:+d} — {outcome}."
def _save(event: SavingThrowRolledEvent, outcome: str) -> str:
return (
f"{event.target_id} {outcome} a save versus {event.category}: "
f"rolled {event.roll}{event.modifier:+d}, needing {event.required}."
)
def _turning(event: UndeadTurnedEvent, outcome: str) -> str:
pool = f", {event.hd_pool} HD affected" if event.hd_pool is not None else ""
return f"{event.caster_id} presents the holy symbol (rolled {event.roll}{pool}) — {outcome}."