Files
TheLastGarden/content/dialogue/season1/letter-from-the-garden.ink
T
josh 26eb77a216 feat(02-05): sim/offline + auto-harvest + letter Ink + letter-renderer
- src/sim/offline/: OfflineEventBlockSchema (Zod) + EMPTY_OFFLINE_EVENTS
  + aggregateOfflineEvent pure aggregator (D-19); 14 tests green
- src/sim/garden/auto-harvest.ts: autoHarvestReadyPlants silent-mode
  branch (D-10); reuses harvest() pipeline so selector + Pitfall 10
  unlocks + STRY-10 Lura gate all run identically; BLOCKER 3 invariant
  preserved (no lastTickAt writes); 7 tests green
- simulateOneTick: ctx.silent triggers auto-harvest sweep before tick
  increment; active-play path unchanged (silent defaults false)
- content/dialogue/season1/letter-from-the-garden.ink: authored skeleton
  with VAR plants_bloomed / fragment_titles / lura_was_here per D-17/D-18;
  bible voice, anti-FOMO compliant, 24h cap silent in voice (D-11)
- ink-loader: loadInkStory union extended with letter-from-the-garden;
  separate letterStoryGlob for lazy code-split chunk; INK_VARIABLE_MAP
  gains plants_bloomed / fragment_titles / lura_was_here slots reading
  from session.pendingLetterEventBlock
- src/ui/letter/letter-renderer.ts: pure buildLetterSlots helper —
  prefers fragment first-sentence body for tonal weight, slugified-id
  fallback; 10 tests green
- npm run compile:ink emits 5 .ink.json files (was 4); Vite emits the
  letter as a separate lazy chunk (letter-from-the-garden.ink-*.js)
- 295/295 tests green (was 264; +31 new); npm run ci exits 0
2026-05-09 10:49:59 -04:00

48 lines
1.6 KiB
Plaintext

// Letter from the garden — UX-02 + CONTEXT D-17 + D-18 + D-20.
//
// Composed from authored skeleton + templated insertions per CONTEXT D-17.
// Slots populated at runtime from sim/offline/events.ts via the variable
// map in src/content/ink-loader.ts.
//
// Per Pitfall 4: Ink VAR names are snake_case AND case-sensitive.
// Per CONTEXT D-11: 24h offline cap is silent in voice — no numeric
// "28h" copy in any branch.
// Per CLAUDE.md Tone — the gardener-keeper voice. Warm. Specific.
// Intermittent. Sometimes funny, sometimes devastating. Never a stat
// dump (UX-02 explicitly forbids that). The skeleton holds the voice;
// the slots fill in the specifics.
// Per anti-fomo-doctrine.md: this letter is NOT a "you missed X — come
// back tomorrow!" nag. It is a contemplative summary of what stayed.
VAR plants_bloomed = 0
VAR fragment_titles = ""
VAR lura_was_here = false
VAR fragment_count = 0
VAR last_plant_type = ""
== letter ==
The garden held its breath while you were gone.
{ plants_bloomed > 1:
{plants_bloomed} blooms came and went, each leaving the soil a little quieter than they found it.
- else:
{ plants_bloomed == 1:
One bloom came and went. The space it left feels generous, somehow.
- else:
Nothing bloomed. The wind carried something else, and the garden held that, too.
}
}
{ fragment_titles != "":
Among what stayed: {fragment_titles}.
}
{ lura_was_here:
Lura came by once. She did not knock. She left a folded leaf on the gate post — you'll find it when you next walk past.
}
The light is the same as when you left. The garden is older.
-> END