Spaces:
Sleeping
WASM Maintenance & Robustness Guide
This document answers the question: "What do I change as I continue developing, and will this continue to work no matter what?"
Executive Summary
No, this will NOT continue to work "no matter what."
The WASM distribution relies on a specific set of constraints and parallel implementations. Breaking these constraints will cause the offline mode to fail to compile or behave incorrectly, even if the Python backend works fine.
Key Architectures to Maintain
1. Dual Bindings (py_bindings.rs vs wasm_bindings.rs)
The Rust engine now has two separate entry points:
src/py_bindings.rs: Usespyo3to expose classes to Python.src/wasm_bindings.rs: Useswasm-bindgento expose classes to JavaScript.
What to do:
- If you add a new method to
GameState(e.g.,undo_turn()) and want it available in the offline game, you must expose it in BOTH files. py_bindingsreturns Python objects;wasm_bindingsmust return Serde-serializable structs or primitives that JS can understand.
2. Dependency Management (Cargo.toml)
WebAssembly runs in a sandboxed browser environment. It generally cannot use:
- C-linked libraries (unless compiled to WASM, which is hard).
- File System I/O (
std::fs,std::iorelated to files). - Networking (
std::net,reqwestusually need WASM-specific feature flags). - Multi-threading (Standard
std::threadis not supported;rayonis included but generally falls back to serial on WASM unless configured with Web Workers).
Critical Rules:
- Gate Python Dependencies:
pyo3andnumpymust ALWAYS be optional and gated behind theextension-modulefeature.# Good pyo3 = { version = "...", optional = true } - Gate System Dependencies: If you need to read a file in Rust, gate it so it doesn't compile for WASM.
#[cfg(not(target_arch = "wasm32"))] fn read_config() { ... }
3. The "Mock" Adapter (wasm_adapter.js)
The wasm_adapter.js file manually mimics the behavior of your Python Flask server (server.py).
What to do:
- If you change the format of the JSON returned by
/api/statein Python, you MUST updatewasm_adapter.jsto match. - If you add a new endpoint (e.g.,
/api/play_sound), the offline mode will throw errors unless you implement a handler for it inwasm_adapter.js(ormain.jschecks for offline mode).
4. Data Format (cards_compiled.json)
The WASM engine loads the card database from a JSON file fetched via HTTP (fetch('/data/cards_compiled.json')).
Robustness:
- If
CardDatabase::from_jsonin Rust changes its expected schema, thecards_compiled.jsonfile must be regenerated. - Since WASM cannot scan a directory of images or JSONs, this "compiled" single file is the Single Source of Truth for the offline engine.
Checklist for New Features
When implementing a new feature (e.g., "Mulligan Phase"):
- Core Logic: Implement in
src/core/logic.rs. (Safe for both) - Python API: Expose in
src/py_bindings.rs. - WASM API: Expose in
src/wasm_bindings.rs. - Verification: Run
cargo build --target wasm32-unknown-unknown --release --no-default-featuresto ensure you didn't break the WASM build. - Frontend: Update
main.js/wasm_adapter.jsif the API signature changed.
Troubleshooting
- "Crate
pyo3not found": You are trying to compile WASM with default features. Use--no-default-features. - "Random number generator error": Ensure
getrandomis set tofeatures = ["wasm_js"](orjsfor v0.2) inCargo.toml. - "Undefined symbol": You likely used a C library or system call not available in the browser.