Summary
During testing of the new single-file embedded-game export (docs/wasmplayer-single-file-export.md, src/WasmPlayer/scripts/export-embedded.mjs, and the window.QuestVivaEmbeddedGame boot branch near wasm-player.js:1897), I found a reproducible-but-load-dependent console error during WasmPlayer boot:
TypeError: Cannot set properties of undefined (setting 'backgroundColor')
TypeError: Cannot set properties of undefined (setting 'color')
TypeError: Cannot set properties of undefined (setting 'fontFamily')
TypeError: Cannot set properties of undefined (setting 'fontSize')
The stack trace bottoms out inside _framework/dotnet.native.wasm (a generated JS-interop marshaling frame, not application JS) — so this is the .NET WASM runtime itself calling into JS to set 4 style properties together on an object reference that's undefined at that point.
The game still boots and plays correctly despite the errors (confirmed full playthrough works), so this looks non-fatal — but it indicates something in the WASM boot sequence assumes a DOM element (or JS interop handle) exists before it reliably does.
Investigation so far
All done via a local CDN stand-in (a python http.server with Access-Control-Allow-Origin: *, serving a Release AppBundle) and a separate origin serving generated single-file HTML exports, verified with browser dev tools.
- Not specific to the new embedded-game boot path's code. Decoding the exact same
.quest package bytes and loading them via the pre-existing ?url= boot path (network fetch, same origin) did not show the error, while the embedded path (bytes available synchronously via base64, no fetch delay) did, reproducibly, across multiple different game packages (a blank freshly-created draft AND examples/published.quest).
- Not specific to game content. Same bytes reproduced the error whether generated via the Node CLI script (
export-embedded.mjs) or via the AppShell in-browser TypeScript export path (exportSingleFile in src/AppShell/src/lib/editor-store.ts).
- It is timing/load sensitive. An early, low-load test of
published.quest via the embedded path passed completely clean (no errors). A later reload of the identical file under heavier concurrent system load (multiple dev servers + browser tabs running WASM boots simultaneously) reproduced the error consistently.
Working theory: the new embedded-game path is faster than every existing boot source (bytes are already in memory — no network round-trip — before startGame()/Bridge.Initialise() runs), which exposes a latent race that pre-existing (slower) boot sources rarely or never hit.
Where to look
- Search
WasmPlayerBridge.cs / PlayerHelper.cs / GameQuery.cs for JS-interop calls that set background/foreground/font together. Grep hits so far (none obviously match a direct .style.backgroundColor = pattern on a quick read, so the actual call site is probably in the .NET WASM SDK's own generated JSImport marshaling glue, or somewhere not yet located):
JsSetBackground/JsSetForeground — WasmPlayerBridge.cs:354-357,714-723
IPlayer.SetFont/SetFontSize — WasmPlayerBridge.cs:780-782
PlayerHelper.cs's m_fontSize/SetFontSize — PlayerHelper.cs:27-28,332-348
- Check whether
initWasmPlayer (wasm-player.js:446) assumes something set up asynchronously elsewhere (the chrome.css <link> load, jQuery UI init in playercore.js's initPlayerUI, paper.js/grid canvas setup) has completed before Bridge.Initialise/Bridge.InitialiseWithSave (called at wasm-player.js:533-534, right after the synchronous swapInPlayerUi() call at line 530) starts executing game startup scripts that might reach this style-setting interop call.
- Confirm whether pre-existing fast boot sources (
source=editor/source=local, delivered via BroadcastChannel with no network delay) can also reproduce this under load — if so it further confirms this predates the new embedded export feature entirely and is a general latent race, not something introduced by it.
Impact
Not currently blocking anything — the single-file export feature works correctly end-to-end despite this. Worth a dedicated root-cause pass since it suggests a real (if currently harmless) race in the boot sequence.
Summary
During testing of the new single-file embedded-game export (
docs/wasmplayer-single-file-export.md,src/WasmPlayer/scripts/export-embedded.mjs, and thewindow.QuestVivaEmbeddedGameboot branch nearwasm-player.js:1897), I found a reproducible-but-load-dependent console error during WasmPlayer boot:The stack trace bottoms out inside
_framework/dotnet.native.wasm(a generated JS-interop marshaling frame, not application JS) — so this is the .NET WASM runtime itself calling into JS to set 4 style properties together on an object reference that's undefined at that point.The game still boots and plays correctly despite the errors (confirmed full playthrough works), so this looks non-fatal — but it indicates something in the WASM boot sequence assumes a DOM element (or JS interop handle) exists before it reliably does.
Investigation so far
All done via a local CDN stand-in (a
python http.serverwithAccess-Control-Allow-Origin: *, serving a ReleaseAppBundle) and a separate origin serving generated single-file HTML exports, verified with browser dev tools..questpackage bytes and loading them via the pre-existing?url=boot path (network fetch, same origin) did not show the error, while the embedded path (bytes available synchronously via base64, no fetch delay) did, reproducibly, across multiple different game packages (a blank freshly-created draft ANDexamples/published.quest).export-embedded.mjs) or via the AppShell in-browser TypeScript export path (exportSingleFileinsrc/AppShell/src/lib/editor-store.ts).published.questvia the embedded path passed completely clean (no errors). A later reload of the identical file under heavier concurrent system load (multiple dev servers + browser tabs running WASM boots simultaneously) reproduced the error consistently.Working theory: the new embedded-game path is faster than every existing boot source (bytes are already in memory — no network round-trip — before
startGame()/Bridge.Initialise()runs), which exposes a latent race that pre-existing (slower) boot sources rarely or never hit.Where to look
WasmPlayerBridge.cs/PlayerHelper.cs/GameQuery.csfor JS-interop calls that set background/foreground/font together. Grep hits so far (none obviously match a direct.style.backgroundColor =pattern on a quick read, so the actual call site is probably in the .NET WASM SDK's own generated JSImport marshaling glue, or somewhere not yet located):JsSetBackground/JsSetForeground—WasmPlayerBridge.cs:354-357,714-723IPlayer.SetFont/SetFontSize—WasmPlayerBridge.cs:780-782PlayerHelper.cs'sm_fontSize/SetFontSize—PlayerHelper.cs:27-28,332-348initWasmPlayer(wasm-player.js:446) assumes something set up asynchronously elsewhere (thechrome.css<link>load, jQuery UI init inplayercore.js'sinitPlayerUI, paper.js/grid canvas setup) has completed beforeBridge.Initialise/Bridge.InitialiseWithSave(called atwasm-player.js:533-534, right after the synchronousswapInPlayerUi()call at line 530) starts executing game startup scripts that might reach this style-setting interop call.source=editor/source=local, delivered viaBroadcastChannelwith no network delay) can also reproduce this under load — if so it further confirms this predates the new embedded export feature entirely and is a general latent race, not something introduced by it.Impact
Not currently blocking anything — the single-file export feature works correctly end-to-end despite this. Worth a dedicated root-cause pass since it suggests a real (if currently harmless) race in the boot sequence.