3.2 KiB
Build Output Locations
Load when: configuring build tools, troubleshooting "where did the output go?", auditing .local/, or writing .gitignore entries for generated artifacts.
Hard rule: build output is never inside src/
src/ is source-only. Every generated / built artifact — Rust target/,
wasm-pack pkg/, TypeScript dist/, Godot exports, anything else a tool
emits — goes under .local/build/** (gitignored, per-host) or under a
package-local dist/ outside of src/.
This rule exists because of two incidents:
- Rust
target/insidesrc/(historical) — cargo's default target sat atsrc/simulator/target/and accidentally committed ~25 GB / 65k files to git before being purged. Target was relocated to.local/build/rust/viasrc/simulator/.cargo/config.toml. - wasm-pack
pkg/insidesrc/(2026-04-17) —build-wasm.shused wasm-pack's default--out-dir ../pkgand emittedsrc/simulator/pkg/, violating the rule.pkg/was relocated to.local/build/wasm/via--out-dir ../../.local/build/wasm.
./run verify enforces this invariant — step 16
_verify_no_build_in_src fails the regression gate if
src/simulator/pkg/ or any src/**/target/ tree has content. .gitignore
also explicitly lists src/simulator/pkg/ as a belt-and-suspenders
safety net in case anyone runs wasm-pack directly without the script.
If you find yourself writing into src/**/target/, src/**/pkg/,
src/**/dist/, or src/**/build/, stop — something's misconfigured.
Canonical artifact paths
| System | Output path | Configured in |
|---|---|---|
| Rust (cargo) | .local/build/rust/ |
src/simulator/.cargo/config.toml |
| Godot exports | .local/build/godot/<version>/<platform>/ |
scripts/run/remote.sh, scripts/run/export.sh |
| WASM (wasm-pack) | .local/build/wasm/ |
src/simulator/build-wasm.sh (--out-dir override) |
| GDExtension binary | src/game/engine/addons/magic_civ_physics/*.{so,dll,dylib} |
src/simulator/build-gdext.sh |
| TypeScript (Vite) | <pkg>/dist/ per package |
each vite.config.ts (Vite default) |
The GDExtension output is the one exception where a build product
lands inside src/ — Godot's GDExtension loader requires the binary
to live next to the .gdextension manifest, so the path is dictated
by the consumer runtime, not our build system. Those files are
gitignored (.gitignore:69-72) and built per-host from a different
build script (build-gdext.sh) that reads from .local/build/rust/.
When a Vite alias or Dockerfile references the WASM output
Use .local/build/wasm/magic_civ_physics.js as the canonical entry
point. Concrete examples:
// public/games/age-of-dwarves/guide/vite.config.ts
'@magic-civ/physics-rs': path.resolve(__dirname, '../../../../.local/build/wasm/magic_civ_physics.js'),
# public/games/age-of-dwarves/guide/e2e/Dockerfile.web
COPY .local/build/wasm/ ./.local/build/wasm/
Do NOT resurrect src/simulator/pkg/ in any new config. It is
gitignored, the verify gate fails on content there, and the doc
surfaces below are single-sourced — a stale reference creeping in
will be caught by grep -R "src/simulator/pkg" . --exclude-dir=node_modules.