feat(web): add solitaire_web Bevy WASM build targeting play.html canvas
Build and Deploy / build-and-push (push) Failing after 58s
Build and Deploy / build-and-push (push) Failing after 58s
Adds a new `solitaire_web` crate that compiles the full `solitaire_engine` to `wasm32-unknown-unknown` and renders to a `<canvas id="bevy-canvas">` element in `play.html` — the same ECS code path as desktop and Android. Changes to enable the WASM target: - .cargo/config.toml: add wasm32-unknown-unknown rustflags for getrandom - Workspace Cargo.toml: add solitaire_web member - solitaire_data/Cargo.toml: gate tokio/reqwest/dirs/keyring to non-wasm - solitaire_data/src: add wasm32 branch to data_dir() (returns None); cfg-gate sync_client network types, auth_tokens, matomo_client - solitaire_engine/Cargo.toml: gate tokio/reqwest/kira/arboard/dirs/zip to non-wasm (mio/cpal/arboard don't compile for wasm32-unknown-unknown) - solitaire_engine/src/lib.rs: cfg-gate module declarations and re-exports for analytics, audio, sync, sync_setup, avatar, leaderboard plugins - solitaire_engine/src/core_game_plugin.rs: cfg-gate plugin registrations that require TokioRuntime (audio, sync, analytics, leaderboard, avatar) - solitaire_engine/src/resources.rs: cfg-gate TokioRuntimeResource - solitaire_engine/src/game_plugin.rs: cfg-gate std::fs::remove_file (x10) - solitaire_engine/src/theme/mod.rs: cfg-gate importer module (uses dirs+zip) - solitaire_engine/src/settings_plugin.rs: cfg-gate theme ZIP import UI - solitaire_engine/src/assets/sources.rs: cfg-gate FileAssetReader/user_theme_dir - solitaire_engine/src/auto_complete_plugin.rs: cfg-gate audio system - solitaire_engine/src/daily_challenge_plugin.rs: cfg-gate server fetch - solitaire_engine/src/hud_plugin.rs: cfg-gate AvatarResource import - solitaire_engine/src/profile_plugin.rs: cfg-gate AvatarResource import - solitaire_server/web/play.html: minimal HTML canvas shell - solitaire_web/: new crate (Cargo.toml + src/lib.rs) - build_wasm.sh: add Bevy WASM build step (cargo + wasm-bindgen + wasm-opt) All tests pass; clippy --workspace -- -D warnings clean; native build (solitaire_engine, solitaire_app) unaffected. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
[package]
|
||||
name = "solitaire_web"
|
||||
version.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
solitaire_engine = { path = "../solitaire_engine" }
|
||||
solitaire_data = { path = "../solitaire_data" }
|
||||
# Direct dep so `bevy::` resolves in lib.rs; zero extra features so this
|
||||
# contributes nothing to unification with the desktop/Android feature set.
|
||||
bevy = { workspace = true }
|
||||
wasm-bindgen = "0.2"
|
||||
getrandom = { version = "0.3", features = ["wasm_js"] }
|
||||
console_error_panic_hook = "0.1"
|
||||
|
||||
# webgl2 must only be enabled for the wasm target — it constrains the
|
||||
# renderer to WebGL2 compatibility limits, which is wrong for native builds.
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
bevy = { workspace = true, features = ["webgl2"] }
|
||||
@@ -0,0 +1,42 @@
|
||||
//! Browser entry point for the Ferrous Solitaire Bevy WASM build.
|
||||
//!
|
||||
//! This crate compiles the full `solitaire_engine` to `wasm32-unknown-unknown`
|
||||
//! and renders to a `<canvas id="bevy-canvas">` element. It shares the same
|
||||
//! ECS code path as the desktop and Android builds; the only differences are:
|
||||
//! - Audio, sync, and analytics plugins are cfg-gated out in `CoreGamePlugin`
|
||||
//! on the wasm32 target (see `solitaire_engine/src/core_game_plugin.rs`).
|
||||
//! - `LocalOnlyProvider` is passed as the sync provider (sync is disabled).
|
||||
//! - Storage is handled automatically by `WasmStorage` (localStorage-backed),
|
||||
//! wired by `CoreGamePlugin` via `default_storage_backend()`.
|
||||
|
||||
use bevy::prelude::*;
|
||||
use bevy::window::{Window, WindowPlugin};
|
||||
use solitaire_data::LocalOnlyProvider;
|
||||
use solitaire_engine::CoreGamePlugin;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn start() {
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
App::new()
|
||||
.add_plugins(
|
||||
DefaultPlugins.set(WindowPlugin {
|
||||
primary_window: Some(Window {
|
||||
// Bind to the existing <canvas id="bevy-canvas"> in play.html.
|
||||
// Without this, Bevy appends its own canvas to <body>.
|
||||
canvas: Some("#bevy-canvas".into()),
|
||||
// Let CSS size the canvas; Bevy follows the element's size.
|
||||
fit_canvas_to_parent: true,
|
||||
// Prevent the browser stealing keyboard events and scroll.
|
||||
prevent_default_event_handling: true,
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
}),
|
||||
)
|
||||
// LocalOnlyProvider disables cloud sync — correct for the web build
|
||||
// since SyncPlugin is cfg-gated out on wasm32 anyway.
|
||||
.add_plugins(CoreGamePlugin::new(Box::new(LocalOnlyProvider)))
|
||||
.run();
|
||||
}
|
||||
Reference in New Issue
Block a user