fix(web): rebuild Bevy canvas WASM; add SolitaireGame interactive API
Grey screen fix (canvas_bg.wasm): - Rebuilt Bevy WASM from refactored solitaire_core that removes the per-game KlondikeAdapter field from GameState. The old binary was built with wasm-opt -Oz; the large adapter allocation pattern appears to trigger an over-aggressive wasm-opt optimisation that corrupts Bevy's render pipeline, causing a permanent grey screen on /play. - build_wasm.sh: change wasm-opt -Oz → -O2. Speed-optimised level avoids the size-focused transforms that miscompile Bevy's deep render stacks. solitaire_core refactoring: - game_state.rs: remove adapter: KlondikeAdapter field; use static KlondikeAdapter::config_for() instead of a per-instance allocation. Gate test_pile_state behind #[cfg(feature = "test-support")] so production builds carry no test-only heap state. Add instruction_history() public accessor (delegates to saved_moves()). - card.rs: add Card::new(), face_up(), face_down() const constructors for more ergonomic test and wasm code. - pile.rs, solver.rs: cargo fmt. solitaire_wasm interactive API: - lib.rs: add SolitaireGame wasm-bindgen struct with draw(), move_cards(), undo(), auto_complete_step(), serialize(), from_saved() — the full player-action surface used by game.js. Add DebugSnapshot, DebugMove, DebugInvariantReport structs and debug_snapshot(), debug_legal_moves(), debug_apply_move_json() methods for e2e test automation (window.__FERROUS_DEBUG__ bridge). Add replay_moves() to export the current game as a Replay v2 payload. - solitaire_wasm.js + solitaire_wasm_bg.wasm: rebuilt with new API. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
@@ -122,6 +122,67 @@ export class SolitaireGame {
|
||||
const ret = wasm.solitairegame_auto_complete_step(this.__wbg_ptr);
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* Applies the legal move currently at `index` from `debug_legal_moves()`.
|
||||
* @param {number} index
|
||||
* @returns {any}
|
||||
*/
|
||||
debug_apply_legal_move(index) {
|
||||
const ret = wasm.solitairegame_debug_apply_legal_move(this.__wbg_ptr, index);
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* Applies one debug move encoded as JSON.
|
||||
*
|
||||
* JSON must match [`DebugMove`], for example:
|
||||
* `{"kind":"move","from":"tableau-0","to":"foundation-1","count":1}` or
|
||||
* `{"kind":"stock_click"}`.
|
||||
* @param {string} move_json
|
||||
* @returns {any}
|
||||
*/
|
||||
debug_apply_move_json(move_json) {
|
||||
const ptr0 = passStringToWasm0(move_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
const ret = wasm.solitairegame_debug_apply_move_json(this.__wbg_ptr, ptr0, len0);
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* Returns all currently-legal debug moves as a JS array.
|
||||
*
|
||||
* Includes [`DebugMove::StockClick`] when stock interaction is legal.
|
||||
* @returns {any}
|
||||
*/
|
||||
debug_legal_moves() {
|
||||
const ret = wasm.solitairegame_debug_legal_moves(this.__wbg_ptr);
|
||||
if (ret[2]) {
|
||||
throw takeFromExternrefTable0(ret[1]);
|
||||
}
|
||||
return takeFromExternrefTable0(ret[0]);
|
||||
}
|
||||
/**
|
||||
* Returns deterministic instruction history for the current game.
|
||||
*
|
||||
* Together with `seed()` and `draw_mode`, this history is replayable.
|
||||
* @returns {any}
|
||||
*/
|
||||
debug_move_history() {
|
||||
const ret = wasm.solitairegame_debug_move_history(this.__wbg_ptr);
|
||||
if (ret[2]) {
|
||||
throw takeFromExternrefTable0(ret[1]);
|
||||
}
|
||||
return takeFromExternrefTable0(ret[0]);
|
||||
}
|
||||
/**
|
||||
* Returns a comprehensive debug snapshot for automated verification.
|
||||
* @returns {any}
|
||||
*/
|
||||
debug_snapshot() {
|
||||
const ret = wasm.solitairegame_debug_snapshot(this.__wbg_ptr);
|
||||
if (ret[2]) {
|
||||
throw takeFromExternrefTable0(ret[1]);
|
||||
}
|
||||
return takeFromExternrefTable0(ret[0]);
|
||||
}
|
||||
/**
|
||||
* Draw from stock to waste (or recycle waste → stock when stock is empty).
|
||||
* Returns `{ok, error?, snapshot?}`.
|
||||
@@ -182,6 +243,21 @@ export class SolitaireGame {
|
||||
SolitaireGameFinalization.register(this, this.__wbg_ptr, this);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Returns replay moves encoded in the `solitaire_data::Replay` wire format.
|
||||
*
|
||||
* This derives move counts from the deterministic instruction history and
|
||||
* validates that the resulting move stream replays cleanly from the current
|
||||
* game's seed/draw mode.
|
||||
* @returns {any}
|
||||
*/
|
||||
replay_moves() {
|
||||
const ret = wasm.solitairegame_replay_moves(this.__wbg_ptr);
|
||||
if (ret[2]) {
|
||||
throw takeFromExternrefTable0(ret[1]);
|
||||
}
|
||||
return takeFromExternrefTable0(ret[0]);
|
||||
}
|
||||
/**
|
||||
* The seed used to deal this game.
|
||||
* @returns {number}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user