Exact source used by this build. SHA-256: 1201ac53f63b00fef12dde284e7802ef468acfba877ff2079a1cc5d60fa34b72.
1 # Wave-3 integration and core hardening
2
3 Changes are uncommitted. No deployment, credential access, remote push, or history
4 rewrite was performed. No runtime dependency was added. The initial worktree was
5 clean. Only explicitly authorized generated test persistence was removed.
6
7 ## Integration gate
8
9 Part A completed before hardening began: `bun run check` passed **320 tests**,
10 67,800 assertions, with all 15 content domains validated. An earlier run passed
11 311 tests but its live workerd socket closed while source edits were still in
12 progress; the stable-source rerun passed.
13
14 - **Maps/fishing:** each map's authored water GIDs carry a validated habitat tag.
15 Fishing coverage is derived from these tags and actual ground tiles, eliminating
16 the old coordinate rectangles. Land and bridges remain dry; mixed habitats are
17 supported. Farm pond, river, beach ocean, mountain lake, rainforest river and
18 bog are covered, plus the canyon hot spring. Legendary depth remains reachable.
19 - **Mines:** the entrance resolves from the mountain mine POI at content load,
20 retaining runtime warp overrides and removing duplicated fallback coordinates.
21 Tests use the actual mountain map rather than a small obsolete fixture.
22 - **Crafting/fishing:** crafted crab pots and bait use fishing-owned placement and
23 consumption helpers. Saved crafted item IDs are retained. Both recipe paths
24 share trapper ingredients. A cooking recipe now accepts actual fish; forage
25 cooking and artisan processing are exercised together.
26 - **Mines/crafting/shops:** integration tests mine ore, smelt it in a furnace,
27 obtain a geode and crack it at the blacksmith. Food restores combat-owned health;
28 the crafting compatibility view no longer overrides late-sleep/pass-out health.
29 - **Shared code:** the merged clock and registry already composed correctly, so
30 no competing timing implementation was introduced. Online elapsed hooks split
31 at calendar boundaries; offline hooks advance only machines; pause freezes both.
32 Inventory, tools and farming retain their owned chest/pickup, blast, crop-removal
33 and fertilizer helpers. New tests run these systems together. One registry
34 update-cadence selector drives fast simulation timers; durable clock/checkpoint
35 alarms have independent deadlines. Frequent input and visual events now share
36 generic batched/transient persistence metadata.
37
38 ## Findings
39
40 | # | Result | Change and evidence |
41 | --- | --- | --- |
42 | 1 | Fixed | Client persists a cryptographic enrollment secret before opening the socket. Allocation is idempotent by its hash. Lost second-device responses and restart recovery retain the same slot. |
43 | 2 | Fixed | 30-second bounded checkpoints coalesce position/clock/progress state. Unchanged moves are no-ops. Durable gameplay outcomes journal pending state immediately. Disconnect/day-end flush; fast simulation avoids per-frame durable alarms. Repeated object recreation cannot reset the checkpoint deadline. Movement, fishing and combat replays enforce budgets. |
44 | 3 | Fixed | Authenticated reconnect replaces the previous socket. Its attachment is invalidated before close; delayed packets/close callbacks cannot disconnect the replacement. Close code 4001 stops older tabs from retrying and replacing each other. |
45 | 4 | Fixed | All presence flags are reconciled against live sockets before any hooks run. Recreating the real DO with no sockets and mixed stale sleep flags leaves the calendar unchanged. |
46 | 5 | Fixed | Versioned static-map fingerprint drives reconciliation even for foundation-v1 saves. Missing areas/static corrections/POIs update while crops, soil, paths, repairs, system state and resized crop/fertilizer indexes survive. Actual DO reload covered. |
47 | 6 | Fixed | Tiny global sleep-readiness state crosses area boundaries. Named sleep events and persistent local waiting UI show who is ready. |
48 | 7 | Fixed | Authority accepts sleep only within reach of a bed POI inside the player's current starter home. NPC/inn beds are not implicitly player-owned. Existing overnight loops now walk home and return to work. |
49 | 8 | Fixed | `areaSystems` patches and separate `area_state` SQL rows update mutable slices without replacing static maps/chunks. Regression patch is under 500 bytes and writes exactly two rows (world + area state), leaving every chunk untouched. Removed generated areas also leave patches and persistence. |
50 | 9 | Fixed | `addPlayer` passes configured rules into initialization hooks; first real-server join receives registered starter recipes. |
51 | 10 | Not reproduced | The merged authoritative item catalog already requires a crop's produce ID to equal its crop ID. A regression proves a linked but renamed produce item is rejected. No farming workaround added. |
52 | 11 | Fixed | Overlapping landscape media rules still reproduced. Reset width/transform and reserve safe-area control lanes. At 852×393 the calculated hotbar moves from −148.9…404.9 px to 128…691 px. |
53 | 12 | Fixed | Original farmhouse corner still reproduced. Prediction and authority now share swept geometry; prediction also checks the last transmitted position so accumulated frames cannot cut corners. Covers the original 16 ms case and 120 frames of packet batching. |
54 | 13 | Not reproduced | Original target (13,1) now lies inside the actual non-tillable warp. Every current farm tillable target avoids interception; regression covers over 2,900 targets. No warp behavior change needed. |
55
56 ## Write measurements
57
58 All rows below are 60-second deterministic replays through the production DO and
59 real in-memory SQLite. Two socket adapters supply messages; separate existing
60 suites exercise actual TCP WebSockets and local workerd. SQL changes include
61 inserts, updates and deletes; totals add alarm writes. These are local counters,
62 not deployed billing telemetry. Setup/join/checkpoint costs precede measurement.
63
64 | Replay | SQL rows | Alarm writes | Alarm invocations | Total writes/min |
65 | --- | ---: | ---: | ---: | ---: |
66 | Movement/stationary before (two clients, 10 Hz each) | 6,229 | 399 | 199 | 6,628 |
67 | Stationary after | 4 | 10 | 10 | 14 |
68 | Moving after | 8 | 10 | 10 | 18 |
69 | Fishing before progress fix (75 ms polls) | 7,155 | 10 | 10 | 7,165 |
70 | Fishing after, same 1,578 progress inputs and five catches | 51 | 10 | 10 | 61 |
71 | Combat after, two clients attacking at 10 Hz | 10 | 10 | 10 | 20 |
72
73 Movement writes fall by **99.7%**. Four hours project to 4,320 movement writes or
74 14,640 for the measured active-fishing loop. Eight hours of movement project to
75 8,640. The architecture document records request/duration projections and the
76 remaining allowance for economic transactions. These are workload projections,
77 not a universal daily cap. Visual fishing/combat events still broadcast; catch,
78 kill, loot and economic outcomes journal immediately and survive pre-checkpoint
79 restarts. Transient progress no longer evicts catches from the 100-event history.
80
81 ## Regression coverage and existing test updates
82
83 New suites cover merged timing and cross-system recipes/health; initialization,
84 sleep readiness and beds; enrollment/reconnection/restart presence; bounded
85 movement/fishing/combat writes; journal/checkpoint/restart consistency; compact
86 area slices and retirement; layout and current-map warp evidence. Existing map,
87 content, movement and migration suites gained targeted regressions.
88
89 No tests were deleted. Obsolete map fixtures moved to authored metadata. The
90 invalid ingredient-category test now uses a genuinely absent category because
91 fish exist after integration. Sleep-loop setup walks to a real bed, retaining
92 overnight/crop/machine/wallet assertions. Persistence assertions reconstruct the
93 checkpoint plus durable journal instead of assuming every alarm compacts SQL.
94 The old duplicate-socket rejection expectation was replaced with same-identity
95 reconnection, replacement-close and continued observer checks, as finding #3
96 requires. Multiplayer clock behavior remains governed by
97 `docs/time-and-multiplayer.md`; the requested offline-machine exception is now
98 explicit there.
99
100 ## Validation and limits
101
102 - `bun run check`: **356 passed, 0 failed**, 71,699 assertions across 65 files (68.62 s). Includes all workspace typechecks, feel-lab typecheck, real workerd/WebSocket tests, content validation and all new regressions. Validated 15 domains, 12 crops, 206 items and eight Tiled areas.
103 - `bun run --cwd apps/client build`: **passed**, 244 modules transformed, 423 ms.
104 - `bun test apps/server/test/write-budget.test.ts apps/server/test/mines-write-budget.test.ts apps/server/test/fishing-write-budget.test.ts`: **11 passed**, 82 assertions; measured values above.
105 - `bun test packages/sim packages/content apps/client`: **271 passed** at the focused checkpoint (before final budget additions).
106 - `git diff --check`: **passed**.
107 - Temporary `tamarack-server-test-*` directory count after the final full run: **0**. `apps/server/.wrangler` is now approximately **9.7 MB**, including the preserved 9.3 MB local world.
108
109 The first final check exposed one remaining old map test that inspected only
110 checkpoint player rows after an alarm. It now verifies checkpoint-plus-journal
111 recovery and additionally checks scoped `areaSystems` patches. The subsequent
112 full check passed. No gameplay assertion was removed.
113
114 Chrome aborted under the macOS sandbox, so phone screenshot QA was unavailable.
115 Layout was checked through stylesheet cascade/box geometry and client tests.
116 The production client build succeeds with the existing warning about a chunk over 500 kB (JavaScript 2,797.43 kB, gzip 507.77 kB).
117 Art asset wiring was not part of the requested integration/hardening changes.
118
119 The workerd suite now uses one temporary directory for persistence, configuration
120 and logs, reuses it only across deliberate restarts within that suite, and removes
121 it in teardown. Approximately 1.2 GB of authorized accumulated test state was
122 removed after the integration gate; the 9.3 MB local development world is preserved. Existing dependencies (~409 MB) remain necessary for builds/tests; current client output is 2.7 MB, generated catalogs 44 KB, and retained ignored run evidence approximately 6.4 MB.
123
124 ## Files changed
125
126 ```text
127 apps/client/src/core/device-token.test.ts
128 apps/client/src/core/device-token.ts
129 apps/client/src/core/session.ts
130 apps/client/src/net.test.ts
131 apps/client/src/net.ts
132 apps/client/src/styles.css
133 apps/client/src/systems/fishing/index.ts
134 apps/client/src/systems/movement/geometry.test.ts
135 apps/client/src/systems/movement/geometry.ts
136 apps/client/src/systems/movement/index.ts
137 apps/client/src/systems/sleep/index.ts
138 apps/client/test/hotbar-layout.test.ts
139 apps/client/test/sleep.test.ts
140 apps/client/test/warp-interactions.test.ts
141 apps/server/src/index.ts
142 apps/server/src/migration.ts
143 apps/server/test/core-hardening.test.ts
144 apps/server/test/crafting-loop.test.ts
145 apps/server/test/fishing-multiplayer.test.ts
146 apps/server/test/fishing-write-budget.test.ts
147 apps/server/test/harness.ts
148 apps/server/test/items-loop.test.ts
149 apps/server/test/maps-migration.test.ts
150 apps/server/test/maps-world.test.ts
151 apps/server/test/mines-loop.test.ts
152 apps/server/test/mines-write-budget.test.ts
153 apps/server/test/server.test.ts
154 apps/server/test/write-budget.test.ts
155 docs/architecture.md
156 docs/extending.md
157 docs/time-and-multiplayer.md
158 docs/w3-integration-hardening-report.md
159 packages/content/data/crafting/crafting.json
160 packages/content/data/fishing/NOTES.md
161 packages/content/data/fishing/fishing.json
162 packages/content/data/maps/beach.json
163 packages/content/data/maps/bog.json
164 packages/content/data/maps/canyon.json
165 packages/content/data/maps/farm.json
166 packages/content/data/maps/mountain.json
167 packages/content/data/maps/rainforest.json
168 packages/content/data/maps/town.json
169 packages/content/data/maps/woods.json
170 packages/content/data/mines/mines.json
171 packages/content/src/domains/crafting/index.ts
172 packages/content/src/domains/crafting/schema.ts
173 packages/content/src/domains/farm/schema.ts
174 packages/content/src/domains/fishing/index.ts
175 packages/content/src/domains/fishing/schema.ts
176 packages/content/src/domains/maps/loader.ts
177 packages/content/src/domains/maps/schema.ts
178 packages/content/src/domains/mines/index.ts
179 packages/content/test/crafting-content.test.ts
180 packages/content/test/fishing-content.test.ts
181 packages/content/test/items.test.ts
182 packages/content/test/mines-content.test.ts
183 packages/sim/src/protocol.ts
184 packages/sim/src/systems/crafting/effects.ts
185 packages/sim/src/systems/crafting/index.ts
186 packages/sim/src/systems/crafting/materials.ts
187 packages/sim/src/systems/crafting/model.ts
188 packages/sim/src/systems/crafting/placement.ts
189 packages/sim/src/systems/energy/index.ts
190 packages/sim/src/systems/fishing/index.ts
191 packages/sim/src/systems/fishing/integration.ts
192 packages/sim/src/systems/fishing/mechanics.ts
193 packages/sim/src/systems/fishing/model.ts
194 packages/sim/src/systems/index.ts
195 packages/sim/src/systems/mines/combat.ts
196 packages/sim/src/systems/mines/index.ts
197 packages/sim/src/systems/mines/model.ts
198 packages/sim/src/systems/movement/geometry.ts
199 packages/sim/src/systems/movement/index.ts
200 packages/sim/src/systems/registry.ts
201 packages/sim/src/types.ts
202 packages/sim/src/world.ts
203 packages/sim/test/areas-weather.test.ts
204 packages/sim/test/core-initialization-sleep.test.ts
205 packages/sim/test/fishing-system.test.ts
206 packages/sim/test/integration-timing.test.ts
207 packages/sim/test/mines-system.test.ts
208 packages/sim/test/sim.test.ts
209 packages/sim/test/wave3-integration.test.ts
210 ```
211