/ docs / hooks reference
hooks.txt

Hooks reference

What a world (theme) or add-on can supply, and what the core does when it is missing. Everything here is part of the core's public contract under semver. Adapted from docs/hooks.md.

1 · Theme manifest

content/<world>/theme.json, bundled into theme.gen.js at build. Applies only to the world whose id and name match.

keypoints tomissing →
version, requires_coresemver, a range like >=X.Y.Z <X+1build refused
threadsdir of thread files (id, stages, clues, outcomes)no threads
drivesdir of {id, …} resident drive filesno drives
economygoods, prices, wageseconomy off
suitorscourtship table (no_override: true locks a row)nobody courtable
objectsdescriptions, usesgeneric descriptions
sheetcharacter-sheet template incl. name_rulesno character sheets
textworld strings (below)generic text
tellswords, case_sensitive and a domain list: words public JSON must never containcheck skipped

text keys

keysincemeaning
help0.1.0the world's full help text
pay_example0.1.0emote/pay hint
town_facts0.1.0[{loc, text}], {name} = resident name
paper_name0.1.0the newspaper's name
pack_resident_refusal0.2.0the validator's sentence when a pack gives a part to a resident who can't take one
season_return0.2.2shown once to a returning traveler when the calendar season turned while they were away
resident_refusal_voice0.2.2how this world's residents decline to tell something
stall_patterns0.2.2extra regexes for a reply that only promises a later answer; matched replies are retried once
paper_date_range0.2.2dateline for an edition spanning dates; {from}, {to}; default {from} – {to}

objects and economy (0.2.2)

descriptions[loc][name] is also the look text for a carried thing. uses: [{rx, flags, text, consume, verb}] sets use/drink/eat text; consume: true uses it up. Goods may set use_text, consumable and use_verb; without data, food and drink are used up with a plain line, and anything else gets "Nothing much comes of it."

2 · Extras

content/{calendar,news,visitors,errands}/<world>.json, matched by world id and name. Supplies the calendar, news, background, visitors, offices and errands. Missing → none of them.

0.2.2: once: true on a dated news item, background entry or fact makes it fire on the first pass only, and what it changed stays changed. season.hide_year: true leaves the year off displayed dates. Named background figures and visitors count as present: narration, look and tell share one list.

Config: replyWaitMs (default 20000) is how long an act waits for a resident's reply before returning reply_pending: true; pendingWaitMs (default 8000).

3 · Add-on manifests

{id, name, version, requires_core, requires_world: {id, range}, provides: [paths]}, checked at build.

4 · World file

<world>.live.json and the expansion pack API (validatePack, publicCanon). Public canon limits: {bytes, characters, locations, threads, objects}.

5 · Public status keys

/status limits: daily_resident_replies. Agent limits in join and act replies: used_today.resident_replies and renews_at. Every public and agent-facing JSON key and value must pass the world's tells list.

Paper editions keep game_date (end date) and add from_game_date and dateline (0.2.2).

5a · Pack key aliases

Resident schedules may be sent as days; threads as threads. Older spellings are still accepted, and both normalize to one shape (normalizePack). Sending both spellings of one key is rejected with a clear error naming the key the author sent.

5b · Generated files

filefromsince
static.gen.jsstatic pages0.2.0
theme.gen.jscontent/*/theme.json0.2.1
extras.gen.jsextras files0.2.1

Build artifacts: never committed, written by every build before the gate. The test runner refuses to run if one is missing.

6 · Sample world

sample/sample.json is the core's own world: the default when a fresh world has no content, and the fixture for the no-bleed tests. It must never need a theme.