Exact source used by this build. SHA-256: f31e800ef1bf42b8978f00821d4213395282dfc9ca82043aa133dd00fcca3c4d.

1 # Animals, festivals and villagers integration
2 
3 Changes are uncommitted on main, based on `eefbc4b`. The worktree was clean when
4 this task began. No deploy, credentials, remote push, history rewrite, dependency
5 addition or deletion of an existing file was performed. Following the Mac restart,
6 work continued without agents, browsers or concurrent heavy commands.
7 
8 ## Shared-file repair audit
9 
10 Reviewed the affected code against integrate-1 (`7d77753`), both parents of the
11 animal/festival/villager merges (`be8f979`, `cfc1646`, `0461b35`), and their branch
12 tips. Package scripts and credits were also checked against the content-lint and
13 art merges (`118445a`, `b4a7200`). The resulting repairs are:
14 
15 | File | Result |
16 | --- | --- |
17 | `packages/sim/src/systems/movement/index.ts` | Removed duplicated imports, interleaved handlers and the copied private path sampler. Retained integrate-1's shared swept geometry, unchanged-move no-op, batched persistence, initial jitter allowance and partial-warp distance charge. Added feature access/repair checks. Equipment and horse speed multiply through the registry. Equipment remains effective in an isolated movement registry. |
18 | `apps/client/src/systems/movement/index.ts` | Repaired the interleaved distance expression and duplicate imports. Prediction uses the same composed speed as authority and retains swept collision, packet-anchor checking, reconciliation and camera behavior. |
19 | `packages/sim/src/systems/registry.ts` | Recombined one hook type, context, dispatcher and returned API. Kept offline-machine hooks, bounded update intervals and persistence metadata; combined item tools, movement speed, intent/access guards, repairs and greenhouse capabilities. Added exact festival freeze deadlines and a weather policy capability. Paused/offline worlds release fast cadence. |
20 | `packages/sim/src/clock.ts` | Removed the second elapsed pass and duplicate locals. Each online millisecond is delivered once, split at calendar ticks or festival expiry. Calendar resumes with the remaining time after an event. Manual pause and the machines-only offline path remain intact. |
21 | `packages/sim/src/systems/shops/index.ts` | Removed duplicate `getShops`/`shopIsOpen` definitions. Kept cross-domain shops, keeper presence, hours, inventory/wallet transactions and integrate-1 geode cracking. |
22 | `packages/sim/src/systems/index.ts` | One deterministic registration list containing all 20 systems. Festivals settle elapsed deadlines before fishing scores; animals immediately precede weather; community follows shipping. All public exports retained. |
23 | `apps/client/src/systems/index.ts` | Removed imports embedded in the registration array and repeated entries. All 22 systems remain registered. Animal counter interactions precede generic shops; festival/community interactions precede inventory fallback. |
24 | `packages/content/src/domains/index.ts` | Reviewed; already contains all 19 domains exactly once. No edit needed. |
25 | `packages/sim/test/registry.test.ts` | Kept existing tests; added exact live registration order and combined capability/cadence/offline/metadata coverage. |
26 | `apps/client/src/core/registry.test.ts` | Retained the exact registration assertion and corrected interaction order. |
27 | `packages/content/test/domains.test.ts` | Reviewed; the merged exact 19-domain assertion was already correct. No edit needed. |
28 | `apps/client/public/assets/CREDITS.md` | Retained art-round-two provenance and animal/villager credits, separated procedural placeholders and added festival/community CC0 credits. |
29 | `package.json` | Removed duplicate `typecheck`, `check` and `postinstall` keys. The combined check retains workspace typechecks, content-tool typecheck, feel checks, all tests, content validation and warning-mode content lint. Art scripts retained. |
30 
31 The farming season/greenhouse callbacks, tool-owned animal extensions and trusted
32 forage/tool quest progress were also reviewed against integrate-1. They already
33 composed correctly and were retained. No server persistence policy was replaced.
34 
35 ## Porting decisions
36 
37 ### Animals
38 
39 - Added the missing authored farm building area, `poi.farm.building_area`, at
40   `(25,5)`, size `20×24`, and documented it in `docs/maps.md`. All 11 building
41   definitions fit somewhere inside it. Existing terrain layers are unchanged.
42   Placement checks both footprint and doorway against that area and live
43   collision, reserved POIs, crops, objects, players, animals and products.
44 - Carpenter and ranch positions resolve from town POIs. The carpenter uses
45   `poi.town.meeting_hall_bench_01`; ranch supplies use
46   `poi.town.sugar_shack_counter`. Both use the shop system and scheduled keepers.
47 - The town carpenter's client planning grid reconstructs authored farm terrain
48   plus shared buildings. It explains that live occupancy is checked on confirm;
49   the authority still validates the real farm atomically. Area-scoped snapshots
50   do not expose a remote live farm merely to draw the grid.
51 - Care/wandering remain on ten-minute ticks and are not also charged in elapsed
52   hooks. Walking creates coalesced state changes; newly spawned products request
53   durable outcome persistence. Pause/offline behavior remains frozen.
54 - Demolition removes an empty generated interior through integrate-1's existing
55   area-removal support. Occupied interiors still reject demolition. The obsolete
56   branch tombstone workaround is gone.
57 - Initial grass patches moved off non-growable path tiles, and validation now
58   rejects non-growable initial grass. Pet rain preview and actual weather share
59   the festival weather override without consuming an extra random roll.
60 
61 ### Festivals and community
62 
63 - Existing festival entrances, games, layouts, closures and community stations
64   already resolve to POIs on the current maps. Retained those references and
65   added validation that the fishing game has reachable tagged water and fish
66   available in its season/time window.
67 - Admission alone no longer freezes the calendar. The main event freezes it
68   when all connected players participate. Timers use injected real elapsed time
69   and 250 ms active cadence, with exact fractional expiry splitting.
70 - Festival fishing uses ordinary rod charging, map-water casting, bite windows,
71   hook and minigame mechanics. The old synthetic cast/reel scoring path is gone.
72   Only a verified rod fish catch scores; trash, pots and repeated claims do not.
73 - Fishing now owns one real elapsed timeline. Existing integrate-1 mid-tick
74   saves migrate their calendar remainder once, preserving active casts. Explicit
75   pause/offline behavior remains frozen; transient fishing progress stays batched.
76 - Festival sunshine is supplied to the weather owner before watering or animal
77   preview. This avoids weather being overwritten by a later roll and avoids
78   silently watering soil on an otherwise sunny festival morning.
79 - Minerals have one canonical item definition: the mines catalog. Removed the
80   14 duplicate community mineral records while retaining every mineral ID,
81   mines value, museum reference and all artifact records/files.
82 
83 ### Villagers
84 
85 - NPC walking runs only through `onElapsedTime`; clock ticks select routes with
86   zero movement. Active walking requests the content-defined 1-second cadence
87   and creates no durable per-frame event. Stopped NPCs preserve state identity.
88 - Current map POIs, collision-grid paths and unlocked warp graph remain the
89   schedule authority. Festival dates are validated against festival content.
90 - Villager 06 staffs the carpenter; villager 05 staffs ranch supplies. Both the
91   client availability display and authoritative access require the scheduled
92   keeper to be present, in addition to shop hours.
93 - Gift tastes and quests reference actual vegetable/crop, fish, forage, cooked,
94   artisan and mineral items/tags; tag/reference validation catches missing inputs.
95 
96 ## Cross-system paths verified
97 
98 | Path | Integration |
99 | --- | --- |
100 | Villager gifts/delivery quests | Real crop, fish, forage, cooked and mineral catalog IDs/tags; independent player friendship and inventory rules retained. |
101 | Fishing/monster quests | Authoritative rod/pot catches report fishing progress once. Monster death reports slay credit only to the last hitter. No client progress intent added. |
102 | Bundles | Added real fish and artisan alternatives; retained crop and mineral requirements and choose-N/partial shared contribution rules. Tests donate all four categories. |
103 | Festival fishing | Ordinary fishing producer updates both the actual catch collection and festival score; expiry is processed before scores. |
104 | Museum | Real mine nodes/geodes yield canonical museum minerals; fishing treasure contains museum artifacts/minerals. Producer-to-inventory-to-donation tests retain duplicate rejection and pending catch semantics. Existing drop/treasure RNG is used rather than awarding an extra unrelated item. |
105 | Animal machines | Actual egg/milk product tags feed the existing dairy recipes, producing artisan inventory. Four species are tested through overnight production, collection/milking, machine loading, elapsed processing and collection. Removed obsolete external milk/egg/fish exemptions so missing producers fail content validation. |
106 | Carpenter | Town POI, present villager keeper, common shop access, buyer materials, shared/split wallet rules, farm placement and generated interiors. Two real TCP-client tests cover both wallet modes. |
107 
108 ## Tests and assertion decisions
109 
110 No existing test was deleted or skipped. Existing assertions were retained or
111 replaced by checks of the governing integrated behavior:
112 
113 - The old festival branch froze time immediately on attendance. That contradicted
114   `docs/time-and-multiplayer.md`, which specifies the main event. Tests now assert
115   admission-running, main-event-frozen, expiry-resumed and no exit-time rewind.
116 - The old synthetic fishing timer assertion is replaced by actual charging,
117   water casting, biting, hooking, fish inventory/collection and exactly-once
118   scoring assertions. Packet spam cannot mint catches.
119 - Animal fixtures now use the authored building zone/town shops. Multiplayer
120   overnight fixtures walk to the real starter bed and return to the coop.
121   Wallet, material, shared-care, product, RNG and area-scope assertions remain.
122 - Removed-interior assertions replace obsolete tombstone assertions and also
123   verify the area-removal patch. This follows integrate-1's supported deletion
124   protocol, not a relaxation of occupancy protection.
125 - The geode fixture advances through the keeper's actual commute before buying.
126   Economic assertions remain. Persistence tests reconstruct checkpoint plus
127   journal rather than assuming every accepted action rewrites checkpoint rows.
128 - The crafting overnight sprinkler test still requires sunny weather and all its
129   original watering assertions; correcting invalid animal grass seeds made the
130   deterministic fixture compatible without weakening those checks.
131 
132 New files: `animals-integration.test.ts`, `villagers-integration.test.ts`,
133 `integration2-hooks.test.ts` and `mixed-day-write-budget.test.ts`. Existing
134 festival, fishing, mines, community, content, client and multiplayer suites gained
135 producer, reference, timing, durability and regression assertions.
136 
137 ## Measured writes
138 
139 Local production `FarmWorld` replays use real in-memory SQLite and deterministic
140 socket/time adapters. Writes include SQL inserts/updates/deletes plus alarm writes.
141 These are measured local workloads, not deployed billing telemetry.
142 
143 | Replay | SQL row changes | Alarm writes | Alarm invocations | Total writes |
144 | --- | ---: | ---: | ---: | ---: |
145 | Stationary, 60 seconds, two players at 10 Hz | 4 | 10 | 10 | 14 |
146 | Movement, same duration/input rate | 8 | 10 | 10 | 18 |
147 | Fishing, 60 seconds, 1,574 progress inputs | 64 | 10 | 10 | 74 |
148 | Combat swing spam, 60 seconds | 10 | 10 | 10 | 20 |
149 | Mixed full game day, 848.04 real seconds | 913 | 141 | 141 | **1,054** |
150 
151 The mixed replay begins from a prepared mature farm/mine save. All measured play
152 uses server intents and elapsed time: both players harvest/replant/water 24 plots
153 in total and fish for two minutes (15 catches); one player pets, feeds and
154 collects an animal product, the other breaks eight mine nodes (19 hits) and kills
155 one monster. They travel through actual maps, with NPC schedules walking
156 throughout, then both continue 10 Hz movement until the 2 AM overnight checkpoint.
157 The test checks aging, day transition, outcomes and restart recovery. Mine travel
158 accounts for the slightly longer-than-14-minute day.
159 
160 - Proportional four-hour projection: **17,898 writes**.
161 - Conservative projection: round up to **17 complete days** and add all **300
162   setup/join/fixture-checkpoint writes**: `17 × 1,054 + 300 = 18,218`.
163 - Both are asserted below **20,000**. The conservative allowance is **1,782 writes**.
164   It describes this reproducible workload, not an unlimited cap on arbitrary
165   purchases, reconnects or other durable transactions.
166 
167 ## Acceptance and resource handling
168 
169 - `bun run check`: passed, **643 tests**, **0 failures**, 151,194 assertions
170   across 91 files (89.58 seconds). Includes workspace/content-tool/feel
171   typechecks, real workerd/WebSocket tests, content validation and lint.
172 - Content validation: **19 domains**, 12 crops, 243 items, eight Tiled areas.
173 - `bun run content:lint`: passed, **0 errors**, **1,877 TBD warnings**.
174 - `bun run --cwd apps/client build`: passed, 442 ms. JavaScript 3,103.19 kB,
175   gzip 578.24 kB. The existing Vite warning about a chunk over 500 kB remains.
176 - Focused post-resume checks: 20 fishing/timing tests; 14 registry/hook/full-day
177   replay tests; 18 animal/crafting/festival multiplayer and budget tests passed.
178 - `git diff --check`: passed.
179 
180 The full check ran once after the restart, after focused repairs; the client
181 build followed it serially. Temporary acceptance logs and the five task-owned
182 pre-crash integration logs were removed after recording their results. Test
183 servers and their temporary persistence are torn down by their harnesses.
184 Retained ignored artifacts: current client build about 3.0 MB, generated content
185 48 KB, preserved existing server state 9.7 MB, and existing dependencies 409 MB.
186 The dependencies are needed for validation; no new large untracked artifact or
187 project copy was introduced. Other pre-existing run evidence was preserved.
188 
189 No browser/phone visual review was run in the resumed task. Client model tests and
190 the production build cover the integration; existing responsive UI styling is
191 retained. Creative names stay `TBD`; reserved fishing/animal display names were
192 converted to placeholders without changing IDs or numerical mechanics. Content
193 lint remains strict for errors and warns for TBD fields.
194 
195 No Git writes were attempted; all changes are left uncommitted as instructed.
196 
197 
198 ## Files changed
199 
200 ```text
201 apps/client/public/assets/CREDITS.md
202 apps/client/src/core/registry.test.ts
203 apps/client/src/systems/animals/index.ts
204 apps/client/src/systems/animals/model.ts
205 apps/client/src/systems/festivals/index.ts
206 apps/client/src/systems/index.ts
207 apps/client/src/systems/movement/index.ts
208 apps/client/src/systems/shops/index.ts
209 apps/client/test/animals-model.test.ts
210 apps/server/test/animals-loop.test.ts
211 apps/server/test/festivals-community.test.ts
212 apps/server/test/mixed-day-write-budget.test.ts
213 docs/architecture.md
214 docs/extending.md
215 docs/maps.md
216 docs/w3-integration2-report.md
217 package.json
218 packages/content/data/animals/animals.json
219 packages/content/data/community/community.json
220 packages/content/data/crafting/crafting.json
221 packages/content/data/fishing/fishing.json
222 packages/content/data/items/animals.json
223 packages/content/data/items/community.json
224 packages/content/data/items/fishing.json
225 packages/content/data/items/mines.json
226 packages/content/data/maps/farm.json
227 packages/content/data/villagers/villagers.json
228 packages/content/src/domains/animals/index.ts
229 packages/content/src/domains/animals/schema.ts
230 packages/content/src/domains/festivals/index.ts
231 packages/content/src/domains/villagers/index.ts
232 packages/content/src/domains/villagers/schema.ts
233 packages/content/test/animals-content.test.ts
234 packages/content/test/community-content.test.ts
235 packages/content/test/crafting-content.test.ts
236 packages/content/test/festivals-content.test.ts
237 packages/content/test/villagers-content.test.ts
238 packages/sim/src/clock.ts
239 packages/sim/src/systems/animals/REPORT.md
240 packages/sim/src/systems/animals/buildings.ts
241 packages/sim/src/systems/animals/index.ts
242 packages/sim/src/systems/animals/lifecycle.ts
243 packages/sim/src/systems/animals/types.ts
244 packages/sim/src/systems/community/README.md
245 packages/sim/src/systems/festivals/README.md
246 packages/sim/src/systems/festivals/index.ts
247 packages/sim/src/systems/fishing/index.ts
248 packages/sim/src/systems/fishing/model.ts
249 packages/sim/src/systems/index.ts
250 packages/sim/src/systems/mines/combat.ts
251 packages/sim/src/systems/movement/index.ts
252 packages/sim/src/systems/registry.ts
253 packages/sim/src/systems/shops/index.ts
254 packages/sim/src/systems/villagers/README.md
255 packages/sim/src/systems/villagers/index.ts
256 packages/sim/src/systems/villagers/schedules.ts
257 packages/sim/src/systems/villagers/types.ts
258 packages/sim/src/systems/weather/index.ts
259 packages/sim/test/animals-integration.test.ts
260 packages/sim/test/animals-system.test.ts
261 packages/sim/test/community-restoration.test.ts
262 packages/sim/test/festivals-system.test.ts
263 packages/sim/test/fishing-system.test.ts
264 packages/sim/test/integration2-hooks.test.ts
265 packages/sim/test/mines-system.test.ts
266 packages/sim/test/registry.test.ts
267 packages/sim/test/villagers-integration.test.ts
268 packages/sim/test/wave3-integration.test.ts
269 ```
270