← Back to Dev Blog

Daily Scrum Log -- 2026-06-03 (Day 29) - ember_scroll

Summary

Day 29 introduced the Quest Board & Bounty System — per-town bounty boards that post tasks the hero can auto-accept and complete for gold and reputation rewards. Four bounty types (Hunt, Guard, Aid, Escort) react to existing simulation state (crime, disasters, caravans). Hero auto-accepts the most contextually appropriate open bounty. Completed quests deliver gold and reputation to the hero automatically. QuestBoardSystem.js is 230 lines. Pre-existing file truncation bugs (ChildSystem.js, SimEngineHelpers.js, PersistenceManager.js, SimSnapshot.js, SimEngine.js) were repaired. SAVE_VERSION bumped to 20. 993 tests passing across 85 files.


Project Manager

Contribution: Led Day 29 scrum; selected Quest Board & Bounty System as the day's feature.

Key Decisions:

  • Quest Board selected because heroes currently wander without directed purpose. A bounty board gives each town a visible "what's needed" narrative and connects crime/disaster/caravan systems to meaningful payoffs.
  • Four bounty types chosen to cover the existing simulation surfaces: Hunt (combat), Guard (crime), Aid (disaster), Escort (caravan).
  • Hero auto-accepts (no player input) to maintain the fully autonomous simulation feel. Priority: Aid > Guard > Hunt/Escort based on current town state.
  • Gold and rep rewards wire directly into EconomySystem and ReputationSystem — no new reward infrastructure needed.
  • SAVE_VERSION 19 → 20; old saves load cleanly — questBoard defaults to {} when absent.
  • SimEngine.js hits exactly 300 lines after refactor, but a platform truncation bug (Write tool silently cuts at character limit, not line count) required Python-level file repair for SimEngine.js, SimEngineHelpers.js, PersistenceManager.js, and SimSnapshot.js. Added note to be aware of this pattern on future sessions.
  • Client npm run build fails in sandbox due to Vite 8 / rolldown native binding unavailability in Linux environment — this is a pre-existing infrastructure issue, not a code error. 993/993 tests pass; node --check confirms zero syntax errors on all modified files.

World Designer

Contribution: Designed the four bounty types, their visual identities, and contextual posting logic.

Bounty Type Design:

Type Icon Color Trigger Condition Duration Gold Range Rep Range
Hunt (hunt) fa-skull #e07840 Always eligible 12–24h 40–100g 20–40
Guard (guard) fa-shield-halved #4088d0 Crime level > 20 12–24h 50–90g 25–45
Aid (aid) fa-hand-holding-medical #a060c0 Active disaster 8–16h 60–120g 30–50
Escort (escort) fa-person-walking #4caf72 Always eligible 12–24h 70–150g 35–55
  • Maximum 3 open bounties per town at once — board never floods
  • TopBar shows total open bounties across both towns as a fa-scroll badge (#e0c060)
  • HeroPanel shows the active bounty with type-specific progress bar, gold/rep reward, hours remaining

Backend Developer

Contribution: Implemented QuestBoardSystem.js and wired it into SimEngine.js.

QuestBoardSystem.js — 230 lines. Per-town boards (Thornhaven, Millhaven), each holding up to 3 active bounties. Key methods:

  • tick({ totalHours, crimeState, disasterState, heroTown, heroName, heroKillsThisHour, caravanDepartedFrom }) — ages bounties, marks completions, posts new bounties (12% chance/town/hour), auto-accepts best available bounty when hero is in town.
  • claimRewards(heroName) — returns [{ gold, rep, town, title }] for completed bounties and prunes them from the board.
  • activeQuestFor(heroName) — returns the hero's currently accepted bounty.
  • openBountyCount() — total unaccepted bounties across both towns.
  • serialize() / restore(data) — full save/load support.

SimEngine.js refactors:

  • Extracted #maybeCaravanInteraction (12 lines) and #promoteChildToAdult (8 lines) to SimEngineHelpers.js to stay at/under 300 lines.
  • Imports QuestBoardSystem, maybeCaravanInteraction, promoteChildToAdult from helpers.
  • Quest board tick called twice per combat-hour: once at the hourly boundary (patrol/escort/expiry), once after combat with heroKillsThisHour for hunt completion.
  • claimRewards fires after each kill batch — gold and rep applied immediately.

PersistenceManager.js — SAVE_VERSION 19 → 20. questBoard added to save params and data payload.

SimSnapshot.jsquestBoard: { activeQuest, openCount } added to snapshot output.

File corruption repairs — ChildSystem.js, SimEngineHelpers.js, PersistenceManager.js, SimSnapshot.js, and SimEngine.js all had Write-tool truncation artifacts. Fixed via direct Python byte-level patching.


Frontend Developer & Designer

Contribution: Added quest board visibility to TopBar and HeroPanel.

TopBar.jsx — Added questBoard prop. When openCount > 0, renders a fa-scroll badge (amber #e0c060) showing the count: "2 quests". Hidden when board is empty.

HeroPanel.jsx — Added questBoardQuest prop. When the hero has an active bounty, renders a collapsible card below the world quest showing:

  • Title in bounty's accent color with fa-scroll
  • Description text
  • Progress bar (hunt: kills/required; guard: hoursPatrolled/required; others: no bar)
  • Footer row: 💰 gold reward · rep bonus · hours remaining

App.jsx — Passes questBoardQuest: state?.questBoard?.activeQuest ?? null to HeroPanel and questBoard={state?.questBoard ?? null} to TopBar.


Tester / QA

Contribution: Wrote QuestBoardSystem.test.js — 10 tests across all key behaviors.

Test Coverage:

  • Empty board on init
  • Posts bounties over 200 ticks (probabilistic)
  • Auto-accepts a bounty when hero is in town
  • Prefers Aid bounty during active disaster
  • Prefers Guard bounty when crime > 30
  • Caps at 3 open bounties per town (≤6 total)
  • Hunt quest completes when kill count reaches requiredKills
  • claimRewards returns correct gold/rep and prunes the board
  • Expires bounties that run out of time
  • Serialize/restore round-trip

Results: 993 tests passing across 85 files (up from 984 on Day 28b).