M0-11D
One-simulation spike part D: zoen-sim-ffi Windows + iOS built (recorded not tested), M0-11 result into ADR-029
Evidence
From logs/evidence/M0-11D/. Click a thumbnail for the full image.
Logs and data (4)
spike-report.md · 4 kB · open
# Spike M0-11: one simulation (ADR-029) — report The Rust `zoen-sim` step as a C ABI plugin (`crates/zoen-sim-ffi`) inside the Unity client. Golden check: scenario `walk_eight_directions` from `packages/sim-golden/vectors.json`, final hash `bb46012ea5aaaebf`, every tick compared. Data: `spike-report.json`; per-target build reports `plugin-*.json` in each `logs/evidence/M0-11*` folder. | Target | Result | Plugin | Step cost (median, ns/tick: 1 / 5,000 movers) | |---|---|---|---| | macOS (Apple M3 player) | **pass** — hash match, all scenarios | dylib arm64 406,288 B | 108 / 333,200 | | Android (nubia NX709S, APK) | **pass** — 4 tiers, hash match | .so arm64 316,552 B (stripped, 16 KB aligned) | 54.5 / 149,075–158,175 | | Web (headless Chrome) | **pass** — 0 console errors, hash match | static archive 3,662,566 B; Web build +37,947 B (+0.32%) | 70–100 / 160,000–215,000 (timer-quantized) | | iOS (aarch64-apple-ios) | **built, not tested** (ADR-032) | static archive 2,333,096 B (debug stripped) | — | | Windows (x86_64-pc-windows-msvc) | **staticlib built; DLL blocked**, not tested | .lib 3,701,330 B; no DLL | — | 5,000-mover costs include the C# input fill; all stay under 0.35 ms of a 16.7 ms frame. ## Toolchains Unity 6000.3.25f1 · rustc 1.99.0 (LLVM 23) · Android NDK r27c (bundled) · Emscripten 3.1.39-git with LLVM 17 (bundled) · Xcode 26.6, iPhoneOS SDK 26.5, minimum iOS 15.0. ## Web specifics - Emscripten feature rewrite: rustc's objects list the LLVM 20+ `target_features` names `bulk-memory-opt` and `call-indirect-overlong`; the bundled LLVM 17/Binaryen rejects them, so `tools/sim/build-plugin.mjs web` drops them (implied by `bulk-memory` and `reference-types`, which stay). Re-check on every rustc or Unity upgrade. - Browser floor: Chrome 95, Firefox 100, Safari 15.2 (the precompiled std keeps legacy wasm EH pads, bulk memory and reference types). Lowering it needs `-Zbuild-std` with `target-cpu=mvp` (nightly flags). - `panic=abort` on the Web: no `catch_unwind`, so the plugin relies on its panic-free code (clippy denies indexing/panic). ## iOS (recorded not tested) `node tools/sim/build-plugin.mjs ios`: staticlib at iOS 15.0, every member iOS platform, 9 header exports, needs only `-lSystem -lc -lm`; the C ABI smoke links with the iPhoneOS SDK (not run: no device or simulator target here). 229 of 375 members (Rust's prebuilt std/compiler_builtins) carry embedded LLVM 23 bitcode that Xcode's LLVM cannot parse; the linker drops it (the linked smoke has no `__LLVM` segment). Installed at `Assets/Zoen/Plugins/iOS/libzoen_sim_ffi.a` (iOS player only); iOS builds get `ZOEN_SIM_STATIC`. The Unity Xcode export and an unsigned `xcodebuild` are M0-11D2. ## Windows (recorded not tested) `node tools/sim/build-plugin.mjs windows`: the staticlib builds (COFF x86-64, 9 exports). The DLL does not link with rust-lld: it needs the Windows SDK import libraries (kernel32, ntdll, userenv, ws2_32, dbghelp) and the MSVC CRT (msvcrt, vcruntime, ucrt). Getting them means accepting Microsoft's licence (owner): Visual Studio Build Tools on a …
plugin-ios.json · 2 kB · open
{
"what": "zoen-sim C ABI static library for iOS arm64 (M0-11D)",
"status": "built; recorded not tested (ADR-032)",
"finished": "2026-10-10T20:46:26.700Z",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"target": "aarch64-apple-ios",
"deploymentTarget": "15.0",
"xcode": "Xcode 26.6",
"profile": "plugin (release, lto, codegen-units 1, strip debuginfo) + strip -S",
"platforms": [
"2"
],
"minos": [
"15.0"
],
"nativeLibs": [
"-lSystem",
"-lc",
"-lm"
],
"exports": [
"zoen_sim_abi_version",
"zoen_sim_create",
"zoen_sim_destroy",
"zoen_sim_push_inputs",
"zoen_sim_read_actors",
"zoen_sim_read_events",
"zoen_sim_spawn",
"zoen_sim_state",
"zoen_sim_step"
],
"embeddedBitcodeMembers": 229,
"cSmokeLink": {
"linked": true,
"sdk": "26.5",
"platform": "IOS",
"minos": "15.0",
"bytes": 369152,
"keepsBitcode": false,
"ran": false,
…plugin-windows.json · 2 kB · open
{
"what": "zoen-sim C ABI for Windows x86_64 (M0-11D)",
"status": "staticlib built; DLL blocked on the MSVC CRT and Windows SDK import libraries (Microsoft licence, owner); recorded not tested (ADR-032)",
"finished": "2026-10-10T20:46:38.415Z",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"target": "x86_64-pc-windows-msvc",
"profile": "plugin (release, lto, codegen-units 1, strip debuginfo)",
"nativeLibs": [
"kernel32.lib",
"ntdll.lib",
"userenv.lib",
"ws2_32.lib",
"dbghelp.lib",
"/defaultlib:msvcrt"
],
"objectFormats": [
"coff-x86-64",
"COFF-import-file"
],
"exports": [
"zoen_sim_abi_version",
"zoen_sim_create",
"zoen_sim_destroy",
"zoen_sim_push_inputs",
"zoen_sim_read_actors",
"zoen_sim_read_events",
"zoen_sim_spawn",
"zoen_sim_state",
"zoen_sim_step"
],
"staticlib": {
"path": "target/x86_64-pc-windows-msvc/plugin/zoen_sim_ffi.lib",
"bytes": 3701330,
"sha256": "c3b949ad0b1cd520105bb0c28ed7f8cf76cf98001c8f53fe4e985b5a29cd1bf6",
"members": 291
},
"dll": {
"status": "blocked",
"linker": "rust-lld (lld-link flavour)",
"missingImportLibs": [
…spike-report.json · 4 kB · open
{
"task": "M0-11D",
"spike": "M0-11 one simulation (ADR-029)",
"finished": "2026-10-10T20:49:40.727Z",
"golden": {
"scenario": "walk_eight_directions",
"finalHash": "bb46012ea5aaaebf",
"source": "packages/sim-golden/vectors.json"
},
"toolchain": {
"unity": "6000.3.25f1",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"androidNdk": "r27c (27.2.12479018, bundled with Unity)",
"emscripten": "3.1.39-git (bundled with Unity, LLVM 17 fork)",
"xcode": "Xcode 26.6",
"iphoneosSdk": "26.5",
"iosDeploymentTarget": "15.0"
},
"targets": [
{
"target": "macOS",
"rust": "aarch64-apple-darwin",
"result": "pass",
"tested": true,
"evidence": "logs/evidence/M0-11/",
"binary": {
"kind": "dylib arm64",
"bytes": 406288
},
"stepNsPerTick": {
"movers1": 108,
"movers5000": 333200
},
"note": "macOS player (Apple M3), finalHash match, allMatch"
},
{
"target": "Android",
"rust": "aarch64-linux-android",
"result": "pass",
"tested": true,
…Tests
$ node tools/sim/build-plugin.mjs ios$ node tools/sim/build-plugin.mjs ios$ node tools/sim/build-plugin.mjs windows$ node tools/sim/build-plugin.mjs windows$ node tools/unity-run.mjs editmode$ pnpm --filter @zoen/wiki exec playwright test --only-changedNotes
2026-10-10 20:50 UTC · Roadmap: roadmap.json tracks no task or gate state (only status=replaced), so nothing to set; done-state comes from the task log. ADR-029 + ADR-003 status line updated.
2026-10-10 20:51 UTC · Done; M0-11 complete. rustup targets aarch64-apple-ios + x86_64-pc-windows-msvc (owner approval 2026-10-10). Xcode 26.6 is now installed (iPhoneOS SDK 26.5; CONTINUE_HERE said absent). build-plugin.mjs ios: staticlib at iOSTargetOSVersionString 15.0, strip -S 5,890,424 -> 2,333,096 B (375 members, all platform iOS minos 15.0, needs -lSystem -lc -lm, 9 exports); C smoke linked with xcrun --sdk iphoneos clang (not run: no device/sim target, ADR-032). 229 std/compiler_builtins members embed LLVM 23 bitcode that Apple nm (LLVM 21) cannot parse: nm --no-llvm-bc; the link drops it (smoke has no __LLVM segment). Installed Assets/Zoen/Plugins/iOS/libzoen_sim_ffi.a with a hand-written iOS-only .meta (avoids the default-meta first import seen in C2). build-plugin.mjs windows: staticlib 3,701,330 B (COFF x86-64 + raw-dylib import members, 9 exports); DLL via rust-lld blocked: missing kernel32/ntdll/userenv/ws2_32/dbghelp.lib + msvcrt.lib (MSVC CRT, Windows SDK: Microsoft licence) -> owner-licence pending line in logs/reviews.jsonl; ZOEN_WIN_LIBS hook passes lib dirs once allowed. No Windows player build (no DLL). SimPluginImport: IOSPlugin/WindowsPlugin + ApplyIOS (iOS only, no editor) / ApplyWindows (StandaloneWindows64 only, CPU x86_64, no editor), StaticLibraryFor(target); Build.PlayerDefines adds ZOEN_SIM_STATIC for WebGL and iOS when their .a exists. EditMode 81/81 (+IOSPluginImportsForTheIOSPlayerOnly, +WindowsPluginImportsForTheWindows64PlayerOnly on a stand-in .dll, OnlyTheWebBuild... renamed OnlyTheStaticLibraryBuildsGetTheStaticSimDefine). Evidence logs/evidence/M0-11D/: plugin-ios.json, plugin-windows.json, spike-report.md/.json. ADR-029 spike result (confirmed with qualification; open risks Windows licence/no machine, iOS not run, Emscripten LLVM gap, Web floor). verify --changed green. Optional M0-11D2: Unity iOS Xcode export (needs Build.IOS + unity-run build ios export path) and unsigned xcodebuild now that Xcode exists.
