Linking things together
Which field joins what to what, and which joins are not checked for you.
The spatial spine
biome -> area -> point of interest -> dungeon| Biome | A theme. Supplies room templates, encounter tables, ambience, palette. |
| Area | Belongs to one biome. Joined to other areas by connections. |
| Point of interest | Belongs to one area. A place inside it you can go. |
| Dungeon | Hangs off a place through poi.dungeon. Does not replace the place. |
A place whose area does not exist never appears. Travel needs a declared connection.
A road is two entries, one on each area. oneWay is read on the destination's entry, so listing a road both ways gives a two way road.
Placing a person
Two fields, both work. npc.home names a place. poi.residents lists people. Pick one and stay with it.
Offering a quest
npc.offersQuests is what puts a job in front of a player.A quest can begin in one of four ways. At least one must be true:
- An NPC lists it in
offersQuests. autoStartis set.- Another quest
unlocksit. - An effect emits
startQuestfor it.
Chaining quests
Four pieces. All four are needed.
- Only the first link is in an NPC's
offersQuests. - Each later link
requiresthe previous one complete. - Each link but the last
unlocksthe next. - The level floor sits on the first link only.
{ "id": "mill_1", "unlocks": ["mill_2"],
"requires": { "minLevel": 3 } }
{ "id": "mill_2", "unlocks": ["mill_3"],
"requires": { "quests": [ { "quest": "mill_1", "status": "complete" } ] } }Dialogue
npc.dialogue names a dialogue. The dialogue never names the NPC. A dialogue nothing points at can never be opened.Inside a dialogue, five fields name a node, and only nodes in that same dialogue:
start · option.goto · check.onSuccess · check.onFailure · redirectWhen[].goto
option.effects run on choosing the option, whatever option.check then rolls. Put anything that depends on the roll on the success node's onEnter.Options are tested against what the speaker knows, not what is true.
Objectives
kill | A death whose statblock id is target. |
collect | Gaining the item named by target. |
reach | Entering a map, firing a trigger, opening a gate, or a custom event. |
talk | Starting a conversation with target. |
custom | Your own when predicate. Required for this kind. |
On the first four kinds, when is an extra condition the event must also pass. It is never a second way to complete.
objective.target is a bare id, not a checked reference. A typo passes validation and the objective never completes. The same applies to condition.prevents, condition.implies, sense.ignores, and dungeon.guaranteedRoles. The studio has a rule for the first of these.Flags
A flag is a free string. Nothing checks that the thing reading it and the thing writing it agree on the spelling. The studio does, with flag_never_set and flag_writer_unreachable.
The engine writes these itself. You can read all of them:
found:<poi> a hidden place has been discovered
seen:<map>:<room> a room description has been shown
gate:<id>:open a gate stands open
gate:<id>:tried a bypass with no retry has been failed
said:<dialogue>:<node>:<option> a once only option has been taken
quest:<quest>:<objective>:count counted objective progress
ending:<arc> an ending arc has been reachedLore
- A
learnLoreeffect is the only thing that teaches lore. - A
loreThreadgroups entries. Read it asthreads.<id>.known. requirement.loregates on it.
Lore no effect teaches is reported as unlearnable_lore.
Deeds
Three things record a deed:
quest.remembersAswhen a quest finishes.dialogueNode.rememberswhen a line is reached.- An
emiteffect anywhere.
npc.caresAbout lists the kinds a person takes personally. Those fade slower in their memory. The memory model decides who saw it, who they told, and how the story changed on the way.
Arcs
An arc groups quests. Read it as arcs.<id>. Finishing an arc marked isEnding ends the run, unless start.postVictory is continue.
The whole graph
npc ──dialogue──> dialogue ──(node ids only, never global)──> node
│ │ │
│ │ └──offersQuests──> quest ──unlocks──> quest ──> arc ──isEnding──> the end
│ │ │
│ │ ├──rewards.items──> item
│ │ ├──rewards.reputation──> faction
│ │ └──remembersAs──> deedKind
│ │
│ ├──statblock──> monster ──loot──> lootTable ──> item
│ ├──faction──> faction ──relations──> faction
│ ├──caresAbout──> deedKind
│ └──home──> point of interest <──residents── point of interest
│ │
│ ├──area──> area ──biome──> biome
│ ├──gate──> gate
│ └──dungeon──> dungeon ──biome──> biome
effect learnLore ──> lore <──entries── loreThreadEvery arrow is a checked reference except the ones named above.