fix(@projects/@magic-civilization): 🐛 resolve wasm build getrandom dependency error

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Natalie 2026-04-30 23:59:41 -04:00
parent 5cac55a1d3
commit 957eae6448
3 changed files with 168 additions and 10 deletions

View file

@ -0,0 +1,128 @@
---
id: p1-52
title: api-wasm build fix — unblock WASM bundle for design-lab WASM consumption
priority: p1
status: missing
scope: game1
owner: terraformer
updated_at: 2026-05-01
wave: A.5
coordinates_with:
- p1-46
- p1-47
- p1-48
- p1-49
- p1-50
- p2-49
- p2-50
canonical_doc: public/games/age-of-dwarves/docs/terrain/WORLDGEN_RNG.md
---
## Summary
`bash src/simulator/build-wasm.sh` currently fails with an upstream
compilation error in the `getrandom 0.3.x` line on `wasm32-unknown-unknown`
(both `0.3.3` and `0.3.4` reference `backends::inner_u32` /
`backends::inner_u64` symbols that don't exist in the wasm32 backend,
even with `--cfg getrandom_backend="wasm_js"`).
Root of the dep chain (from `cargo tree -p magic-civ-physics --target
wasm32-unknown-unknown -i getrandom@0.3.4`):
```
getrandom v0.3.4
└── rand_core v0.9.5
├── rand v0.9.2
│ └── mc-trade v0.1.0
│ ├── mc-ai v0.1.0 → mc-turn → mc-mapgen → magic-civ-physics
│ └── mc-turn ─────────────^
└── rand_chacha v0.9.0 → rand v0.9.2
```
Wave A pinned the workspace to `rand = "0.9"` (in `mc-trade`) which
forces `rand_core 0.9.x` which forces `getrandom 0.3.x`. The native
build (cargo test on the workspace) compiles fine because native
`getrandom` doesn't take the broken backends path; only the
`wasm32-unknown-unknown` target hits it.
This blocks the **rolling Wave E** plan: every Wave AD objective
ships Rust + GDExt + WASM bridges, but the WASM bundle can't be built,
so the design lab can't consume WASM-built selectors and is stuck on
the TS twins. By extension, p1-46 (Wave E lab integration) cannot
land until WASM builds are green.
This objective is **Wave A.5** — sits between Wave A (foundation
crates) and Waves BE (consumers). Lands as a small, focused workspace
fix.
## Acceptance
- ◻ **Root cause documented** — short writeup in
`src/simulator/api-wasm/BUILD.md` (new) explaining why `getrandom
0.3.x` fails on `wasm32-unknown-unknown` with our workspace deps,
and the chosen fix path. Future contributors who hit the same wall
read this first.
- ◻ **WASM build green**`bash src/simulator/build-wasm.sh` exits 0,
produces `.local/build/wasm/magic_civ_physics_bg.wasm` and
`magic_civ_physics.d.ts` containing — at minimum — these exports:
- `tileTectonicsJson(col, row): string | undefined`
- `tileClimateJson(col, row): string | undefined`
- `tileHydrologyJson(col, row): string | undefined`
Verify by `grep -E 'tile(Tectonics|Climate|Hydrology)Json'
.local/build/wasm/magic_civ_physics.d.ts | wc -l` returns 3.
- ◻ **Native build still green**`cargo check --workspace` clean
after the fix; `cargo test -p mc-mapgen -p mc-climate -p mc-trade
-p mc-turn -p mc-ai` all pass. The fix must not regress native
builds.
- ◻ **Determinism preserved** — the parity tests Wave A established
(`mc-mapgen/tests/cross_build_determinism.rs`) still pass byte-for-
byte after the fix. If the fix involves swapping a randomness source
(e.g. downgrading `rand`), the seed-derive output must be unchanged.
- ◻ **Doc updated**`WORLDGEN_RNG.md` §11 "Open questions" gets a
new closed bullet recording the fix decision (e.g. "rand pinned to
0.8 in mc-trade due to getrandom 0.3.x wasm32 breakage"). The
doc-↔-code mirror reflects the actual dep state.
- ◻ **Smoke import test** — add a stub TypeScript file at
`.project/designs/app/src/utils/wasm/smoke.ts` (or similar) that
imports each of the three new `tile*Json` functions and exports a
no-op caller. `npx tsc --noEmit` clean from the design app proves
the WASM bundle is reachable from the lab. This is the gate that
unblocks Wave E rolling.
## Why this is its own objective rather than a hidden fix in p1-46
p1-46 (Wave E) consumes the WASM bundle but doesn't own it. If WASM
build is broken, every downstream Wave is blocked from showing
visual proof — that's a cross-cutting infra concern, not a
lab-specific one. Splitting it out lets `simulator-infra` own the fix
without coupling it to lab-rendering work.
## Non-goals
- Wiring the lab to actually consume the WASM bundle — that's p1-46
Wave E (or rolling-Wave-E increments).
- Adding new WASM exports beyond what Wave A/B already authored —
this objective unblocks the existing surface, doesn't extend it.
- GDExt build pipeline — Godot's bridge is a different cargo target
and doesn't hit this issue. Out of scope.
## Suggested fix paths (specialist picks one)
In rough order of cleanliness:
1. **`[patch.crates-io]` workspace entry** pinning `getrandom 0.3` to
the latest 0.3.x that actually compiles on `wasm32-unknown-unknown`
— if such a version exists. Fast, surgical.
2. **Downgrade `mc-trade`'s `rand` to 0.8** (which uses
`getrandom 0.2.x`, known-good on wasm32). Requires updating
`rand_chacha` and any 0.9-only API usage. Medium scope.
3. **Patch `getrandom 0.3.x` via a fork** with the missing
`backends::inner_*` exports. Highest scope, last resort.
Specialist verifies determinism vector after the fix — Wave A's
`cross_build_determinism.rs` is the canary.
## Dependencies
- Wave A landed (p1-50, p2-49, p2-50) — gives the WASM bridge
functions to verify exist in the built bundle.

View file

@ -881,7 +881,7 @@ dependencies = [
"mc-tech",
"mc-trade",
"mc-turn",
"rand",
"rand 0.8.6",
"serde",
"serde_json",
"tokio",
@ -1142,7 +1142,7 @@ dependencies = [
name = "mc-trade"
version = "0.1.0"
dependencies = [
"rand",
"rand 0.8.6",
"serde",
"serde_json",
]
@ -1163,7 +1163,7 @@ dependencies = [
"mc-trade",
"pollster",
"proptest",
"rand",
"rand 0.8.6",
"serde",
"serde_json",
"wgpu",
@ -1420,8 +1420,8 @@ dependencies = [
"bit-vec",
"bitflags 2.11.0",
"num-traits",
"rand",
"rand_chacha",
"rand 0.9.2",
"rand_chacha 0.9.0",
"rand_xorshift",
"regex-syntax",
"rusty-fork",
@ -1456,14 +1456,35 @@ version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]]
name = "rand"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
dependencies = [
"libc",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha",
"rand_core",
"rand_chacha 0.9.0",
"rand_core 0.9.5",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core 0.6.4",
]
[[package]]
@ -1473,7 +1494,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.9.5",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom 0.2.17",
]
[[package]]
@ -1491,7 +1521,7 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a"
dependencies = [
"rand_core",
"rand_core 0.9.5",
]
[[package]]

View file

@ -35,7 +35,7 @@ members = [
serde = { version = "1", features = ["derive"] }
serde_json = "1"
getrandom = "0.2"
rand = "0.9"
rand = "0.8"
siphasher = "0.3" # pinned — worldgen seed derivation; see mc-mapgen/RNG.md
# Workspace-wide lint configuration — Python-styled Rust.