Changelog (status history, rounds 4–9)
The status notes and round-by-round change lists that used to sit in CONTINUE_HERE.md, moved here on 2026-10-06 so the status file stays short. History only; the current status and next actions are in CONTINUE_HERE.md.
- 2026-10-11 M1-04C (partial; 1,000-bot soak):
pnpm zone:bots -- --steps 100,250,500,1000 --step-s 30(each step's bots connect over the first half of the step) and per-second series in the metrics (connected, bytes per bot down/up, RTT p50/p99 from atomic 0.5 ms buckets, process RSS), load average each minute, memory drift over the hold (least-squares RSS slope,loadTest.memoryDriftPercent).tools/zone-soak-report.pydraws the Grafana-like PNG and the summary. Soak (120 s ramp + 600 s hold, load average 201–378 on 8 cores): 1,000/1,000 connected, 0 disconnects, down 2.42 KB/s mean, RSS drift −4.27 %; loop p99 1,686 ms and 1,754 dropped ticks from the load (tick-thread CPU 4.51 ms + workers 7.86 ms per loop). Evidencelogs/evidence/M1-04C/; re-run as M1-04D on a quiet Mac. - 2026-10-11 DEC-20261011-01 (test platforms, owner decision): ADR-032 amended. Every client milestone is tested on Web
(Chrome on the Mac and the phone), the Android APK (nubia NX709S) and Windows (Unity Mono x86_64 player built on this
Mac, run by the owner on his Windows PC); macOS and iOS are paused (code kept, unmaintained; release targets of
ADR-024 unchanged). The Windows sim DLL is built on the owner's PC: no SDK/CRT download here (
logs/reviews.jsonlM0-11D answered). Guide section#test-platforms;reference-devices.jsonaddsowner_windows(unprobed) and marks the Mac's native app paused (probes kept); M2-08/M2-10 retargeted; new card WIN-01 in M1 (proposed). Brief, unity-batchmode skill, UNITY_TOOLKIT, PERFORMANCE and theunity-runnot-tested reasons updated. - 2026-10-11 M1-04B (snapshot pool, partial):
services/zone/src/pool.rsShardPool(std threads): clients in stable shards (slot mod 4), shard 0 on the tick thread, 3 workers read the tick's state and return their shard at the barrier; byte-identical to one shard and allocation-free (tests/snapshot_pool.rs).netcode.jsonserver.snapshotWorkers4 andloadTest.botMix.fieldSpawnShare0.5 (proposed); profile phasepoolWaitand worker CPU. 1,000 bots 80 s: loop p99 12.1 ms (was 32), CPU 2.9 + 6.5 ms/tick, 0 disconnects, 3.7 KB/s/bot; the single-threaded path under load 55 stalled (p99 2.6 s). Soak,--steps, memory drift and chart → M1-04C. - 2026-10-11 M1-04 part A (bots + 1,000-bot run, partial): new crate
services/bots(pnpm zone:bots, no external crates): N bots on 4 poll(2) workers with a linear connect ramp, waypoint wander (25% crowd the town, 75% walk to a hunting zone), casts and chat as bot-side timers (protocol v1 has no action bits or chat message), in-process server with a per-phase loop profile (net/profile.rs: ingest, tick, snapshot build, hand-off; tick-thread CPU; 1 s windows).netcode.json → loadTestholds the doc's load-test plan (+ proposedbotMix). 200-client load check re-run: PASS p99 5.5 ms at load 3. 1,000 bots, 20 s ramp + 60 s hold: 0 disconnects, 8.5 KB/s/bot mean, 10.6 max; loop p99 32 ms (CPU 15.1 ms/tick, snapshot build 11.7 ms) → M1-04B parallelises snapshots, then the 10-min soak. - 2026-10-11 M1-03D (zone part D, socket load check):
pnpm zone:loadcheck(services/zone/src/bin/loadcheck.rs) joins 200 headless clients to an in-process server for 10 s (random walk, input per tick, ack per snapshot, ping per second) and writes loop p50/p99/max, late/dropped ticks, bytes per client (down/up), snapshot sizes, RTT, closes and the tick thread's CPU time; exits 1 on any breach. Run at load average ~100 on the 8-core Mac: 200/200 joined and closed cleanly, 0 stale/dropped inputs, 0 skipped frames, downstream max 13.9 KB/s (cap 32), but loop p99 84.7 ms (target 15) with tick CPU 6.4 ms/tick (34 % of wall) - load, idle re-run owed.zone:benchre-run passes (p99 ≤ 12 ms);zone:snapbenchbandwidth unchanged. Client:bytes_out,close()reports a clean close;ServerReportgains mean tick, catch-up ticks and stalls. Evidencelogs/evidence/M1-03D/. - 2026-10-11 M1-03C (zone part C, WebSocket endpoint; load check split to M1-03D):
services/zonesrc/net/—ws.rsRFC 6455 onstd(SHA-1, base64, upgrade, masked/continuation/control frames; no crates, workspace still builds offline),server.rs(acceptor, reader + writer thread per connection, one bounded event queue into the tick, per-client pool of frame buffers out; hello → join or close 4001; inputs remapped onto the entity's server sequence; acks move the baseline; ping → pong; idle timeout 4002; leavers are stopped and parked, new clients reuse them; graceful 1001 shutdown),client.rs(blocking Rust client),bin/zone.rs(pnpm zone:run). Close codes and the session inzoen.schema.json;netcode.json → serverproposed (port 7310, timeouts, queues, spawn spread; spawn at the start waypoint's zone centre). Teststests/ws.rs,tests/server.rs; evidencelogs/evidence/M1-03C/. - 2026-10-11 M0-11D (one-simulation spike part D; M0-11 done):
build-plugin.mjs iosbuilds the aarch64-apple-ios staticlib at iOS 15.0 (2,333,096 B afterstrip -S; only-lSystem -lc -lm), checks every member is iOS and the 9 exports, and links the C smoke with Xcode 26.6's iPhoneOS SDK (not run; 229 std members carry LLVM 23 bitcode that the link drops). Installed asPlugins/iOS/libzoen_sim_ffi.a(iOS player only);Zoen.BuildaddsZOEN_SIM_STATICto iOS builds too.build-plugin.mjs windowsbuilds the x86_64-pc-windows-msvc staticlib (3,701,330 B, COFF); the DLL is blocked on the Windows SDK and MSVC CRT import libraries (Microsoft licence, owner item inlogs/reviews.jsonl); Windows-x64-only import rules are ready. EditMode 81/81. Spike reportlogs/evidence/M0-11D/spike-report.md; ADR-029 records the result: one simulation confirmed with Windows/iOS as open risks. - 2026-10-11 M0-11C2 (one-simulation spike part C2, Web):
build-plugin.mjs webinstalls the Emscripten 3.1.39 staticlib asPlugins/WebGL/libzoen_sim_ffi.a;SimPluginImport.ApplyWebkeeps it to the Web player (editor, Android and every other player off) andZoen.BuildaddsZOEN_SIM_STATICto a Web build when it exists. The Web player (11,800,723 B, +37,947 B against the 2026-10-08 build) runs it in headless Chrome 155: ZOEN_SIM finalHashbb46012ea5aaaebf= the golden vector, allMatch over 4 scenarios in all four smoke cases, 0 console errors; median step 70–100 ns/tick for 1 mover and 0.16–0.21 ms/tick for 5,000. The Web bench times 20,000/40-tick samples (Chrome's ~100 µs timer read 0 ns for 200 ticks).web-smoke.mjs --sim; EditMode 79/79. Evidencelogs/evidence/M0-11C2/. Next: M0-11D (Windows/iOS, ADR-029 result). - 2026-10-11 M0-11C (one-simulation spike part C, Web, partial):
tools/sim/build-plugin.mjs webbuildscrates/zoen-sim-ffias awasm32-unknown-emscriptenstaticlib (stable rustc 1.99, LLVM 23,-C panic=abort) and checks it with the Emscripten 3.1.39 (LLVM 17) bundled with Unity 6000.3.25f1: the objects link with its wasm-ld once the LLVM 20+ feature namesbulk-memory-optandcall-indirect-overlongare dropped fromtarget_features; the C smoke linked by its emcc runs in its Node with the macOS/Android hash. Archive 3,662,566 B. Report:logs/evidence/M0-11C/plugin-web.json. Unity install, Web build and browser smoke remain (M0-11C2). - 2026-10-11 M0-11B (one-simulation spike part B, Android):
tools/sim/build-plugin.mjs androidlinkscrates/zoen-sim-ffiforaarch64-linux-androidwith the NDK r27c bundled with Unity 6000.3.25f1 (316,552 B, 16 KB aligned), placed asPlugins/Android/arm64-v8a/libzoen_sim_ffi.so(ARM64 player only,SimPluginImport.cs). The IL2CPP APK (32.7 MB) loads it on the nubia NX709S: ZOEN_SIM finalHashbb46012ea5aaaebf= the golden vector, allMatch on every tier, 0 app errors; median step 54.5 ns/tick for 1 mover and 0.15–0.16 ms/tick for 5,000 (macOS player: 108 ns, 333 µs).android-smoke.mjs --sim+tools/unity/sim-expect.mjs. Evidencelogs/evidence/M0-11B/. Next: M0-11C (Web). - 2026-10-10 WIKI-EVIDENCE-01 (evidence on the wiki):
tools/evidence-index.mjswriteslogs/evidence-index.json(generated; per task: files with kind image/video/audio/text/json/other and size) fromgit ls-filesunderlogs/evidence/(git-ignoredframes/,pw-artifacts/,*.logstay out), makes cached WebP thumbnails ≤ 480 px and video posters with ffmpeg (apps/wiki/public/evidence-thumbs/, 8 MB, git-ignored) and hard-links the files intoapps/wiki/public/evidence/(git-ignored; the static export copies them toout/). Runs on task-logfinish/reportand the wiki dev/build. Ledger: evidence totals, an Evidence column, task cards with thumbnail strips (contact sheets first), inline clips (preload="none", poster) and log links, filter All / Has evidence / Visual only (?ev=), and/ledger/<ID>/with the full gallery, excerpts, tests and notes. Backfill: 96 folders, 866 files (71 tasks with images, 11 with clips, 45 with text/json). Spectests/ledger-evidence.spec.ts; rule in AI_WORKFLOW §6. - 2026-10-10 M1-03B (delta snapshots + protocol; WebSocket split to M1-03C):
packages/protocol/zoen.schema.json(hello, join, input, snapshot v1, ack, ping, pong; protocolVersion 1) with the hand-written reference codeccrates/zoen-protocol(no deps; bit packing, fixed messages, snapshot encode,ClientViewdecoder) and a Rust test that ids/versions/fields match the schema plusprotocol.test.mjsagainstnetcode.json → snapshot(new group: doc bit widths, rates, 32 KB/s cap; proposed 16 mm quantum, 10-bit HP permille, 16-bit entity ids, 32-frame baseline history, idle/run anim states).zoen-zonesnapshot.rs: nearest-150 replicated set, Quake-3 baseline by acked tick (full snapshot when older than the history), leaves always, enters + due changes within the 1,600 B packet, priority accumulators giving 20/10/4 Hz by band; zero allocations. Bytes per client (everyone walking):logs/evidence/M1-03B/snapshot-bench.json. - 2026-10-10 M1-03 part A (partial; M1-03B holds snapshots, protocol, WebSocket):
services/zone(cratezoen-zone, workspace members nowcrates/*+services/*): puretick(state, inputs, out)=zoen-simstep (reused, golden parity test) → uniform-grid spatial hash (16 m cells, intrusive lists, O(1) insert/move/remove, radius query) → per-client AOI sets (90 m / town 70 m, enter/leave diffs, bitset + member list); fixed-rate scheduler (absolute deadlines, no drift, catch-up ≤ 4 ticks then drop + re-anchor, overrun/lateness metrics, 10 µs histogram). Newcrates/zoen-data(JSON reader moved out ofzoen-sim-tools). Numbers moved tonetcode.json(tick budget and targets, grid, radii, channel caps from NETCODE_1000.md; proposed:maxTicksPerFrame4,leaveMarginM5,maxSize512). Tests: randomized brute-force checks for the hash and the sets, scheduler on a test clock, 0 allocations per tick at full channel size.pnpm zone:bench(one thread): p99 0.80 / 2.51 / 4.05 ms for 1,000 movers, 1,000 players + 4,000 monsters, and a 1,000-player town crowd; 0 allocations (logs/evidence/M1-03/tick-bench.json). - 2026-10-10 MODEL-01E (done):
tools/model-views.pyno longer cuts the Bellwhisker Jerboa at its tail. New STUB rule: a valley cut that leaves on one side under 10 % of the drawing, made (≥ 90 %) of one part lying mostly across the cut (a tail's tuft), is skipped (jerboa tuft 6 %; real view boundaries 20–45 %). Jerboa and elite side views now hold the whole body; the other 38 cuts are byte-identical. New--checkmode re-splits all 40 and flags a view under 10 % of the drawing, a crop whose largest part is under 80 % (two views) or an implausible aspect. Evidencelogs/evidence/MODEL-01E/. - 2026-10-10 M0-06 (done; owner approval pending): ADR-003 (Rust zone servers, now also the wire protocol: one schema
packages/protocol/zoen.schema.json→ Rust + C#, bit-packed binary over WebSocket,protocolVersion/dataVersion), ADR-004 (monorepo: pnpm + Cargo + Unity/.NET side by side, one-way data flow,tools/verify.mjsand CI) and ADR-005 (skill system, data references) gained Status, Context, Decision, "Built in M0" and Consequences; ADR-024 gained what M0 built (Unity 6000.3.25f1 client,com.zoen.core, runner, pinned test packages, M0-11 part A on macOS) and Consequences. The M0-11 result stays pending in ADR-029. New "Proposed" status key.tools/docs-lint.mjsnow fails when a full-format ADR lacks a Status, Context, Decision or Consequences line (11 checked; the short round 1–5 records are listed as exempt). Kept consistent: ARCHITECTURE.md (shared-sim and protocol rows), ENGINE_PLATFORMS.md (vectors inpackages/sim-golden),stack.json(note, protocol path), the decisions widget and the M0-06 card. Owner gate line inlogs/reviews.jsonl. - 2026-10-08 M0-11 (partial; part A of the one-simulation spike, ADR-029):
crates/zoen-sim-ffi(cdylib + staticlib) is a C ABI over the zoen-sim step (include/zoen_sim.h, ABI version 1): create/destroy a world with fixed capacities, spawn, push inputs (all or nothing), step N ticks, read hash/state/actors/events into caller buffers; error codes, no allocation after create, panic-free code withcatch_unwindas a backstop (a panicking world is poisoned).node tools/sim/build-plugin.mjs macosbuilds thepluginprofile (LTO, arm64 dylib 406 KB), runs a C smoke, checks the exports and installs the dylib and the golden copy into Unity. Unity:ZoenSimNativeP/Invoke (blittable, no per-tick allocation;__Internalreserved for Web/iOS behindZOEN_SIM_STATIC),SimGoldenreplay,SimPluginImport(macOS editor + player only, written byProjectSetup),SimBootChecklogsZOEN_SIM. EditMode 76/76 (11 new: all 4 golden scenarios match every tick and event, layouts, error codes, 0 GC per tick, import settings); macOS build +macos-smoke.mjs --simpass (finalHash bb46012ea5aaaebf matches; player step 108 ns/tick for 1 mover, 333 µs/tick for 5,000 movers incl. C# input fill). Evidencelogs/evidence/M0-11/. Next: M0-11B (Android). - 2026-10-08 M0-07 (done): Unity toolkit gate without MCP — the CoplayDev/unity-mcp smoke test was skipped by owner
direction (UNITY_TOOLKIT.md, ENGINE_PLATFORMS.md and stack.json say "no MCP").
com.unity.test-framework1.6.0 (built-in) andcom.unity.test-framework.performance3.5.0 (packages.unity.com; was resolved at depth 3 through Collections) are direct pins, recorded in LICENSES.md (Unity Companion License) and a gate record in UNITY_TOOLKIT.md (files the package writes; its build-timeAssets/Resources/PerformanceTestRun*files ship in players, strip before release). New PlayModeSkyPerformanceTests:SkyModel.Sample+SkyLook.Evaluateover a whole day andSkyController.Tick(rain, cycle off) record 0 GC allocations in 200 single-call samples, against an allocating control that records exactly 1 per call; Boot frame times with the sky are recorded (no budget: editor numbers).unity-run.mjspasses-perfTestResultsand prints median/p95 per sample group (summarisePerf, unit-tested ontools/unity/fixtures/perf-results.json). PlayMode 6/6, EditMode 65/65. Evidencelogs/evidence/M0-07/. - 2026-10-08 M0-05E (done; M0-05 complete): on Android the probe is logged as numbered
ZOEN_PROBE_PART i/nlines of at most 800 UTF-8 bytes without a stack trace (ProbeJson.Lines/Joinin the core: never cut inside a character or next to whitespace; 5 new xunit tests, core 135/135); macOS and the Web keep the oneZOEN_PROBEline.probe-contract.mjsjoins the parts by number (a missing part is an error;hasProbefor polling) andprobe.mjs android-apkwaits for a whole probe. Android rebuilt (135 s); the APK probe on the nubia NX709S passes the contract (native-phone, Vulkan 1.1 on Adreno 730, 18 GB class memory, ASTC/BC/ETC2, maxHz 120, thermal 0, Mid from the cached benchmark) and is recorded inownerTestDevices[owner_android].probes;reference-devices.json → probegainspartLine,androidLineBytes,partNote. The device-probes data test requires all four targets and re-joins the saved logcat parts (logs/evidence/M0-05E/apk-logcat-probe-parts.txt) to the recorded probe. Merged table:logs/evidence/M0-05C/probe-summary.txt. - 2026-10-08 M0-05D (partial; M0-05E holds the APK probe):
probe.mjs phone-chromeon the nubia NX709S (Chrome 154, WebGL 2 via ANGLE on Adreno 730, deviceMemory 8 GB cap, max texture 4096, Mid) passes the contract and is recorded inownerTestDevices[owner_android].probes(model line now from the measured getprop facts).at()inprobe-contract.mjsresolves dotted getprop keys (host.props.ro.soc.model). Android rebuilt (8 min); the APK ran but Unity's Android player cut theZOEN_PROBEentry at 1023 bytes (logs/evidence/M0-05D/), so the APK probe waits for a splitZOEN_PROBE_PARTline in M0-05E. Data 176/176. - 2026-10-08 M0-05C (done; M0-05D holds the phone): rebuilt macOS (3 min) and Web (40 min) and ran
probe.mjson the Mac app (Metal, Apple M3, 24 GB, astc/bc/etc2, High) and Mac Chrome 155 (WebGL 2 via ANGLE Metal, deviceMemory 16 GB, Mid); both pass the contract. Gatherer fix:gpu.msaaMaxasked Unity for 1 sample and always read 1 (now 4 on both).reference-devices.json → ownerTestDevices[owner_mac].probesholds the measured, dated records; the device-probes data test checks them againstlogs/evidence/M0-05C/probe-*.json(6/6);probe-contract.mjs <file>re-checks saved records. EditMode 65/65. Phone not in adb: phone Chrome, Android rebuild and APK probe move to M0-05D. - 2026-10-08 M0-05B (done, part 2; M0-05C holds the device runs): Unity gatherer
Runtime/Diagnostics/CapabilityProbe.cs(SystemInfo/Screen facts, AndroidBuild.SOC_MODELand PowerManager thermal status/headroom; logsZOEN_PROBE {json}once after the first scene; never readsSystemInfo.deviceName),ZoenWebProbeinZoenDevice.jslib(player GL context or a probe canvas: WebGL/GLSL version, unmasked renderer when allowed, extensions, max texture/renderbuffer/samples, deviceMemory, cores, DPR, screen), EditModeCapabilityProbeTests(3; EditMode 65/65),tools/unity/probe.mjs(macos-app, mac-chrome, phone-chrome, android-apk + host facts →probe-<target>.json,probe-summary.txt) andprobe-contract.mjs(data test in device-probes, 5/5). M0-05C: rebuild macOS and Web, run the Mac app and both Chromes, recordownerTestDevices[].probes; M0-05D: Android rebuild and APK probe. - 2026-10-08 M0-05 (done, part 1; M0-05B holds the rest): capability-probe model in the engine-free core
(
packages/core-cs/Zoen.Core/Devices:ProbeReport,ProbeClassifier— GPU family, ANGLE GPU name, API family/version, texture families astc/bc/etc2, OS memory rounded to a common size —ProbeJsonone-line writer, WebGL facts reader andProbeContract), xunitCapabilityProbeTests(core:test 130/130).reference-devices.jsongainsprobe(ZOEN_PROBE schema v1: fields, webFields, the four ADR-032 targets) andprobe.status: pendingon the three Low references;device-probes.test.mjsguards both. M0-05B: Unity gatherer + jslib,tools/unity/probe.mjs, rebuilds, owner probes. - 2026-10-08 M0-12I (done; completes M0-12, the chain M0-12…M0-12I): Android dev APK rebuilt (32.5 MB, 2612 s at
load ~235). APK smoke on the NX709S (4 tiers) passes plain and with
--gmnight + sandstorm: 0 app errors,platformNoise31/31/31/40 as in M0-04C (same 9 patterns),ZOEN_SKYevery run (night sandstorm: sheets 0/200/500/800 particles on Low/Mid/High/Ultra, fog 0.054). Phone Chrome--cdpsmoke passes 4 cases with 0 console errors (85 known warnings, as in M0-04C); with--gmnight + sandstorm in portrait the GM panel sits at the bottom, clear of the FPS overlay (logs/evidence/M0-12I/web-phone-chrome-gm-default.png). Phone smokes usedADB=~/Library/Android/sdk/platform-tools/adb(the server other sessions share); cleanup removed only this task'sadb reverse/forward. - 2026-10-08 M0-12H (partial, split at 150k context; Android build, APK smokes, phone Chrome smoke, phone night shot
and the portrait GM-panel shot move to M0-12I): macOS and Web dev builds rebuilt; plain macOS smoke (4 tiers), Web
smoke in Mac Chrome (4 cases, 0 console errors, plus
--gmnight + sandstorm and--gm-off) pass with aZOEN_SKYline every run. High sky review passes (contrast 5.9–16.8, min 3); the night sandstorm sheets read as thin wind streaks, solook.particlesstays as proposed; owner look review pending inlogs/reviews.jsonl. New sharedtools/unity/sky-expect.mjs(theZOEN_SKY/ZOEN_GMchecks) in the macOS, Web and Android smokes; Web takes--gm/--gm-off(?gm-send=,?gm=off) and--cases, Android--gm/--gm-off(intent extras) and--tag; GM lines may be separated by,becausetask-log.mjsruns its command through a shell. - 2026-10-08 M0-12G (partial, split at 150k context; the macOS rebuild, plain smoke and High sky review move to M0-12H,
Web/Android to M0-12I): the first PlayMode tests,
Tests/PlayMode(asmdefZoen.Tests.PlayMode, any platform,UNITY_INCLUDE_TESTS) withBootSkyPlayTests: Boot loads with no errors; the day follows the stand-in clock over frames (x1, within 100 ms); the dev GM panel over Boot sends/gm weather sandstorm+/gm time night(fog up, key light down, sheets) and returns to the exact baseline look; on Low at night in a sandstorm (no weather particles,budget.lowTierWeatherParticles0) the telegraph's best contrast is 16.6 (min 3). PlayMode 4/4, EditMode 62/62. - 2026-10-08 M0-12F (partial; PlayMode tests, sky review re-run, Web/Android builds and smokes move to M0-12G): the dev
GM panel sits bottom-right and
GmSkyPanel.Roomkeeps it in the larger of the band below / column right of the FPS overlay (max size = room, rows scroll, hidden below 140x48 pt), so it never covers the overlay; EditModeGmPanelNeverCoversTheFpsOverlay(Retina window, 1080p, phone landscape, 390x844 portrait). Sandstorm look (proposed):look.particles.kinds.*.gust(per-particle velocity spread),look.particles.nearFade2.5 m (shader fade from the camera), sheets 0.05 m x stretch 16 (thin 0.8 m streaks, was 0.35 m x 3 blobs). EditMode 62/62. - 2026-10-08 M0-12E (done):
macos-smoke.mjstakes--gm "<cmds>"(sent as-zoen-gm-send,+between words; expectsZOEN_GM panel=onand one reply per command),--gm-off(expectspanel=off, no panel) and--tag; every run needs aZOEN_SKYline, which now carries the fog density. macOS dev build smokes pass plain (4 tiers), GM night and GM off (Low);logs/evidence/M0-12E/night-gm.png. Dev-only-zoen-sky-review <dir>(Runtime/Gm/SkyReview.cs) steps through the review matrix and the four phases in clear weather and logsZOEN_SKY_REVIEWper frame;tools/unity/sky-review.mjsasserts contrast ≥minContrast(Low 5.9–16.6, High too) and that the fog changes the foggiest frame (43–46 % of pixels), then drawssky-review-<tier>.jpgandsky-phases-<tier>.jpg. EditMode 61/61. M0-12F: first PlayMode tests, Web + Android builds and smokes, GM panel off the overlay. - 2026-10-08 M0-12D (partial; macOS build, smoke and night screenshot move to M0-12E):
ProjectSetupwritesResources/Zoen_SkyRules.assetfromtime-weather.jsonand saves the Boot scene with exp2 fog on, no skybox, flat ambient, aSkyobject (SkyController, inactiveWeatherparticles with the foggedZoen/WeatherParticlematerial) and the placeholderGroundTelegraphwith the unlit, fog-exemptZoen/Telegraphshader (Transparent+100, data colours); both shaders are Always Included. Dev GM sky panelRuntime/Gm/GmSkyPanel.cs(#if ZOEN_GM || UNITY_EDITOR, made at runtime, buttons from the data's GM lists,-zoen-gm offhides it,-zoen-gm-sendfor evidence runs);Build.csaddsZOEN_GMunless-zoen-release; the FPS overlay shows a sky line. EditMode 60/60. - 2026-10-08 M0-12C (partial; Boot wiring, telegraph shader, GM panel, PlayMode and macOS move to M0-12D, Web +
Android to M0-12E): the Unity sky controller.
Runtime/Sky/SkyController.csreads time and weather only throughIServerClock(stand-inLocalSkyAuthority, server time = ms since start, the day starts mid-day), appliesSkyLookto one directional key light (sun/moon), flat ambient + ambient probe, exp2 fog and the camera clear colour, and runs one camera-following weather particle system at tier cap × weather share (none on Low); allocation-free per frame,ZOEN_SKYlines on state changes, no time-scale writes. AlsoSkyRulesAsset, the three-bandGroundTelegraphmesh builder and the render-basedTelegraphContrastProbe(not yet in the scene). EditMode 55/55 (6 new inSkyControllerTests.cs); Unity wrote the coreWorld/*.metafiles. - 2026-10-08 M0-12B (partial; the Unity side moves to M0-12C, Web + Android to M0-12D): the sky look model.
time-weather.jsongains the proposedlookblock (per-phase key light, sun or moon, with elevation, azimuth, colour and intensity, flat ambient, sky and exp2 fog; per-weather fog add, hue tint at the phase's brightness, key and ambient scales, particle share and kind;ambientFloor0.035; particle kinds dust, sheets and rain; telegraph fill#ff5a2afrom VFX.md with proposed light and dark edges andminContrast3, WCAG 1.4.11) andbudget.tierLiveParticleTotals(copied from PERFORMANCE.md: weather caps Low 0, Mid 200, High 500, Ultra 800).Zoen.Core/World/SkyLook.cs:SkyLookReader,SkyLook.Evaluate(pure, allocation-free; phase and weather blends, night floor) and the WCAG luminance and contrast helpers. xunit 96/96 (8 new inSkyLookTests.cs). - 2026-10-08 M0-12 (partial; the rest is M0-12B): the engine-free sky core in
packages/core-cs/Zoen.Core/World(ADR-030, look and sound only).TimeWeatherReaderreadstime-weather.json(day length, phase shares and blend, weather states, area weather, hold/blend, weights, heaviness and the option lists of thegmcommands);SkyModelis a pure, allocation-free function of the publishedSkyState, server time, seed and area (phase with its blend, 24-hour clock, automatic weather per slot by a seeded SplitMix64/FNV-1a weighted pick, blends);IServerClockis the client's only view of the sky andLocalSkyAuthoritythe in-process stub of the zone server's clock authority:/gm time <phase|HH:MM>(a phase lands mid-phase),/gm cycle <on|off|xN>(re-anchors, never a time scale) and/gm weather <state|auto>(forced at once) are requests to it.GmAccess: the dev-only local GM flag until M6 (compiled into test builds,gm=offswitches it off, release builds leave it out). Proposed data:clock.dawnStartsAt05:00,weatherChange.weights(clear 6, dust_haze 3, overcast 3, rain 2, sandstorm 1) andweatherChange.heaviness. xunit 88/88 (45 new). M0-12B: the Unity controller in the Boot scene, look values in the data, GM panel and overlay, EditMode/PlayMode, Web/macOS/Android smokes, matrix contact sheet. - 2026-10-08 M0-02: Blender headless smoke.
tools/blender/smoke.py(replaces the earlier training-dummy smoke) builds a 1 m cube in a factory-fresh scene (UV mapUVMap, origin at the base centre, materialM_SmokeCube: a 256 px generated colour grid, metallic 0, roughness 0.5, back faces culled), exportsart/build/smoke/smoke_cube.glb(art/build/is git-ignored) with the glTF settings for the Unity import (glTFast, not installed yet: GLB, embedded PNG, +Y up, metres, transforms applied, no tangents, no Draco/meshopt, no skins, animations, morphs, cameras or lights) and renders a 512 × 512 Eevee Next PNG (falls back to Workbench if Eevee raises; not needed on this Mac).tools/blender/smoke.mjs(pnpm blender:smoke) runs it with--factory-startup --python-exit-code 1and validates the GLB with the model-inbox parser and the PNG (luma mean and spread): 20/20 checks;smoke.test.mjsproves the validator catches a Z-up export, a wrong size, missing UVs, a skin and blank renders. The installed Blender is 4.5.9 LTS (glTF exporter 4.5.51), not 4.2.3: SETUP,stack.jsonand the status now say so. Evidence:logs/evidence/M0-02/. - 2026-10-08 M0-09: engine-free C# core
packages/core-cs:Zoen.Core(netstandard2.1, C# 9, nullable, warnings as errors, deterministic, no dependencies) andZoen.Core.Tests(xunit 2.9.3, net10.0, lock files). The tier rules of M0-04C moved there from the client (TierRules,TierPolicy,MiniJson) plusTierRulesReader(feel-quality.json → rules, shared by the editor's ProjectSetup and the tests). Unity loads the folder as the local packagecom.zoen.core(Zoen.Core.asmdef,noEngineReferences,csc.rspnullable); project files and.artifacts/outputs stay outside it.pnpm core:test(tools/core-test.mjs: quiet, full log inlogs/test-output/core-test-latest.log) is intools/verify.mjsand CI. Guards: a source scan, the compiled references (netstandard only), the asmdef flags and the manifest path; a probe withusing UnityEnginefails the build. No prediction code (M0-11 decides). - 2026-10-08 M0-03: Cargo workspace at the repo root (
Cargo.toml, memberscrates/*, no external crates, builds offline).crates/zoen-sim(no_std+ alloc, no unsafe, no unwrap or panicking index):step(&mut SimState, &[Input], &mut Events)with per-actor sequence numbers (duplicate, older and unknown-actor inputs rejected as events; the intent persists), on-foot movement atattributes.json → base.moveSpeed(6.2 m/s = 310 mm per tick atsim.json → tickHz20), direction-only Q16 integer normalisation, clamp toworld.json → region.sizeM, FNV-1a 64 state hash. Newsim.json: tick, units, determinism and input rules.crates/zoen-sim-tools:export-goldenwritespackages/sim-golden/vectors.json(4 scenarios, 60 ticks, a hash per tick;--checkbyte-identical) next tovectors.schema.json;bench-step. Tests: cargo 12/12 (unit, replay, golden, zero-allocation counting allocator), clippy-D warningsclean, schema + JS hash re-computation 4/4 inpnpm data:test. Bench (release, one thread): 5,000 actors with 5,000 inputs 0.044 ms per tick, 0 allocations.pnpm sim:test|sim:golden|sim:bench; verify.mjs and CI runpnpm sim:test. The Reed Rush dash waits for its authored mana cost and travel time (M2-02). - 2026-10-08 M0-10: Unity runner
tools/unity-run.mjs(librarytools/unity/runner-lib.mjs):editmode,playmode,build web|macos|android,setup,report <log>;build windows|iosrecords "not tested" (ADR-032). Pinned editor fromProjectVersion.txt, refuses while another Unity holds the project (pid, kind, start), quiet unless--verbose, one report (result, counts or size on disk, duration,ZOEN_*lines, first five errors with file:line), full log/XML inlogs/test-output/unity/(ignored), summary JSON tracked; exit 0/1/2/3. Live: EditMode 47/47, PlayMode 0 (none yet), macOS build 117.4 MB, refusal named the build's pid. Parser tests on recorded excerpts (pass, compile error, failing test, licence, build, lock) inpnpm data:test. Skill and toolkit doc point to it. - 2026-10-08 M0-04D (finishes M0-04C): phone smokes for the tier rules on the NX709S (Adreno 730, 60 Hz), no rebuild.
Android APK 4/4, 0 app errors, platformNoise list unchanged: default Mid by the startup benchmark (p95 33.22 ms) at
30.1 fps, Low 30.1, High 60.3, Ultra 60.3 only by launch option; overlay taps cycle Mid → High → Low → Mid → High,
never Ultra (
android-overlay-cycle.mjs, new). Phone Chrome 4/4, 0 console errors: default Mid 30 fps (deviceMemory 8, 8 cores), Low, Ultra refused, low-end → Low.tier-defaults.txtnow has every platform and shows the benchmark pick. The per-loadJS_FileSystem_Syncdeprecation warning is Unity's framework (PlayerPrefs flush after the boot'sSetQualityLevel); noted in the toolkit, not changed. - 2026-10-08 M0-04C (partial): tier defaults, mobile Ultra gate and frame caps from
feel-quality.json → tierSelection(new, all proposed): phones ≤ 4,096 MB and browsers with deviceMemory ≤ 4 GB or ≤ 4 cores start on Low; native builds benchmark the platform default (30 warm-up + 120 frames, p95 within budget +10 %, step down, cached); the saved choice wins; phone Ultra only via the tier launch option until the M1 gate; caps Low/Mid 30, High/Ultra 60 (PERFORMANCE.md, OPT-03), Android frame pacing on. Client:TierPolicy(pure),TierRuntime,StartupBenchmark(ZOEN_PICK), generatedZoen_TierRules.asset, a WebGL jslib. EditMode 47/47; macOS 4/4 (default High 60 fps, Low/Mid 30.0) and Mac-Chrome Web 4/4 (Mid 30 fps, low-end → Low) with 0 errors; three builds rebuilt. Android and phone-Chrome smokes → M0-04D. - 2026-10-08 GM-00: GM arena roadmap (owner decision, all
proposed): GM-00 in M0; GM-01 in M2 right after M2-01 (static targets, spawn ring, reset station, debug toggles, network lab, Time/Weather buttons on M0-12); GM-02 in M4 (slice presets warblade/windarcher/pyromancer, item forge, Dewgrass/Orchard packs, teleport); GM-04 in M6 (the owner's local gm-role CLI; agents never grant roles); GM-03 last in M9 (boss pit, all 18 presets byplanBuild, full forge, give, teleport, one automated test pergm-room.jsoncommand). GM rules (audit,gmitem flag, dev-only GM flag until M6) sit in each task note; M2/M4/M6/M9 gates got one GM line each. M4, M6 and M9 now list tasks next to their groups and the wiki Roadmap shows both (with aproposedchip and notes). Testgm-arena-roadmap.test.mjs. - 2026-10-08 MODEL-01D (MODEL-01 complete): wiki page Model requests (
/model-requests/, nav under Production next to Audio generation): counts by status, the owner steps rendered at build time from the TRIPO_PIPELINE "Current mode" section thatmodel-requests.jsonhowTopoints at (one source; the build fails if the section moves), the agent stepnode tools/model-inbox.mjs, kind/status filters and search, one card per request (views from/art/model-requests/<id>/, or "views missing → ART-3D-…" linking to the art queue, which now takes?q=<id>; prompt and avoid with copy buttons, budget, size, Tripo settings, save-as with a file-name copy button, delivery note oncemodel-delivered.jsonhas one). E2Etests/model-requests.spec.ts; screenshots inlogs/evidence/MODEL-01D/. Known defect moved to MODEL-01E: the Bellwhisker Jerboa side/front views are badly cut. - 2026-10-08 MODEL-01C (partial; the wiki page moved to MODEL-01D):
tools/model-views.pygives each connected part of a sheet cell (row-run labelling, no scipy) to the view that holds at least 90% of its pixels and paints other views' parts out of each crop: the Ashroot Pangolin front view lost the sliver of its top view, the top view is whole again, and whiskers and tail tips that the edge trim clipped are back (all 40 re-cut, previews refreshed;logs/evidence/MODEL-01C/views-fixed.png). Still wrong and left to MODEL-01D: the Bellwhisker Jerboa side/front split (the cut falls on the thin tail, side.png is only the tuft).art/3d/inbox/README.mdadded, inbox GLBs git-ignored (provenance: sha256 inmodel-delivered.json), the inbox checker ignores the README.pnpm data:test152/152. - 2026-10-08 MODEL-01B (partial; the wiki page moved to MODEL-01C):
tools/model-inbox.mjschecksart/3d/inbox/<id>[.vN].glbin plain Node (id, triangles vs budget, size, UVs, embedded textures, no skin or animation), writesmodel-delivered.jsonand re-runs the model generator; rules proposed inmodel-requests.manual.json(inbox: reject above max(25 × budget, 250k)). Fixture testmodel-inbox.test.mjs3/3; the parser matches Blender on the Wukong GLB (53,353 tris).tools/model-views.pypaints the scale bar out and splits at empty gaps first: the bar is gone from every side view and the Ashroot Pangolin is cut right. - 2026-10-08 DEC-20261008-02: ADR-033: Blender and the mannequin first; the owner makes
Tripo models by hand from a model request log (
art/3d/inbox/<id>.glb), no Tripo API or auto-rig; bodies in a thin undersuit with armour as separate meshes. MODEL-01 builds the log, wiki page and inbox checker. - 2026-10-08 M0-04B (finishes M0-04): ProjectSetup rerun with
runInBackground; EditMode 26/26. Android APK built (IL2CPP ARM64, 31.7 MB, first Gradle build 19 min) and passesandroid-smoke.mjson the owner's NX709S (Vulkan, Adreno 730, default Mid, 4/4 tiers, 0 app errors; Android/vendor E lines classified asplatformNoise, 30 fps cap). macOS rebuilt, smoke 4/4 (was 1/4). Web rebuilt, 0 console errors in Chrome on the Mac and on the phone over CDP. Client documented indocs/tech/UNITY_TOOLKIT.md; Unity pin 6000.3.25f1 recorded instack.json. - 2026-10-08 M0-04 (partial):
apps/client-unitycreated: URP 17.3, four tiers generated fromfeel-quality.jsonbyZoen.ProjectSetup.Run(Web Low–Mid), FPS overlay with p50/p95/p99,ZOEN_BOOT/ZOEN_FPSlog lines,Zoen.Build.Web|MacOS|Android, smoke scripts intools/unity/. EditMode 26/26; Web smoke 0 console errors (WebGL 2.0, 60 fps); macOS built, smoke paused when unfocused (fix pending); Android APK left for M0-04B. - 2026-10-08 DEC-20261008-01: owner activated the Unity Personal licence (batchmode
-createProjectexits 0); ADR-032 sets the test platforms (Web, native macOS app, Android APK on the owner's nubia phone); M0-04, M0-05, M0-11, M2-08 and M2-10 cards amended; owner test devices added toreference-devices.json. - 2026-10-07 SETUP-20261007-01: Unity Hub 3.22.2 and Unity 6000.3.25f1 (changeset e1dba0a9aba4) with Android, iOS, Web, Windows Mono modules installed under
~/Unityand~/Applications(about 27 GB); licence sign-in, Xcode and Homebrew left for the owner.
Moved from
CONTINUE_HERE.mdon 2026-10-06 (ADR-029). Nothing below is updated any more; it is kept so earlier decisions and test results stay findable. Agents do not need to read this page for a task. Current status and next actions:CONTINUE_HERE.mdat the repository root (shown on the wiki's Kickoff page).
◆MODEL-01 — model request log (2026-10-08)
scripts/gen-model-requests.mjs(inpnpm data:build) writesmodel-requests.json: 100 requests (20 monsters, 20 optional elites, 2 bosses, 4 mounts, 39 armour pieces, 4 costumes, 11 set pieces) from bestiary, mounts, items, cosmetics and world data, ordered by roadmap need (MDL-MON-duneplate_beetle first, M2-06). Budgets from PERFORMANCE.md; mount, armour-slot, costume, large+ budgets and all size ranges areproposedinmodel-requests.manual.json.tools/model-views.pycuts the ART-MON-053 cells intoart/3d/requests/<id>/(git-ignored PNGs,prompt.txt) and wiki previews; 40 requests pending, 60views-missingwait forART-3D-*turnarounds (60 new 2D requests) plus 10 undersuit turnarounds (5 lineages × 2). M0-08 is replaced by MODEL-01; MODEL-01B holds the inbox checker and the page.
◆2026-10-07 · Site hover cards match the wiki cards (SITE-POPUP-20261007-03)
- Every site card now uses the wiki card's layout (
apps/wiki/components/popup/content.tsx): header, art, identity line, rows, texts and footer hints in the same order, with gold dividers only around the blue modifier block and plain dividers elsewhere. Kinds: skill, item (loot roll, hover and the panel beside it), orb, gem, monster, boss, mount, companion; people keep their own card (the wiki has none). - Hidden on the site: affix tiers and ranges, prefix/suffix tags, the base tier and the "Hold Alt" hint. Withheld until the owner approves: prices (mount price, item "Sells for"), monster life, material names (proposed) and the one orb source that names a drop chance. Every card with numbers carries the early-values line.
- New cards: companions and mounts (stable tabs), boss spotlights, the world page's creatures and people, the build
page hotbar and combo, the build stage's combo chips, the training-ground skill deck and Q–C keys (
useHoveron the existing buttons, so there is no nested control). public-data/early-values.jsongainsskillCards,orbCards,mountCards,monsterCards,petRuleand the item bases' slot name, item level, defence and requirement line (generator only); the public-export test checks they describe public records and carry no price, drop chance, life or proposed material name.
◆2026-10-07 · Site polish: descriptions, loot roll, seal v2, roadmap (SITE-POLISH-20261007-02)
- Owner decision: the site's hover cards show the wiki's descriptions with their design numbers, marked "Early values:
every number will change before release". They come from one public file,
public-data/early-values.json(skill, orb and gem descriptions of public records, the affix table, refinement auras, base names); the public-export tests exempt only that file from the number andeffectrules and check it holds public records only. - "Roll a drop": each roll is a random +0 to +15 enhancement with real affixes of the slot at real tier ranges (seeded, first roll fixed at +7), the refinement aura from +8, shown in the game popup on hover and beside the item.
- Seal buttons v2: outer gilt frame, dark lacquer channel, engraved inner rim around the face, a jewel in each point; labels optically centred so text and icons share one line.
- Roadmap stepper: the lanterns sit inside the scrolling track (they were clipped at its top and left edge).
◆2026-10-07 · Site hover cards (SITE-POPUP-20261007-01)
- The wiki's in-game hover card on the public site (
components/popup/): one global card (kit.gpop, header art per family) for build skills on the path stage, orbs and gems, the field guide's creatures, and the creatures and people of the Amber Basin card. Hover or focus shows it; a tap pins it on touch screens. Cards are built only from the allow-listed public data (kind, role, input, statuses, facets, rarity, colour, rank, places): no stats or tuning.
◆2026-10-07 · Public site rework (SITE-REWORK-20261007-01)
- Scroll rail (
components/layout/scroll-rail.tsx,styles/rail.css): the native page scrollbar is hidden on every page; a gold thread on the right edge carries a lantern at the scroll position (drag it, or press the thread to jump) and a post per chapter (home: sections markeddata-rail; inner pages: theirh2headings, up to 12). Hover opens the index; dragging shows the chapter in a bubble. Shown on phones too (touch grabs only the lantern, so edge swipes still scroll). Replaces the left-side chapter rail that only showed at ≥ 1400 px. - Seal buttons (
styles/buttons.css,components/ui/cta.tsx): lozenge plates with a gilt frame that runs light on hover, a pointer-following glow (components/fx/pointer-light.tsx), one light sweep and rising embers;.cta(jade, primary),.cta.ghost(ink and gold),.cta-icon. Every public button moved over; the kit's sprite.btnstays for/dev/kit. - Header: the ZOEN logo (header cut,
zoen-wordmark-hdr-390w.webp) replaces the emblem, hangs below the floating bar and settles inside it once the bar turns solid; gold shine on hover. - Chapter II: the skill showcase (codex medallion with the build's aura and its facets engraved on a turning ring, kind, role, input, statuses and scenarios from the public data), a large eight-socket chain deck, Q/E/Z/X/C keys, a cast splash on the stage, and a previz screening room (one large player and the reel). Skill icons are exported at 512 px.
- Chapter III: the six painted path emblems (
web_path_*.png, newpath-*icons) as the path picker (halo, running border, beam to the stage, arrow keys); the build painting keeps its full height on the stage (no cropped heads) over a blurred copy; the build's skills, difficulty pips and a seal link to the build page. - Windows (
.gwin) as in the wiki: the header rail sits straight on the body (fill and frame start under the rail; no strip of glass);.gwin-mediaruns art flush under the rail (Amber Basin card). Applies to every site window.
◆2026-10-07 · Development review, round 2 (REVIEW-20261007-01)
- Development review, round 2: measured that the token rules were not enforced (round-1 session median context 425k) and that the token ledger loses sessions whose transcripts are gone; proposed the guards E1–E9, faster-development changes F1–F7, direction findings D1–D12 and OPEN-15 to OPEN-19.
- AAA catalog: 90 proposed details (6
core), four new areas (NET, INP, LOOK, FLOW) and a proposed fourth stagealpha; UI-05 corrected to the HUD's 48 px touch targets; the acceptedcorecount is 38 (EFFICIENCY.md said 37). ctx.mjs polishmarks proposed details; the wiki shows a proposed chip and the four stages.- Owner decisions the same day (ADR-031, task DECISIONS-20261007-01): OPEN-15 C (build both impact
modes, judge at 80 ms), OPEN-16 (a) non-verbal voices, OPEN-17 yes, OPEN-18 all, OPEN-19 later. Catalog round 2
accepted (217 details, 44
core); HIT-04, NET-02, SFX-27, ACC-06 and the tasks M2-01, M2-07 and M2-08 updated. - Round-2 tools, each run in a fresh sub-agent context and committed separately:
- LEDGER-20261007-01 (E1): rebuilds merge with the previous ledger; history restored from 3465c40 (4,393 messages, 2.02 B tokens, 11 archived sessions); sub-agent transcripts are counted and attributed.
- ENFORCE-20261007-01 (E2, E3, E5, E7): read guard and context meter hooks in
.claude/settings.json, lane agents in.claude/agents, a next-session chip at every finish. - CTX-GUIDE-20261007-01 (E4):
ctx.mjs guideandctx.mjs docslice docs by anchor; 14 M0–M2 task cards name their guide sections (a card's median slice is 0.85k tokens instead of 8.8k). - WIKI-TESTS-20261007-01 (E9): the three round-8 failures were test races and a wrong tab locator, not UI bugs.
- QUIET-TESTS-20261007-01 (E6):
pnpm data:testprints 573 bytes instead of 31,409;verify.mjs --changed.
◆Status notes up to 2026-10-06
Status (2026-10-05): Round 8 (owner UI refinement) is implemented (T087). Round 7 (T085–T086) and rounds 1–6 still hold. Pre-production guide, wiki, data and tooling are complete.
- Art: 368 delivered, 140 pending (508 requests). B10–B23 plus the first five requests of B24 generated and synced 145 assets;
pnpm data:testpassed 93/93 for each completed batch. B24 is paused after ImageGen hit its usage limit; its task log records the partial batch.ART-WEB-boss-regent-splashremains loggedok:falsebecause its best-of-three image clips part of the boss in the central 4:5 crop.ART-ATL-notable-crossbowis also loggedok:falseafter three attempts because its silhouette remains ambiguous at 32 px. Next queue head:ART-MAT-wolf_fang(seeart-requests/queue.json). - Audio: 320 prompts: 318 delivered, 2 planned boss themes pending (GUIDE-DEV-20261005-03); no boss audio generated by the guide update. Round 9 (SFX-ENV-20261005-02): outdoors is a quiet bed + random one-shot accents (
acc-<area>, 12 requests × 3 takes, 5 s) instead of a constant loop; town/GM music plays one loop then rests 60–120 s (runtime rules in AUDIO.md); engaged boss themes use encounter playback. Measured not heard. One-shots are single 5-second MP3 takes; ambience loops are single 20-second MP3 takes. Local Stable Audio 3: local SFX operations.- ADR-026 (owner, 2026-10-05, task
SFX-ENV-20261005-01): classic town/GM music; ordinary outdoor travel/combat uses environment sound. The owner later allowed special boss music (GUIDE-DEV-20261005-03), scoped to engaged named encounters. Delivered: 12 area beds rewritten per area (the generic first-pass beds are archived inaudio/superseded/) + 12 landmark spot emitters (negative prompts keep music out), and two music themes,mus-amber-gate(92 BPM) andmus-gm-proving-ground(100 BPM), as 60 s loops with 3 takes each. - Small Music bundle installed 2026-10-05 with the owner's OK (
dit_sm-music_f16.npz, 919 MB;./tools/sfxgen --model sm-music). The owner asked whether it differs from the SFX model: it does (separate music-only weights). A test of the SFX model on the same prompts gave in-key sound but no beat (clips inlogs/evidence/SFX-ENV-20261005-01/). - Measured, not heard: every take is in the −15.5…−17.5 LUFS band, every music take hits its requested tempo exactly (a 60 s loop is 92 or 100 beats, so the loop point is on the beat grid), no take has a silent edge. GM take 1 opens and closes about 8 dB softer than its median; the other five loop level-cleanly. The owner must listen (Audio generation page → generated list) and pick one take per theme.
- Loop defect fixed: the model ends every clip with 0–1.35 s of digital silence and the old loop builder looped that hole (all earlier ambience loops had it). Now trimmed, requested +3 s, and every loop's edge is validated.
- ADR-026 (owner, 2026-10-05, task
- Wukong hands and feet (CHR-WUKONG-20261005-03, 2026-10-05): relaxed curled hands on the walk, fists on the run, arms closer to the body;
shorter, narrower, lower walk steps; higher run heel kick; no skid at contact (new
wukong_foot_slide.pytest). Rig 18/18, glTF pass, browser 12/12, foot slide pass. Video:logs/evidence/CHR-WUKONG-20261005-03/wukong_hands_feet_vs_reference.mp4. Owner review pending. - Wukong rework 2 (CHR-WUKONG-20261005-02, 2026-10-05): feet, scarf and antenna reworked against the owner's videos in
3d/: smooth boot weights, IK walk/run with planted feet and heel-to-toe roll, scarf 3 × 8 with B-spline weights, solver damps relative to the pose + separate air drag- per-joint angle limits. Rig 18/18, glTF pass, browser 12/12. Video:
logs/evidence/CHR-WUKONG-20261005-02/wukong_rework_vs_reference.mp4. Owner review pending. Details: Wukong rig → Rework 2.
- per-joint angle limits. Rig 18/18, glTF pass, browser 12/12. Video:
- 3D rig test (CHR-WUKONG-20261005-01, 2026-10-05): the owner's Tripo Wukong model is rigged, coloured from the owner's four turnaround views and animated, and runs in a browser demo: Wukong rig. Tripo's Mixamo body skeleton plus 77 spring bones (4 antenna feathers, cape, 9 sashes),
art/3d/wukong/demo/wukong.glb(serve the folder over http;?hq= 4K texture). Tests: rig 18/18, glTF contract, browser 12/12; clips inlogs/evidence/CHR-WUKONG-20261005-01/. It is a hero asset, over the player budget (53k tris vs 22k, 129 weighted bones vs 80): the game-tier reduction is the next step in the doc. Clips are procedural stand-ins. - Public site overhaul (WEB-OVERHAUL-20261005-01…04, 2026-10-05, owner request, done): high-end "chronicle" redesign of
apps/sitein the classic caravan theme: floating header, colophon footer, home in ten chapters (WebGL hero parallax over the key art, combat training ground, character select with WebGL burn transitions, three.js 3D basin diorama, bosses + field guide, mounts, loot stage, roadmap road, registry under a WebGL lantern sky), rebuilt inner pages and a home share card. Doc: Public website plan → Chronicle redesign. three.js 0.186 added (MIT, lazy chunk, wide screens only). Tests (task log): typecheck, ESLint (0 errors), unit tests and the leak scan (604 built files) pass; final e2e run 63 passed / 1 failed / 32 skipped (opt-in and device-specific), the one failure a pre-existing race in the direction mock-up spec's shared temp folder, fixed and re-run green; Lighthouse mobile all 7 pages within budget (home 92, largest paint 3.25 s; a11y, best practices, SEO 100). Chrome does not count a full-viewport image as the largest paint, so the measured element on home is the preloaded wordmark (see the doc). Evidence:logs/evidence/WEB-OVERHAUL-20261005-04/(home-desktop.mp4 scroll clip, Lighthouse reports). Owner review pending (pnpm site:dev→ http://127.0.0.1:4340); nothing committed. - Engine: Unity 6 LTS + URP accepted by the owner (ADR-024, round 6). Docs, stack and roadmap describe the Unity
client; Rust servers stay. Tooling: Unity dev toolkit +
.claude/skills/unity-*. - Battle preparation (GUIDE-DEV-20261005-02, 2026-10-05): completed the researched game development guide
in the wiki at
/process/game-dev-guide. ADR-027 records the owner's movement-first requirement through windup, active and recovery, including finishers. Added canonicaldevelopment-standards.json(documented, not implemented; tuning proposed), mannequin/multi-angle review, C1–C18 controls, semantic VFX roles/budgets, area briefs and prioritized battle recommendations. Agent read-first/kickoff, Combat, production/testing gates and M2–M5 roadmap are connected. Data tests 93/93, docs lint and wiki production build pass; targeted browser checks 6/6, plus captures/anchor and overflow audit at desktop, 390 px and 360 px. Evidence:logs/evidence/GUIDE-DEV-20261005-02/. No game runtime/production animation tests executed; all engine milestones remain NOT_STARTED. - Battle decisions follow-up (GUIDE-DEV-20261005-03, 2026-10-05): owner accepted mana for movement; starting jump/dash reuse targets 1 s / 0.3 s (Cairn Vault/Reed Rush, proposed); CC/root validation, per-skill WASD, combo memory/refunds, optional lock-on, enemy engagement coordination and first-slice foundations/optional cosmetic KO-combo feedback. Silk Roll is blue. R3 toggles close ↔ tactical only. Special named boss music is allowed; two briefs are cataloged, not generated. Entry-level reference selection is in
reference-devices.jsonand Performance: Galaxy A07 4G 4 GB, iPhone SE (2020), Intel N150 8 GB Windows laptop; physical probe/performance tests pending. Guide/ADRs/Combat/Skills/Audio/environment/stack/roadmap agree; runtime milestones remain unstarted. Validation: data 93/93, docs lint, wiki build/typecheck and 18 targeted desktop/mobile checks pass; three-viewport/anchor/proposed-tuning and Silk Roll/map render audit passes. Legacy green icon artwork revision is documented, not rendered. Evidence:logs/evidence/GUIDE-DEV-20261005-03/. - No game client or server code exists yet. All engine milestones M0–M11 are NOT_STARTED.
- Review: speed, tokens and AAA details (GUIDE-DEV-20261006-01, 2026-10-06): new wiki pages
AAA detail catalog (127 proposed details in 11 areas, rendered from
polish-standards.json; 37coredetails are due with the first polished skill) and Speed and token efficiency (measured: USD 557 real Claude cost, 69% of it cache re-reads at a median 465k-token context; the Ledger's per-task rows summed to 1.86× the real total because 156 tasks had no session id). Tools:node tools/ctx.mjs(context packs) andtask-log.mjsnow attributes the Claude Code session by itself and prints turns and average context atfinish. Corrections recorded: telegraphs must not share the capped decal pool; dynamic resolution, mixer effects and streamed audio do not exist in the Web build. All of it is proposed: OPEN-11 to OPEN-14 are the owner's. No runtime exists, so nothing in the catalog is implemented or measured. Tests (task log): data 104/104, docs lint 0 problems, wiki typecheck and production build pass, the new browser spec passes 5 with 1 phone-only skip (desktop, mobile, 360 px). The full Playwright suite was not re-run. Nothing committed.
This folder is standalone: sibling folders are archived and never cited. Accepted art lives in art/originals/; the
owner's round-4 and round-5 references live in art/owner-refs/.
◆Round 8 changes (T087, UI refinement from the owner's review)
- Inventory (
/windows#tab-inventory): window 620 px, outer container padding 0, inner panel 12 / 8 / 8 (.gwin.custom.tight, also used by Character); weapon and off-hand are now exactly 2×3 (the bag footprint of a weapon, owner answer) placed at left/right 74 px and top 70 px of the equipment panel (offsetPxinui-windows.json), whose backdrop now runs down through the potion row to just above the bag; clicking a socketed gem picks it up and holds it (it leaves the socket only when placed, Esc puts it back); the Inventory / Cosmetics tabs are inset; the gold and Zoe boxes are lower; pressing an equipped item scales it down ~7% and equipping plays a small settle on the slot. Contract:ui-windows.json(width 620, padding 22 = rim 6 + panel 8 + gutter 8, height 912). - Character: same width/padding; portrait at the top of its block with the level medallion on its corner (removed beside the EXP bar); 13 smaller skill slots in the delivered
round HUD slot frame + keycap plate (
ART-HUD-002) on a painted backdrop in a bronze frame; framed stat body. - Header title 3 px lower; Map circles 76 units and the pin tip sits exactly on the current circle's centre; Social HP bars share one width and use the bronze field frame with the delivered red liquid (no new art needed).
- Kit: gold button hover lights the whole button (the old glow layer painted over the art); plain window headers are transparent and the panel fill / glass starts under the rail; page heads (Item catalog, Online, social & events, every doc) have the header rail on top and the framed body under it.
- HUD (
/hud): the mock is built from the deliveredART-HUD-001…014sheets (lib/hud-sprites.tsholds each part's box); nothing was missing, so no image was generated. - Economy: the "Rarity by affix count" showcase renders the real item popup.
- Character (follow-up): level medallion centred under the portrait, right-hand stat values colour-coded (damage type, speed, crit, life/mana/armour, STR/AGI/INT dials), the stat body touches the tab strip.
- Popups: the economy showcase keeps the gold dividers (the doc's
.md hrstyle no longer leaks into popups); the popup footer ("Hold Alt…", "Sells for…") is tight; orb / gem / consumable art and socket rings are smaller. - Interpretation note: "scale down on equip" = press feedback + a landing settle; tell me if it should differ.
◆Round 7 changes (T085–T086, all in logs/tasks.json and on the Ledger page)
- Decisions: ADR-015/016/019/020/021/022/023 accepted. OPEN-2 decided (Tripo + Blender polish), OPEN-3 decided (local AI audio), OPEN-4/5/6 skipped by the owner. OPEN-10 (Windows code signing) explained in Updates.
- Tripo: Tripo → Blender → Unity pipeline: the two bridge add-ons in
tripo ai/are interactive loopback receivers; hands-free generation uses the Tripo API/Python SDK (key in the owner's environment, credit guard), Blender polishes headless. Roadmap M0-08 + M3 automation; owner to confirm that their plan's credits cover the API. - Economy: drop quantities are random everywhere (
drop-quantity.json: materials 1–5 …, ADR-017 amended). Caravan Market with daily/weekly capped, account-bound Zoe and gold stock (market.json, ADR-018 amended; catalogue in Items & economy). - UI: the rail header and title plaque are rebuilt as one material end to end; close button sits on the ring and its hover is the same button lit; crest title container is gold; tabs have no divider or gap; gold button has its own sun-and-jade end caps; red items are stronger; options is one vertical scroll with portal dropdowns; loading bar runs end to end; Character has a level medallion + rail EXP bar; Map has art waypoints, a smooth road and a "you are here" pin; mounts and companions are showcased with their art; new gold-coin-stack currency art next to the Zoe coin.
- Inventory: pale backdrop, clearer slot boxes, weapon/off-hand 2×6, circle-art sockets (no overlap, highlight not scale),
exactly 1 main + up to 2 support gems (second main refused), gems drag out of sockets, drag ghost keeps its size, gold + Zoe
boxes and the
Boran · STR · AGI · INTline under the grid, window width fixed at 636 so the grid is never cut. - Art queue: +7 requests (gold coins, stats icon, 4 map waypoint states, map pin).
- Note for agents: this Mac is often saturated by other projects (Blender renders, dev servers);
build-ui-sprites.pycan take 5–10 minutes. Run it in the background and wait.
◆Round 6 changes (T078–T084, all in logs/tasks.json and on the Ledger page)
- Engine: ADR-024 accepted, ADR-002 superseded, OPEN-9 closed. ARCHITECTURE, ANIMATION, VFX, AUDIO, PERFORMANCE,
NETCODE, SETUP, AI_WORKFLOW, VISION, LICENSES, KICKOFF and CLAUDE.md updated;
stack.jsonandroadmap.json(M0-03…07, M1-01/05, M11) migrated. New Unity dev toolkit doc (22 reviewed GitHub tools with licence, status and gate) and two project skills (unity-batchmode,unity-toolchain-gate). - UI: window crest without any background (wings on a thin rail, open title frame in the wings' own bronze); gold
button = the regular box button in polished gold/amber; textbox/textarea = thin bronze frame from the button rim with
corner flourishes (
field-frame), gold on focus; tab badge 16 px with the same 11 px number. - Zoe coin: the logo's sun embossed on a gold coin (
ui/zoe-coin, stand-in) on every Zoe price and balance. - Public site + sign-in: one-tap Google sign-in on the web and in game (Android Credential Manager, iOS Google + Sign in with Apple, Windows system browser + PKCE) — Accounts and sign-in; site plan adds Showcase, public Roadmap, Event times, Skill and Inventory playgrounds and a premium design brief for the AI designer.
- Development plan: auto-patching (Windows launcher with signed deltas and rollback,
Addressables content updates, store update gates, browser version check) and security & auto-ban
(security event log from M1, certain/strong/watch rules in
security.json, automatic bans, human review only when a player appeals via Contact us, rule-quality limits, red-team and false-positive gates). OPEN-10 (code signing) added. - Audio: see the status above; the Audio generation page now starts with the generated sounds.
◆Round 5 changes (T071–T077, all in logs/tasks.json and on the Ledger page)
- Site: sticky header and sidebar fixed (
body{overflow-x:clip}); sharp ZOEN logo (exact-width srcset cuts with a light sharpen instead of one large file scaled ~2.8×). - Popups: 320 px wide; at most two gold dividers (above and below the blue modifier block), regular dividers elsewhere.
- UI kit (UI components; rules in HUD_UI → Controls):
- Gold button = bright gold title plaque with dark engraved text, same 34 px art / 44 px height.
- Tabs always one row (scroll + edge fade), popup divider underneath, glowing gold underline on the open tab, enamel count badges.
- Textbox/textarea: one bronze line (no double border) with a 200 ms focus glow. Slider: engraved track + gem knob.
- Custom dropdown everywhere; no native select remains (tested).
- Premium tags carry a crown;
TagIconset of 20 painted-gold glyphs (code stand-ins, art requested). - Grab/grabbing cursors show the back of the hand (palm-facing art set aside in
art/superseded/ui-kit/).
- Windows: custom windows follow the owner sketch (
art/owner-refs/hud/window-artwork-idea.png): minimal outer rim and subtle background, close top-right, resize grip, crest (delivered wings, leather title cartouche, ZOEN medallion) on the inner panel's top border. Windows without a close button keep the rail, with a ring-less right cap. - Orbs and gems: orbs/shards coloured by rarity (common tan … very rare orange, milestone red), gems by socket colour
(red/green/blue/white, Jade Caravan rule) in names, popup titles and well frames (
items.jsoncurrencyRarity/gemColors, proposed). - Inventory: weapons stand upright and fill their 2×3 slot, belts fill 2×1 (
tools/build-icon-fit.py, rerun by art-sync); quick slots 1–8 take potions/scrolls by drag; sockets show on hover — click a gem to remove it, drag gems in (group rules). No popup opens over a drag. - Tooling: the sprite builder composes from memory (no re-reads of its own outputs, which raced with art-sync runs).
- Art queue: +25 requests (window crest P0, outer background, back-of-hand grab cursors P0, 20 tag icons, slider knob); the unused window-plate request was removed.
◆Round 4 changes (T054–T070, all in logs/tasks.json and on the Ledger page)
- Header and site:
- ZOEN logo in the header and home hero; the emblem on small phones and as the favicon.
- No menu toggle on desktop.
- No sideways scroll on any page at 360 px (tested on every route).
- Clean bronze rim on cards (the old well sprite's corner fans caused the stray inner art).
- Windows:
- Popups and plain windows keep the rail header, now drawn above the frame.
- Custom windows (Character, Inventory, Stash…) use one fixed header plate inside the panel: game emblem, centred auto-fit title, close button in the ring.
- Popups: layout standard (hairlines between rows, gold divider between major blocks, plain divider inside a block, never doubled); one-line auto-fit titles.
- UI kit:
- Checkbox, radio, switch and slider drawn in code.
- Dropdown list as glass with corner ornaments only.
- Bevelled tags, new modal, toasts with tones.
- Atlas: sector tint 16% → 4%; unallocated node frames look disabled.
- Inventory and stash (owner references):
- Equipment area on a painted backdrop with subtle slot boxes.
- A plain sprite grid; blue tile = usable, red = requirements not met.
- Cosmetics tab on the right, disabled.
- Window size 624 × 868 at 1080p.
- Text and items:
- Bestiary art is uncropped.
- Every item name in the guide is a rarity-coloured hover link.
- Economy page has the weapon/rarity showcase.
- Gameplay data:
- 4 team position-event proposals (OPEN-8).
- Release versions (
release.json), shown on the loading screen. - Loading-screen contract and live mock.
- 7 long cosmetic side quests with boss-only drops.
- Controls:
- Camera zooms from tactical to close over-the-shoulder (V toggles).
- Mouse1 walks on empty ground; Shift+Mouse1 attacks in place.
- The Feel Lab plays the full Warblade 8-slot chain (all 7 clips re-recorded).
- Rulesets: alpha = the live game × multipliers (XP ×140/×70, drops ×10 chance and ×10 quantity; 1.6 h to 40, verified under 2 h). No custom alpha kit.
- GM room (Production): 18 one-click preset builds (full gear, 45-point Atlas, hotbar), an item forge with exact affixes, spawns, bosses and resets.
- Caravan Ledger: web activity feed for Auto-Hunt; free in alpha, premium later.
- Engine: analysis and recommendation (Engine & platforms). Browser capped at Low–Mid, apps up to Ultra.
- Art queue: +32 requests (window plate, inventory backdrop, grid tiles, 17 loading screens, cosmetic icons; missing cursors moved to P0).
◆Tests (SFX-ENV-20261005-01 audio design, T086 round-7 verification and the audio batch)
- SFX-ENV-20261005-01 (ADR-026):
pnpm data:test92/92 · sfxgen unit tests 24/24 · docs-lint 0 problems · wiki typecheck clean · Playwright audio page (desktop + mobile) and Maps tests pass (targeted specs, the full Playwright suite was not re-run). Expected red phases are in the task log. The first audio e2e run failed on its 120 s timeout (330 preview files fetched one round-trip at a time); the spec now batches its checks and no longer assumes a non-empty queue. - T086: data tests pass · docs-lint 0 problems · typecheck clean · UI sprites deterministic · wiki build OK.
- Current audio batch: all 24 MP3 takes (20 regenerated plus 4 carapace) passed output validation;
pnpm data:buildpassed with 6 requests done;pnpm data:testpassed 78/78. Static wiki mirrors delivered takes toapps/wiki/public/audio-previews/, and the Audio Requests Done history shows native players per take. Desktop and mobile checks confirm all 24 preview assets are served as audio/mpeg and browser playback starts. (The window-header assertions that expected.gplatewere updated for the round-5 crest in T073; see the T077 run below.) The initial failed data/UI runs were expected TDD checks; corrected audio checks pass. - Playwright (T086) 269 passed / 0 failed / 39 skipped (opt-in recording and device-specific), on desktop + Pixel 7, plus every route at 360 px.
- Atlas drag draw p95 0.3 ms (0.7 ms at 4× CPU throttle); Feel Lab High/Ultra frame p95 16.7 ms.
- Ledger: Claude ≈ USD 308 at list prices (28.1 h wall / 13.7 h active). Codex images: 209 logged, ≈ USD 40 (third-party prices, verify).
◆Web platform (site + admin, tasks WEB-*)
- Built (2026-10-05): the player site (
apps/site, direction A) and the staff console (apps/admin, 15 modules; Players, Security and World on labelled demo data) on a local Supabase database in Docker. Docs: Web platform · Staff console. Tokens: Ledger → "Web apps". - Run:
pnpm db:start→pnpm db:env→pnpm site:dev(4340) andpnpm admin:dev(4350); demo playerspnpm db:seed:demo. Everything at once:pnpm web:verify(summary inlogs/milestones/WEB.md). - Owner next: 1)
pnpm admin:bootstrap-owner(your own console account); 2) AI keys inapps/admin/.env.local(CLAUDE_CODE_OAUTH_TOKENorANTHROPIC_API_KEY, plusGITHUB_TOKEN, and the token as a repository secret), thenpnpm ai:smoke; 3) Tailscale on the Mac and phone for approvals on the go; 4) confirm site direction A (B and C mock-ups inlogs/evidence/WEB-100); 5) legal review of the privacy, terms and cookies drafts; 6) hosting (OPEN-4). - Open: the largest paint on phones is about 2–3.5 s in Lighthouse's simulation on the local HTTP/1.1 server (budget 2.5 s; re-measure on HTTP/2 hosting). The round-7 drop-quantity and market data files are still untracked in git but the admin reads them: commit them with the next sync. Three wiki tests in the uncommitted round-8 inventory work fail.
◆Next smallest actions as of 2026-10-06 (superseded by CONTINUE_HERE.md)
Before game work: read the development guide and standards data. After toolchain/feasibility readiness, M2-09 establishes the mannequin; M2-10 verifies movement/control priority; complete self-review before skill expansion. Assign each skill's locomotion/steering and damage-entity ownership explicitly; the catalog is not bulk-reclassified by this wiki task.
- Owner — look at the Wukong demo (
python3 -m http.server 4320 --directory art/3d/wukong/demo, open http://127.0.0.1:4320/) and the two videos inlogs/evidence/CHR-WUKONG-20261005-01/; say what should change (feather/cape feel, colour, which extra parts to rig). Then an agent starts the game-tier reduction (fingers merged, chains thinned, 22k tris). - Owner — install Unity. Unity Hub + the current 6.x LTS with Android, iOS, Web and Windows (Mono) modules; sign in with your Unity ID (agents can't). Full Xcode later for iOS device builds. Then an agent starts M0 (KICKOFF.md).
- Owner — decide OPEN-8 (team events), OPEN-7 (Zoe prices), OPEN-10 (code signing); later a Google Cloud project for sign-in (free; see Accounts and sign-in). New (2026-10-06): OPEN-11 (one Rust simulation for server and client), OPEN-12 (accept the AAA detail catalog), OPEN-13 (token rules: one task per fresh session, context packs), OPEN-14 (shake default, blood, others' numbers). Work that does not need Unity can start as soon as Rust is installed: see Speed and token efficiency → Faster game development.
- Agent (art): continue the live missing-art queue at
ART-ATL-notable-tome; useart-requests/queue.jsonas the source of truth. - Owner (audio): listen on the Audio generation page and pick one take per music theme (say if "classic" should sound different: the agent read it as classic orchestral fantasy). Still undecided: boss-fight music and the Sand Arena colosseum.
world.jsonkeeps amusicmood line for outdoor areas as a note only; the Maps page now says "no music, environment sound only" there. - Agent: once Unity is installed, start M0-01 with the prompt in KICKOFF.md. The git repository already exists (38 commits) with more than 1,100 uncommitted paths; committing them needs the owner's go-ahead.
◆Commands (as of 2026-10-06)
pnpm data:test · pnpm docs:lint · pnpm wiki:build && pnpm wiki:test · pnpm art:sync · pnpm ui:sprites ·
python3 tools/build-brand.py · python3 tools/build-icon-fit.py · pnpm showcase:record · node tools/task-log.mjs report · node tools/token-ledger.mjs ·
node tools/codex-ledger.mjs
Source: zoen/docs/roadmap/CHANGELOG.md · 10,443 words · edit the Markdown, not this page.
