fix(web): resolve wasm32 runtime panics; game boots and renders in Firefox
Build and Deploy / build-and-push (push) Failing after 1m6s

Fixes found while testing the Bevy WASM build in a real browser:

1. chrono wasmbind: add `wasmbind` feature to workspace chrono dep so
   Local::now()/Utc::now() use js-sys::Date on wasm32 (previously
   fell through to std::time::SystemTime which panics on wasm32).

2. std::time::SystemTime: replace all remaining direct SystemTime::now()
   calls (4 sites across game_plugin, difficulty_plugin, time_attack_plugin,
   solitaire_data/storage) with chrono::Utc::now() which is wasm32-safe.

3. user_dir: return empty PathBuf (instead of panicking) when data_dir()
   is None on wasm32; there is no filesystem in the browser so user themes
   are unsupported and a benign empty path is correct.

4. ThemeRegistryPlugin: gate build_registry_on_startup to non-wasm32
   (the filesystem scan for user themes has nothing to scan in the browser;
   only the bundled embedded themes are available).

5. AssetMetaCheck::Never: configure AssetPlugin in solitaire_web to skip
   `.meta` sidecar fetches — we don't ship .meta files, so the default
   AssetMetaCheck::Always produced a 404 flood on every card/background asset.

Result: `http://localhost:<port>/play` boots in Firefox with zero errors
and renders the full Bevy game — home screen, onboarding modal, HUD all
visible. Assets load correctly from /assets/. Chromium has a separate
wgpu-27/ANGLE/GLES shader translation bug (not in our code); Firefox works.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-06-01 14:16:19 -07:00
parent f464aab543
commit a92ac066a6
10 changed files with 72 additions and 56 deletions
+5 -4
View File
@@ -22,7 +22,8 @@
//! was closed, the file is treated as missing.
use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};
use chrono::Utc;
use bevy::prelude::*;
use solitaire_core::game_state::GameMode;
@@ -222,9 +223,9 @@ fn auto_deal_on_time_attack_win(
/// the system time predates the epoch (impossible under any sane clock,
/// but the fallback keeps the function infallible).
fn current_unix_secs() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_or(0, |d| d.as_secs())
// Use chrono so this works on wasm32 (chrono has the `wasmbind` feature;
// std::time::SystemTime panics on wasm32-unknown-unknown).
Utc::now().timestamp().max(0) as u64
}
/// Periodically persists the live `TimeAttackResource` to