The Velan Codex

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.

RungOpponentEncounterOpens whenPay on first win
1–3The Ring golem, ranks I, II, III (ring_golem), in orderring_rank_1, _2, _3 (bestiary)act1.stage >= 6 and seen.ring != 0the place only
4–6Cadet Orrin Tey, a Warden cadet: Repel and Bracering_card_cadetact1.stage >= 7 and ring.rank >= 3rep.wardens +5
Ketter, a Facet duellist of the Crown cut: Bevel Lashring_card_duellistsamerep.facets +5
Faye Linnet, a Waymaker who casts only Gale and won't teach it to anyonering_card_waymakersamerep.waymakers +5
7–8Orrin again, back from Twinhold's yard: adds Tallyring_court_cadettwinhold.stage >= 1 and ring.card.cadet != 0rep.evane +5
Ketter again, back from Lanternfall: adds Facet Sealring_court_duellistlanternfall.stage >= 1 and ring.card.duellist != 0rep.facets +5
9Ringmaster Ulla Stroud, threads from both sidesring_ullaact2.done != 0 and ring.rank >= 8rep.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.").

RouteBetweenFight on the wayPay in Act 2Pay from Act 3
The Pale RoadHalfway and Twinholdone roll: road_glints; from Act 3 sallow_road_glints or sallow_road_winged; warden_enforcers instead if the player is Distrusted by the Evane80150
The Amber RoadHalfway and Lanternfallone roll: road_glints or edge_boar; from Act 3 shard_pack or hunter_ambush80150
The Long RoadTwinhold and Lanternfall, over the wind passcaravan_defence, every run (three waves; wagon HP as the protect objective from Act 2 scene 2.5)150250
The north rim (after Act 4)The Heart Pane's north rim and Lanternfall or Twinholdinner_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 courtscaravan_defence250

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

FlagValuesWhat it is
world.day0 upIn-game day counter, +1 at each in-game dawn. Sleeping (farm, inn, Aske's fire) moves to the next dawn. New.
hunt.open0–3How many fresh warps are open now.
hunt.<id>.phase0–6The warp's own clock (table below). Set by the hunt controller each dawn; never goes backwards.
hunt.<id>.stage0–3The player's progress: 1 reached the site, 2 guardian beaten, 3 glyph traced.
hunt.<id>.result0–41 sealed, 2 shared, 3 hoarded, 4 missed (faded, dug or sealed without the player).
hunt.count, hunt.sealed, hunt.shared, hunt.hoarded, hunt.missed0 upRunning tallies for the profile and for NPC lines ("You're the one who keeps sealing them").
spell.learned.<id>1As 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 stateChance per dawnMax openSitesGlyph kinds
Act 4, before the outcome (act3.done != 0, act4.stage < 8)15%1Any site except the Pane'sAny
Mended (act4.outcome == 1)5%1Mending scars only: the Sallow warp, Corran's hairline, Saltglass, the Pane's centreMirrored and parallel. Asymmetric only at the Undermere site, and only once dark.known is set
Shattered (act4.outcome == 2)40%3Any, plus the Pane's ringEvery kind; each guardian adds a glint_brute
Held (act4.outcome == 3)20%2Any, plus the rim (rim_warp)Every kind; the Pane at dawn shows a new reflected glyph now and then
RegionSite idWhereNear a town
1. The Sallowsteps_lipThe Drowned Steps, under the water ("light on the water at the Drowned Steps")yes (Sallowbank)
2. The Long Roadpass_cliffThe wind pass cliff warpyes (the camp)
3. Twinhold and Greenvaultorchard_crackGreenvault's old orchard outside the wallsyes (Greenvault)
4. Hushfold and the Hour Stairgorge_lipThe Hour Stair gorge, below the archive windowno
5. The Shardfieldlakebed_lipThe cracked lakebed, past the storm sheltersno
6. Corrancorran_hairlineCorran's hairline warp, the north edgeyes (Corran)
7. The Undermerewarp_rootThe warp root under Corran (the Mended world's "dark")yes (the den)
8. The Heart Paneinner_ring, rim_warp, pane_ringThe inner-ring path; the rim (Held); the ring of pieces (Shattered)no

Timing (in-game days)

DayphaseWhat happens
01The warp opens. A rumour goes up on the two nearest boards.
12The glyph surfaces at the lip at dawn. The guardian is on site.
23Facet glyph-hunters arrive and start digging.
34Warden menders arrive and start setting seal-stones.
45At 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.
66The 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

Seal it, share it, hoard it

ChoiceWhat the player doesMoves
SealClose 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
ShareTrace 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
HoardTrace 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
MissedArrive 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

RegionEncounter (new)Enemies
1. The Sallowhunt_guardian_sallow5 glint + glint_brute
2. The Long Roadhunt_guardian_road3 dust_glint + 2 winged_glint
3. Twinhold and Greenvaulthunt_guardian_lowlands4 glint + glint_brute
4. Hushfold and the Hour Stairhunt_guardian_highlands4 frost_glint + echo_owl
5. The Shardfieldhunt_guardian_shardfield4 shard_glint + shardshell_crab
6. Corranhunt_guardian_corran3 stilled_glint + 2 winged_glint
7. The Undermerehunt_guardian_undermere4 roof_glint + drowned_chorister
8. The Heart Panehunt_guardian_panesky_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.

From Side Quests › Recurring world activities