osrlib.crawl.views
The projection API: the player's safe whitelist and the referee's full state.
execute() mutates session state; build_player_view
and build_referee_view build these frozen
projections from that state alone, never from the event log.
The player view is an enumerated whitelist: party public sheets, location and facing, the mapped cells with their edges — walked cells, remembered seen cells the party's light has shown it, and what its light reveals right now (secret doors only if discovered — an undiscovered secret door renders as wall), known piles and emptied caches in explored space, active effects on party members with remaining durations, the elapsed clock, the mode, the journal (the appended beats verbatim, each with the clock position it landed at), the active quests with their revealed objectives, the current encounter/battle public state (names, counts, distances, visible conditions — never HP), fatigue/exhaustion/deprivation status, and the adventure's public prose. It never carries unexplored geometry, undiscovered traps or secret doors, monster HP or stat internals, referee-visibility roll outcomes, session flags, trigger fired-marks, referee notes, quest wiring (activation clauses, patterns, conditions, rewards, hidden objectives, inactive quests), RNG state, or the seed — the seed lives only in the save, and neither view carries it.
The referee view carries everything else the save does, minus RNG internals and the seed, for LLM referees and tests. A front end must never trust the client: a networked game keeps the session and the referee view server-side, and returns only the player view — or player-visibility events — over the wire.
EdgeView
EncounterGroupView
Bases: BaseModel
A monster group as the players see it: id, name, count, distance, behavior — never HP.
The group id is the command vocabulary: battle declarations name their
target_group_id with it, so the projection must carry it for a wire client
to fight at all — an allocator ordinal, not a secret (the id doctrine
MemberView already sets).
EncounterView
Bases: BaseModel
The current encounter or battle's public state.
Four id tuples — declarers, front_rank, immobile, and reloading —
describe the round's shape as the players know it at the table: who is able to
act, who stands close enough to swing, who is held fast, and who is still
cranking a windlass. Each one corresponds to a rejection the engine would
otherwise raise against the whole round, so a front end that reads all four can
offer only the declarations the engine will accept. Without them a front end
has to assume a rank width, and a wrong assumption costs the party its turn.
declarers
class-attribute
instance-attribute
Every member who must declare this round, in marching order: living and able
to act. A ResolveBattleRound naming
any other roster — a slept or paralysed member included — is rejected whole
(battle.declaration.roster_mismatch).
front_rank
class-attribute
instance-attribute
The living members close enough to attack in melee, in marching order — the
party's first rank at the current formation width, or every living member when
the formation_width_limit flag is off. A melee attack declared for anyone else
is rejected (battle.declaration.not_in_front_rank), and inside melee reach a
weapon that is both melee and missile counts as a melee weapon.
immobile
class-attribute
instance-attribute
The declarers who cannot move this round — entangled, in practice, since the
states that stop a move otherwise stop a declaration. Their close and
withdraw moves are rejected (battle.declaration.cannot_move).
reloading
class-attribute
instance-attribute
The members who may not fire a reload weapon this round, because they fired
one last round (combat.attack.reload). Empty when the ruleset's weapon_reload
flag is off, so a front end can combine this list with the weapon's own
qualities and need not read the flag at all.
ExploredLevelView
MemberEffectView
MemberView
ObjectiveView
Bases: BaseModel
One revealed objective as the players know it: what it is called, and whether it is done.
Hidden objectives have no view at all — an objective nobody has been told about
is absent from the list, not listed as unknown — so state needs only the two
values a visible objective can be in.
name
instance-attribute
name: str
The objective's display label: its authored name, or its id when the
document authors none — never empty, because the view's job is what it is
called.
PileView
PlayerView
Bases: BaseModel
The safe projection: an enumerated whitelist of exactly the fields a player may see.
journal
instance-attribute
journal: tuple[JournalEntry, ...]
The session journal, shipped as written: the players' own record of the adventure, in order of discovery, each beat carrying the clock position it landed at. The wiring behind the beats — trigger fired-marks, referee notes — stays out.
quests
instance-attribute
The quests in play, in the order the adventure authored them: active ones only. A quest nobody has taken on yet is not the party's business, and a finished one leaves the list — its record is the journal, which keeps every beat it wrote.
QuestView
Bases: BaseModel
One active quest as the players know it: the charge, who gave it, and where it stands.
narrative is the quest's authored offer beat and speaker its attribution,
both empty when unauthored: a wire client holds no adventure document to resolve
either from, so the projection carries the words themselves. The wiring that
starts a quest, checks it off, and pays it — clauses, patterns, conditions,
rewards — never appears; that is the game's secret exactly as a trigger's is.
objectives
instance-attribute
objectives: tuple[ObjectiveView, ...]
The revealed objectives, in the order the quest authored them.
RefereeView
build_player_view
build_player_view(session) -> PlayerView
Build the player view from session state (never from the event log).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
GameSession
|
The running session. |
required |
Returns:
| Type | Description |
|---|---|
PlayerView
|
The frozen whitelist projection. |
build_referee_view
build_referee_view(session) -> RefereeView
Build the referee view: everything but RNG internals and the seed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
GameSession
|
The running session. |
required |
Returns:
| Type | Description |
|---|---|
RefereeView
|
The full-state projection. |