Story
Recurring world activities
Three activities keep the world open after Act 4 (Story Bible section 1: no endgame): the Proving Ring ladder, caravan jobs and warp-born glyph hunts. Each runs on its own flags and its own board or clock.
The Proving Ring ladder
The Ring in Halfway's old quarry, inside the truce stones, is the one place there where casting is allowed, under ring wards that make every spell pull its punches. It is Codex section 10's designated PvP place, and until there are servers it runs a ladder of NPC bouts. The Ring pays only a ladder place and standing: never copper, never items (the bestiary's ring_token is dropped; Ring bouts drop nothing). Bouts give the bestiary's XP. Ringmaster Ulla Stroud keeps the card. Yarn file: Dialogue/Side/ring.yarn.
How a bout is picked. The player reads the Ring Card (board ring_card, at Mark_ulla): ten places, the player's name at the bottom (10th), the nine names above with their rank and side. Tapping Challenge on an open name starts that bout. Each first win over a name moves the player up one place. A loss costs nothing: the wards stop the bout (canLose: true), and the player can challenge again.
| Rung | Opponent | Encounter | Opens when | Pay on first win |
|---|---|---|---|---|
| 1–3 | The Ring golem, ranks I, II, III (ring_golem), in order | ring_rank_1, _2, _3 (bestiary) | act1.stage >= 6 and seen.ring != 0 | the place only |
| 4–6 | Cadet Orrin Tey, a Warden cadet: Repel and Brace | ring_card_cadet | act1.stage >= 7 and ring.rank >= 3 | rep.wardens +5 |
| Ketter, a Facet duellist of the Crown cut: Bevel Lash | ring_card_duellist | same | rep.facets +5 | |
| Faye Linnet, a Waymaker who casts only Gale and won't teach it to anyone | ring_card_waymaker | same | rep.waymakers +5 | |
| 7–8 | Orrin again, back from Twinhold's yard: adds Tally | ring_court_cadet | twinhold.stage >= 1 and ring.card.cadet != 0 | rep.evane +5 |
| Ketter again, back from Lanternfall: adds Facet Seal | ring_court_duellist | lanternfall.stage >= 1 and ring.card.duellist != 0 | rep.facets +5 | |
| 9 | Ringmaster Ulla Stroud, threads from both sides | ring_ulla | act2.done != 0 and ring.rank >= 8 | rep.evane +5 and rep.facets +5; title Ring champion (ring.champion 1) |
The player's place on the card is 10 − ring.rank: 10th with no wins, 1st after Ulla. Within rungs 4–6 and 7–8 the order is the player's. Faye is the Act 1 seed for parallel casting: the player sees Gale drawn before the Long Road. Act 2's hook ("new opponents trained in each court") is rungs 7 and 8.
After Act 4. Act 4's Pane floor opens (ring.floor 2: a mirror slab where the Pane rule applies), and the Ring runs seasons, quarterly, alternating floors. Each season brings three seasonal challengers as server data (Data/Ring/<season>.json, no app update) on a season card beside the ladder; ring.season is the season number the player last fought in and ring.season.wins counts that season's wins (0–3). Winning all three in a season gives the title Season champion and rep.evane +5 and rep.facets +5, at most once a season.
The PvP link. When servers exist (Codex section 10: PvP only in the Ring, no co-op, scheduled tournaments with a leaderboard, server-side checks that the drawing is human), the Ring Card gains a Players tab. Being Ring champion (ring.champion 1) qualifies a player for player bouts and the scheduled tournaments. Player bouts pay a leaderboard place and nothing else; a loss takes nothing; the wards still stop every bout. The NPC ladder stays for offline play and as the way in.
Flags. ring.rank (0–9, wins over distinct names; the Game Screens tab reads it), ring.card.cadet, ring.card.duellist, ring.card.waymaker, ring.court.cadet, ring.court.duellist (1 once beaten), ring.champion, ring.floor (1 sand, 2 Pane), ring.season, ring.season.wins.
New opponents for the bestiary. The six Ring Card challengers (ring_cadet, ring_duellist, ring_waymaker, ring_cadet_2, ring_duellist_2, ring_ulla) are in the Bestiary under "Named opponents", with their HP and kits.
{
"id": "side_ring_ladder",
"title": "The Ring Card",
"description": "Ringmaster Ulla keeps a card of everyone who has stood on the sand. Your name goes at the bottom. The Ring pays in your place and what people think of you, and nothing else.",
"category": "side",
"giver": "ulla",
"board": "ring_card",
"startWhen": { "all": [
{ "flag": "seen.ring", "op": "!=", "value": 0 },
{ "flag": "act1.stage", "op": ">=", "value": 6 } ] },
"stages": [
{ "id": "golems", "text": "Beat the Ring golem at ranks I, II and III.",
"completeWhen": { "flag": "ring.rank", "op": ">=", "value": 3 } },
{ "id": "card", "text": "Beat the three Ring Card challengers: the Warden cadet, the Facet duellist and the Waymaker.",
"completeWhen": { "all": [
{ "flag": "ring.card.cadet", "op": "!=", "value": 0 },
{ "flag": "ring.card.duellist", "op": "!=", "value": 0 },
{ "flag": "ring.card.waymaker", "op": "!=", "value": 0 } ] } },
{ "id": "courts", "text": "Beat the cadet and the duellist again, now they have trained in their courts.",
"completeWhen": { "all": [
{ "flag": "ring.court.cadet", "op": "!=", "value": 0 },
{ "flag": "ring.court.duellist", "op": "!=", "value": 0 } ] } },
{ "id": "ulla", "text": "Ask Ulla for the top of the card.",
"completeWhen": { "flag": "ring.champion", "op": "!=", "value": 0 } }
]
}
Yarn: Side_Ring_Card (reading the card), Side_Ring_Challenge, Side_Ring_BoutGolem, Side_Ring_BoutCadet, Side_Ring_BoutDuellist, Side_Ring_BoutWaymaker, Side_Ring_BoutCadetCourt, Side_Ring_BoutDuellistCourt, Side_Ring_BoutUlla, Side_Ring_Result, Side_Ring_PaneFloor, Side_Ring_Season.
Caravan jobs
Dace's Waymakers carry anyone and anything, for whoever pays, which the other four factions resent. From Act 2 the player can ride guard on their runs between Halfway, Twinhold and Lanternfall. It is the steady side income of the game, and the Long Road run always crosses the wind pass, so it always ends in the recurring caravan_defence fight. Yarn file: Dialogue/Side/caravan.yarn.
How a run is picked. Runs are posted on Dace's caravan board (board caravan_board) at Twinhold's Far Gate yard and Lanternfall's Sand Gate yard (Event_caravan_yard), and Halfway's Truce Board carries the runs that leave Halfway. Each in-game day a board posts up to three runs leaving from its town, drawn from the route table below for that town; one of the three is always passengers. The player takes one (Take on the Notice boards screen); one run at a time, and while a run is under way every board says "You've a wagon waiting." Boards open once the first caravan job is done (long_road.stage >= 5), and a board posts nothing for a player Shunned by the Waymakers (rep.waymakers <= -60: "They won't take your work.").
| Route | Between | Fight on the way | Pay in Act 2 | Pay from Act 3 |
|---|---|---|---|---|
| The Pale Road | Halfway and Twinhold | one roll: road_glints; from Act 3 sallow_road_glints or sallow_road_winged; warden_enforcers instead if the player is Distrusted by the Evane | 80 | 150 |
| The Amber Road | Halfway and Lanternfall | one roll: road_glints or edge_boar; from Act 3 shard_pack or hunter_ambush | 80 | 150 |
| The Long Road | Twinhold and Lanternfall, over the wind pass | caravan_defence, every run (three waves; wagon HP as the protect objective from Act 2 scene 2.5) | 150 | 250 |
| The north rim (after Act 4) | The Heart Pane's north rim and Lanternfall or Twinhold | inner_glints (Act 4's encounter); Act 4's "the last wagon, and the next" | 250 | |
| Even-handed letters (after Act 4) | Twinhold and Lanternfall, sealed letters between the courts | caravan_defence | 250 |
- Cargo follows the direction, as Act 2 has it: towards Lanternfall, Evane grain and mirror-polish; towards Twinhold, salvaged shard-glass and lenses; to and from Halfway, both; passengers on every route. Even-handed letters are posted only for an Even-handed player (
rep.evane >= 25andrep.facets >= 25), Act 4's "carrying letters between the courts". - Pay by standing. The pay above moves with the player's standing with the side that receives the cargo (Twinhold:
rep.evane; Lanternfall:rep.facets; Halfway: no change), the Halfway Rows' bands turned round: Trusted +10%, Neutral as listed, Distrusted −15%, Shunned −30%. Trusted with the Waymakers (rep.waymakers >= 25) adds 10% more. A run has three wagons; each one lost takes 25% off. Rounded down to the copper. - Failing. If the player loses the fight, the wagons turn back and nobody is paid; nothing else is lost ("Roads are long."). Fleeing counts as losing.
- Standing. Each finished run:
rep.waymakers+5, for the first five runs only. Every fifth run Dace has a milestone line and a gift: the 5th awaymaker_band, the 10th a second one (a matched pair), the 15th 3breath_tonic, then Dace's Endless Caravan stories, one each fifth run.
The first job, in Act 1. Act 1's Truce Board hook "escort a Waymaker wagon to the milestone and back" is the trial run, before Dace: Jory's wagon, side_milestone_run.
{
"id": "side_milestone_run",
"title": "To the Milestone and Back",
"description": "Jory's wagon needs a pair of hands as far as the milestone and back. There are glints on the road, and Waymakers carry. That's the whole of it.",
"category": "side",
"giver": "jory",
"board": "truce_board",
"postWhen": { "flag": "act1.stage", "op": ">=", "value": 2 },
"startWhen": { "flag": "side.milestone_run.stage", "op": ">=", "value": 1 },
"stages": [
{ "id": "wagon", "text": "Meet Jory's wagon at Halfway's Bridge Gate.",
"completeWhen": { "flag": "side.milestone_run.stage", "op": ">=", "value": 2 } },
{ "id": "milestone", "text": "Walk the wagon down the Sallow Road to the milestone and back.",
"completeWhen": { "flag": "side.milestone_run.stage", "op": ">=", "value": 3 } },
{ "id": "pay", "text": "Collect your pay from Jory.",
"completeWhen": { "flag": "side.milestone_run.stage", "op": ">=", "value": 4 } }
]
}
It pays 40 copper, fights road_glint (3 glint) at the milestone, Road_1, and gives rep.waymakers +5. If met.jory, Jory remembers the lift. Yarn: Side_Halfway_JoryNotice, Side_Road_JoryWagon, Side_Road_MilestoneGlints, Side_Halfway_PimPaid.
A sample job. Generated runs use the quest shape with job fields added ("category": "job"), so the Journal and boards read them like any side quest. This is one posted on the Twinhold yard's board.
{
"id": "job_long_road_grain",
"title": "Grain over the Pass",
"description": "Three wagons of Evane grain for Lanternfall's bakers. Dace doesn't care who eats it.",
"category": "job",
"giver": "dace",
"board": "caravan_board",
"route": "long_road",
"from": "twinhold",
"to": "lanternfall",
"cargo": "grain",
"wagons": 3,
"encounter": "caravan_defence",
"pay": { "act2": 150, "act3": 250, "standing": "rep.facets", "waymakers": "rep.waymakers", "perWagonLost": 0.25 },
"postWhen": { "all": [
{ "flag": "long_road.stage", "op": ">=", "value": 5 },
{ "flag": "rep.waymakers", "op": ">=", "value": -59 } ] },
"startWhen": { "flag": "caravan.leg", "op": ">=", "value": 1 },
"stages": [
{ "id": "load", "text": "Meet the wagons at Twinhold's Far Gate yard.",
"completeWhen": { "flag": "caravan.leg", "op": ">=", "value": 2 } },
{ "id": "pass", "text": "Get the wagons over the wind pass.",
"completeWhen": { "flag": "caravan.leg", "op": ">=", "value": 3 } },
{ "id": "deliver", "text": "Bring the grain down to Lanternfall's Sand Gate yard and collect your pay.",
"completeWhen": { "flag": "caravan.leg", "op": ">=", "value": 4 } }
]
}
Flags. Per run, set when a run is taken: caravan.route (1 Pale Road, 2 Amber Road, 3 Long Road, 4 north rim, 5 Even-handed letters), caravan.cargo (1 grain, 2 mirror-polish, 3 shard-glass, 4 lenses, 5 passengers, 6 sealed letters), caravan.leg (1 taken, 2 set off, 3 fight won, 4 arrived and paid) and caravan.wagons_lost (0–2). Running totals that only rise: caravan.runs (finished runs) and caravan.failed. Note for the Lead: the four per-run flags are the one place in this tab where a flag goes back to 0, because Take resets them for the next run. The Journal must store a finished job as finished (the save's finished-quest list) so the reset can't reopen it.
Yarn: Side_Caravan_Board, Side_Caravan_Take, Side_Caravan_SetOff, Side_Caravan_Leg (starts the route's fight), Side_Caravan_Arrive (pay), Side_Caravan_TurnBack, Side_Caravan_DaceMilestone, Side_Caravan_EvenHanded.
Warp-born glyph hunts
The third recurring world activity. A fresh warp opens, a warp-born glyph surfaces at its lip and fades within days (Story Bible section 3), Facet glyph-hunters race the player for it, and Warden menders come to seal it. Act 4's "world after" makes warp-born glyphs the Living Spell Library's main channel (walkthrough-act-4.md, section 9). This section turns that into a rolled, timed activity. Crown Surge at the Sallow warp in Act 3 (scene 1.3) is the first warp-born glyph and stays a scripted scene; hunts start after it.
Flags
| Flag | Values | What it is |
|---|---|---|
world.day | 0 up | In-game day counter, +1 at each in-game dawn. Sleeping (farm, inn, Aske's fire) moves to the next dawn. New. |
hunt.open | 0–3 | How many fresh warps are open now. |
hunt.<id>.phase | 0–6 | The warp's own clock (table below). Set by the hunt controller each dawn; never goes backwards. |
hunt.<id>.stage | 0–3 | The player's progress: 1 reached the site, 2 guardian beaten, 3 glyph traced. |
hunt.<id>.result | 0–4 | 1 sealed, 2 shared, 3 hoarded, 4 missed (faded, dug or sealed without the player). |
hunt.count, hunt.sealed, hunt.shared, hunt.hoarded, hunt.missed | 0 up | Running tallies for the profile and for NPC lines ("You're the one who keeps sealing them"). |
spell.learned.<id> | 1 | As for any glyph. |
How a hunt is rolled
Hunts start once Act 3 is over (act3.done != 0). At each in-game dawn, if fewer warps are open than the cap, the hunt controller rolls once:
| World state | Chance per dawn | Max open | Sites | Glyph kinds |
|---|---|---|---|---|
Act 4, before the outcome (act3.done != 0, act4.stage < 8) | 15% | 1 | Any site except the Pane's | Any |
Mended (act4.outcome == 1) | 5% | 1 | Mending scars only: the Sallow warp, Corran's hairline, Saltglass, the Pane's centre | Mirrored and parallel. Asymmetric only at the Undermere site, and only once dark.known is set |
Shattered (act4.outcome == 2) | 40% | 3 | Any, plus the Pane's ring | Every kind; each guardian adds a glint_brute |
Held (act4.outcome == 3) | 20% | 2 | Any, plus the rim (rim_warp) | Every kind; the Pane at dawn shows a new reflected glyph now and then |
- Site: a weighted pick from the site table below. It is never the last site used, never in the region the player is standing in (so a hunt means a trip), and never in a region they haven't reached.
- Glyph: Crown Surge shows at every fresh warp's lip until the player has learned it, and again for anyone whose Crown Surge has been sealed (the spell roadmap's "resurfaces at every fresh warp"). In the Mended world it shows only at the Undermere site. Each warp also takes one pick from the warp-born pool, which is server data (Codex section 11), so new spells need no app update. If the pool has nothing the player lacks, the warp leaves
glyph_dustinstead. - Fixed windows: a server file (
Data/Warps/<id>.jsonwith real dates, Act 4's "7 days of real time" first guess) overrides the roll for special, world-wide warps. Rolled hunts run on in-game days.
| Region | Site id | Where | Near a town |
|---|---|---|---|
| 1. The Sallow | steps_lip | The Drowned Steps, under the water ("light on the water at the Drowned Steps") | yes (Sallowbank) |
| 2. The Long Road | pass_cliff | The wind pass cliff warp | yes (the camp) |
| 3. Twinhold and Greenvault | orchard_crack | Greenvault's old orchard outside the walls | yes (Greenvault) |
| 4. Hushfold and the Hour Stair | gorge_lip | The Hour Stair gorge, below the archive window | no |
| 5. The Shardfield | lakebed_lip | The cracked lakebed, past the storm shelters | no |
| 6. Corran | corran_hairline | Corran's hairline warp, the north edge | yes (Corran) |
| 7. The Undermere | warp_root | The warp root under Corran (the Mended world's "dark") | yes (the den) |
| 8. The Heart Pane | inner_ring, rim_warp, pane_ring | The inner-ring path; the rim (Held); the ring of pieces (Shattered) | no |
Timing (in-game days)
| Day | phase | What happens |
|---|---|---|
| 0 | 1 | The warp opens. A rumour goes up on the two nearest boards. |
| 1 | 2 | The glyph surfaces at the lip at dawn. The guardian is on site. |
| 2 | 3 | Facet glyph-hunters arrive and start digging. |
| 3 | 4 | Warden menders arrive and start setting seal-stones. |
| 4 | 5 | At dusk the glyph is gone: faded, dug out by the hunters, or sealed in by the menders' ring. glyph_dust is left at the lip. |
| 6 | 6 | The warp closes to a scar. |
In the Shattered world the menders still come on day 3 but fail (Ondine's crews "can mend nothing"), so the warp stays open after day 6 and spills glints into the nearest town once a week (hunt_spill) until someone seals it. In the Mended world the hunters only come at the Undermere site.
The race
- Day 1: only the guardian.
- Day 2: the hunters are digging. Talk (share the glyph with them), wait them out, or fight (
hunt_rival_hunters). If the player let Sabe's cut go at the Sallow warp (act3.hunters= 1), the hunters are Sabe's cut, and they wait for the player. If the player hurt them (act3.hunters= 3) and they've left the Undermere, they don't wait. Anyone else is the Crown cut, named for the glyph they chase. - Day 3: the menders are setting stones. Talk (seal it with them), fight (
hunt_menders), or trace inside the closing ring before it shuts (a timed trace).
Seal it, share it, hoard it
| Choice | What the player does | Moves |
|---|---|---|
| Seal | Close the warp with the menders, or alone with a mirrored field cast (Brace across the lip, as Aske did at Corran). The glyph goes with the warp, so trace it first if you want it. | rep.wardens +5; rep.facets −5 if hunters were on site; morality +5 if the site is near a town |
| Share | Trace it, then hold the guardian off while the hunters trace it too, or send word to the Giving Steps so anyone can come. The warp stays open until it fades. | rep.facets +5. If the site is near a town, glints spill into it that night (hunt_spill); morality −5 unless the player stays and fights them |
| Hoard | Trace it, then break the lip (Bevel Lash or Deep Cut on the warp's edge) so it fades for everyone, or run the hunters off. | rep.facets −10, morality −5; 2 × glyph_dust |
| Missed | Arrive after day 4. | 1 × glyph_dust at the lip |
Each result adds 1 to its tally and to hunt.count. A hunt can also yield the glyph itself, Crown Surge, the guardian's materials (mirror_grit, glint_quicksilver), and from humans who yield (canon rule 5) facet_token from hunters and evane_silver from menders. Glints never drop copper.
Guardians
| Region | Encounter (new) | Enemies |
|---|---|---|
| 1. The Sallow | hunt_guardian_sallow | 5 glint + glint_brute |
| 2. The Long Road | hunt_guardian_road | 3 dust_glint + 2 winged_glint |
| 3. Twinhold and Greenvault | hunt_guardian_lowlands | 4 glint + glint_brute |
| 4. Hushfold and the Hour Stair | hunt_guardian_highlands | 4 frost_glint + echo_owl |
| 5. The Shardfield | hunt_guardian_shardfield | 4 shard_glint + shardshell_crab |
| 6. Corran | hunt_guardian_corran | 3 stilled_glint + 2 winged_glint |
| 7. The Undermere | hunt_guardian_undermere | 4 roof_glint + drowned_chorister |
| 8. The Heart Pane | hunt_guardian_pane | sky_shoal + shard_sentinel |
Rivals: hunt_rival_hunters (2 glyph_hunter), hunt_menders (warden_menders). Spill: hunt_spill (4 glint + glint_brute, at the town).
Letters from Twinhold (Shattered)
This is Act 4's "Letters from Twinhold" hook, run as hunts. The first letter is the quest Letters from Twinhold (side_twinhold_letters, region 3); every letter after it opens a hunt. Every 28 in-game days in the Shattered world, an unsigned letter in Ondine's hand reaches the farm (letter_unsigned) naming a place where her crews failed to close a warp. It opens a hunt there at phase 1. The hunters don't know about it, because Facets don't read Ondine's letters, so the player gets a two-day head start. Sealing one of these sends no reply, but the next letter is shorter.
Yarn
Dialogue/Side/hunts.yarn, each node reading $hunt_id: Side_Hunt_Rumour (board notice), Side_Hunt_Arrive, Side_Hunt_Guardian_After, Side_Hunt_Hunters (with _Sabe and _CrownCut variants), Side_Hunt_Menders, Side_Hunt_Seal, Side_Hunt_Share, Side_Hunt_Hoard, Side_Hunt_Faded, Side_Hunt_Spill, Side_Hunt_OndineLetter.
Sample hunt: light on the lakebed
The warp file, Data/Warps/lakebed_lip.json (for a rolled hunt the controller writes openedDay; a server-delivered one carries dates instead):
{
"id": "lakebed_lip",
"region": "shardfield",
"site": { "location": "shardfield", "marker": "Event_warp_lakebed" },
"rumour": "Light on the cracked lakebed, two shelters past the Corran road marker.",
"boards": ["lanternfall_board", "truce_board"],
"glyphs": ["crown_surge"],
"poolPicks": 1,
"guardian": "hunt_guardian_shardfield",
"rivals": { "hunters": "hunt_rival_hunters", "menders": "hunt_menders" },
"window": { "unit": "world.day", "surface": 1, "hunters": 2, "menders": 3, "fade": 4, "close": 6 },
"nearTown": false,
"outcomes": [0, 2, 3]
}
outcomes lists the act4.outcome values the site can roll in (0 = before the outcome). The lakebed isn't a mending scar, so it never rolls in the Mended world.
Its quest, Data/Quests/hunt_lakebed_lip.json, which joins the Journal when the rumour is read:
{
"id": "hunt_lakebed_lip",
"title": "Light on the Lakebed",
"description": "A fresh warp has opened on the cracked lakebed. Whatever surfaces at its lip won't last the week, and you won't be the only one looking.",
"category": "hunt",
"giver": "lanternfall_board",
"board": "lanternfall_board",
"startWhen": { "flag": "hunt.lakebed_lip.phase", "op": ">=", "value": 1 },
"stages": [
{
"id": "reach",
"text": "Get to the cracked lakebed, past the storm shelters, before the glyph fades.",
"completeWhen": { "flag": "hunt.lakebed_lip.stage", "op": ">=", "value": 1 }
},
{
"id": "guardian",
"text": "Beat what came out of the warp.",
"completeWhen": { "flag": "hunt.lakebed_lip.stage", "op": ">=", "value": 2 }
},
{
"id": "trace",
"text": "Trace the glyph at the warp's lip while it shows.",
"completeWhen": {
"any": [
{ "flag": "hunt.lakebed_lip.stage", "op": ">=", "value": 3 },
{ "flag": "hunt.lakebed_lip.phase", "op": ">=", "value": 5 }
]
}
},
{
"id": "decide",
"text": "Seal the warp, share the glyph, or keep it to yourself.",
"completeWhen": { "flag": "hunt.lakebed_lip.result", "op": "!=", "value": 0 }
}
]
}
If the player never comes, the controller sets result = 4 at phase 5 and the quest closes as missed.