Web Build Crash Fixes (JS/WASM)
Posting a bit more info here in case it saves someone else some time.
Got the web build (-target:js_wasm32) stable after hitting two totally separate crashes. Here’s what broke and what I changed.
1) Startup crash: core:os not supported on JS/WASM
What happened
The game would start booting, then immediately die with an Odin runtime error pointing at core:os being “not yet implemented” for the JS target. The browser console would then spiral into loader failures and eventually a WASM trap.
Why it happened
settings_save.odin was calling core:os directly (os.read_entire_file, os.write_entire_file). Those procedures simply aren’t implemented for JS/WASM in Odin, so the build was guaranteed to abort as soon as settings I/O ran.
The annoying part: the project already had the right abstraction in place. utils.odin exposes read_entire_file / write_entire_file with per platform implementations:
-
Native: delegates to
core:os -
Web: uses
fopen/fread/fwriteagainst Emscripten’s virtual FS
…butsettings_save.odinbypassed it.
Fix
settings_save.odin now uses the existing wrappers instead of importing core:os:
-
removed
import "core:os" -
swapped
os.read_entire_file(...)→read_entire_file(...) -
swapped
os.write_entire_file(...)→write_entire_file(...)
Result
Web build can get past init again. This fixes the crash; persistence still depends on how Emscripten FS is mounted/synced in the actual deployment.
2) Gameplay crash: Aborted(alignment fault) from RNG
What happened
After settings stopped killing the build, gameplay would crash shortly after starting with:
Uncaught RuntimeError: Aborted(alignment fault)
Stack trace pointed straight into RNG usage (7 bag shuffle / refill_and_shuffle) via rand.int_max(...).
Why it happened
WebAssembly traps on unaligned 64 bit memory access. Odin’s default RNG (core:math/rand) keeps 64 bit state internally, and in this configuration the RNG state ended up being touched in a way that triggered an unaligned 64 bit read/write instant WASM abort.
Fix approach
Stopped calling rand.* from gameplay code and added a tiny platform RNG layer:
-
Native builds: keep using
core:math/rand -
WASM builds: use a simple 32 bit xorshift (
u32state only) to avoid any 64 bit alignment issues
Code changes
Added two platform files with the same API:
-
source/random_web.odin(#+build wasm32, wasm64p32)-
xorshift32-backed
-
web_rand_init(),game_rand_int_max,game_rand_int31_max,game_rand_float,game_rand_float_range
-
-
source/random_default.odin(#+build !wasm32and!wasm64p32)-
wrapper around
core:math/randwith the same functions
-
Then in game.odin:
-
call
web_rand_init()fromgame_init()(no-op on native) -
replaced all gameplay RNG calls
rand.*→game_rand_*
Result
No more alignment fault during gameplay. 7 bag shuffle and other RNG heavy bits run cleanly on the web build now.
MuTris
Tetris Evolved Through Mutation
| Status | In development |
| Author | meapps |
| Genre | Puzzle |
| Tags | 2D, Arcade, Indie, made_with_raylib, madewithraylib, raylib, Retro, Roguelike, Singleplayer, Tetris |
| Languages | English |
More posts
- Final Web Release1 day ago
- The new 1.4.2 update is here jump in and play directly in your browser!23 days ago
- Steam Release, Cut Content, and Next Steps26 days ago
- Steam Next Fest and upcoming demo on steam!Aug 18, 2025
- Upcoming Update 1.42, Steam Demo, and More!Jun 01, 2025
- Upcoming Update 1.41!!!Apr 27, 2025
- New update!!!Apr 25, 2025
- Finally fixed Scrolling with the Arrow KeysApr 24, 2025
- Add the Fullscreen mode and BG music!!!Apr 24, 2025

Leave a comment
Log in with itch.io to leave a comment.