← Back to Dev Blog

Daily Scrum Log — 2026-05-23 (Day 10) · gilded_path

Summary

Three bugs from BUGS.md were fixed and two new systems shipped. Days are now 100× longer in sub-tick time (50 real seconds per in-game hour, ~20 real minutes per full day). Cottages have their own tile type (TILE.COTTAGE = 8) and render with a 🏠 emoji so players can distinguish homes from grass. The hero's active region is now highlighted with a tinted zone overlay and a label badge, making travel feel meaningful. A* pathfinding replaces Manhattan stepping — villagers now route around buildings and water. The basic economy system adds per-villager gold, shift wages, fluctuating market prices (wheat · iron · bread · cloth), and trade events when compatible professions meet. Test suite grew by 33 tests to 308 passing.


Project Manager

Contribution: Led Day 10 scrum and triaged BUGS.md.

Key Decisions:

  • Prioritised the three reported bugs as Day 10's anchor work — user feedback is the highest-signal signal. Fixed all three before shipping new features.
  • Chose A* pathfinding as the primary new feature. With households visible, watching villagers clip through the Inn is jarring. Path-aware movement is a prerequisite for all future indoor/building interaction.
  • Chose basic economy as the secondary feature. It adds a continuous background narrative to the chronicle (trades, prices) and establishes the gold-tracking infrastructure that will power merchants, shops, and eventually a second-town economy.
  • Deferred children/generational simulation to Day 11. It's the most complex feature and deserves a focused session.
  • Decided to fix the PersistenceManager truncation standing issue by mandating bash heredoc for any file > ~100 lines, not just > ~150. Previous threshold was too high.

Reasoning: The bugs were user-reported friction. Fixing them first earns trust and makes every subsequent session feel like forward progress rather than accumulating debt.


World Designer

Contribution: Specified the region zone visual treatment and cottage tile aesthetic.

Cottage tile:

  • Color: #a07840 — warm amber-brown. Reads as timber/thatch against grass green and tree dark. Distinct from all 7 existing tile colors.
  • 🏠 emoji centred at TILE_SIZE - 6 font size (16px at the current tile size). Fits within one tile without overflow; emoji rendering varies by OS but is universally recognizable as a house.

Region zone overlay:

  • Each non-Town zone gets a semi-transparent tint color that evokes its biome: forest green for Thornwood, slate-blue for Mountains, dark swamp-green for Blackmire, deep red for Crimson Wastes.
  • Dashed gold border (rgba(255,220,100,0.55), 4-3 dash) marks the active zone boundary without obscuring the tiles inside.
  • Region name printed in warm cream at the top edge of the zone, plus a smaller badge directly under the hero dot. This gives two visual anchors — the zone itself and the hero's exact location.
  • Faint static corner labels (opacity 0.42 instead of 0.55) de-emphasised slightly so they don't compete with the active zone label.

Backend Developer

Contribution: Wrote Pathfinding.js, EconomySystem.js; updated TownMap.js, HouseholdSystem.js, Villager.js, SimEngine.js, PersistenceManager.js.

Pathfinding.js:

  • Standard A* with Manhattan heuristic, 4-directional movement.
  • Blocked tiles: BUILDING, TREE, WATER, WALL. Passable: GRASS, PATH, MARKET, FIELD, COTTAGE.
  • Returns [] when start equals end, or when destination is blocked, or when no path exists.
  • Path stored as [{x,y}] array; keys encoded as y * W + x integers for fast Map/Set operations.
  • Tie-breaking: among equal-f nodes the one with the smaller key wins (right/down preference, consistent with prior Manhattan-step behavior for on-grid tie situations).

Villager.js — A* integration:

  • Added #path = [] and #pathTarget = null private fields.
  • step() invalidates and recomputes the path whenever targetAt(hour) changes. Pops one step per call.
  • Added clearPath() for callers that teleport the villager (e.g. HouseholdSystem.assign()).
  • isBlocked() helper retained for potential future use but A* now governs all movement.

TownMap.js:

  • Added TILE.COTTAGE = 8.
  • Extracted HOUSEHOLD_HOMES as a named export so HouseholdSystem.js and generateTownMap() share the single source of truth.
  • generateTownMap() stamps TILE.COTTAGE at each household position.

HouseholdSystem.js:

  • Removed local HOUSEHOLD_HOMES array; imports from TownMap.js.
  • No behavioral changes.

EconomySystem.js:

  • initialize(villagers) seeds 100 gold per villager (idempotent).
  • tick(serializedVillagers, hour) returns {type, message}[] events. Performs three actions:
    1. Wages every WAGE_INTERVAL=10 ticks — profession-specific rates, shift-hour gated.
    2. Price fluctuation every 15 ticks — ±20% drift on each of 4 goods, clamped to [1, base*2].
    3. Trade events every 20 ticks — checks 5 TRADE_PAIR combos within TRADE_DISTANCE=2 Chebyshev distance; buyer pays seller the current wheat/iron/bread/cloth price.
  • Market bulletin fires every 500 ticks (📊 Market prices: ...).
  • serialize() / restore() for persistence.

SimEngine.js:

  • TICK_MS = 500ms, TICKS_PER_HOUR = 100 (was TICK_MS = 3500ms, 1 hour per tick).
  • Added #subTick counter. NPC movement and economy run every tick. Social/combat/phase-transition run only on hour boundaries (#subTick === TICKS_PER_HOUR).
  • #maybeSave() now passes economy: this.#economy.

PersistenceManager.js:

  • SAVE_VERSION bumped to 3.
  • save() accepts economy param; writes economy: economy.serialize() or null.
  • #loadSave() calls this.#economy.restore(save.economy) on boot.

Technical note: PersistenceManager.js was truncated by the Edit tool (same pattern as Days 5, 7, 8, 9). Rewrote via bash heredoc. Raising the standing rule threshold: always use heredoc for any file you're modifying if it exceeds ~100 lines.


Frontend Developer / Designer

Contribution: Rewrote WorldMap.jsx with COTTAGE tile rendering, region zone overlay, and hero region badge.

WorldMap.jsx changes:

  • Added TILE_COLORS[8] = '#a07840' (COTTAGE — warm amber-brown).
  • After base tile fill, a second pass emits 🏠 emoji at TILE_SIZE - 6 font centered on each COTTAGE tile. Uses textBaseline = 'middle' then resets to 'alphabetic' for downstream text calls.
  • REGION_ZONES constant mirrors server/TownMap.js zones with biome tint colors and emoji-prefixed labels.
  • When region prop is a non-Town zone, draws: (a) semi-transparent tint fill over the zone tiles; (b) dashed gold border; (c) region name text at top of zone; (d) small region badge just below the hero dot.
  • Static corner labels opacity reduced from 0.550.42 to avoid competing with the active zone label.
  • All prior features preserved: friendship lines, marriage lines, villager dots, chat bubbles, day/night overlay, lantern halos.

Tester / QA

Contribution: Wrote Pathfinding.test.js (13 tests) and EconomySystem.test.js (13 tests); updated Villager.test.js.

Pathfinding.test.js — 13 tests:

  • Empty array returned when start equals end.
  • Single-step path for adjacent tiles.
  • Optimal path length equals Manhattan distance on clear grid.
  • Path ends exactly at destination.
  • First step is adjacent to start (distance 1).
  • Each consecutive step is exactly 1 tile apart.
  • Routes around single water tile; no step lands on water.
  • Routes around a vertical building wall.
  • Returns [] when destination is a building.
  • Returns [] when no path exists (fully enclosed source).
  • Passes through PATH and MARKET tiles.
  • Passes through COTTAGE tiles.
  • Handles null/empty grid gracefully.

Villager.test.js — updated (7 tests, replaces 3 brittle Manhattan-step tests):

  • Replaces { x: 2, y: 1 } positional assertions with behavior assertions: moves closer each step, moves exactly 1 tile, avoids water, reaches target eventually.
  • Added: target-change path recompute test; clearPath() invalidation test.
  • Grid size bumped from 6×6 to 10×10 for room to route around the water cell.

EconomySystem.test.js — 13 tests:

  • init/re-init gold; day/night wage gating; Baker night-owl wages; trade event emission; trade gold transfer (tested at hour=2 to isolate from wages); no-trade-when-far; price persistence; serialize/restore round-trip; restore(null) is no-op.

Root causes fixed:

  • EconomySystem trade test initially failed because the merchant earned wages during the same 20 ticks, netting positive. Fixed by running the trade test at hour=2 (night, no day-shift wages).
  • PersistenceManager.test.js parse error: the .js file was truncated by an Edit-tool overwrite, leaving the class body unclosed. Fixed by heredoc rewrite.

Results: npm test308 / 308 passing (was 275; +33 tests: 13 Pathfinding + 13 Economy + 7 updated Villager).


What Was Built

Bug fixes:

  • BUG-001: Days are now 100 sub-ticks per hour at 500ms/tick (~20 min/day)
  • BUG-002: COTTAGE tile (type 8) with 🏠 emoji and amber-brown color
  • BUG-003: Active region zone gets tinted overlay + dashed border + name label

New features:

  • Pathfinding.js: A* on the 24×24 grid; villagers route around buildings and water
  • EconomySystem.js: per-villager gold, shift wages, 4-good market prices, proximity-based trade events
  • TownMap.js: exports HOUSEHOLD_HOMES; stamps COTTAGE tiles
  • SimEngine.js: TICKS_PER_HOUR sub-tick architecture; EconomySystem integrated
  • PersistenceManager.js: SAVE_VERSION 3; economy persisted to save files

Tomorrow (Day 11 Candidates)

  • Children / generational simulation — married couples can have children who grow up over many in-game days, inherit profession tendencies, and eventually join the workforce. First generational turnover.
  • Second town — add a second settlement with its own population and a road connecting the two; hero travel events can include inter-town journeys.
  • Villager names on hover / click panel — clicking a villager dot on the canvas opens a sidebar with their name, profession, household, gold, relationship tier with others.
  • Inventory / shop system — merchants and the blacksmith have item stock; hero can browse and buy equipment between quests.
  • Night economy — bakers and night-watch have their own sub-economy (bread sales, guard pay from town coffers).