-
Notifications
You must be signed in to change notification settings - Fork 8
Native Web
FEBuilderGBA runs in a browser with no install, via WebAssembly — the 4th Avalonia head after desktop, Native Android, and Native iOS, added in #1864. It reuses the same platform-agnostic seams the mobile ports introduced.
🌐 Try it: https://laqieer.github.io/FEBuilderGBA/ — deployed to GitHub Pages.
Authoritative reference: the full design lives in
docs/WEBASSEMBLY.md. Experimental preview.
- A
FEBuilderGBA.Browser/head (net10.0-browser,Microsoft.NET.Sdk.WebAssembly) that builds a wasm AppBundle consuming the same Avalonia views as the desktop GUI, deployed to GitHub Pages by.github/workflows/pages.yml. - The shared
FEBuilderGBA.Avaloniaproject multi-targetsnet10.0;net10.0-browser(opt-inEnableBrowserTarget, default OFF). - Built on
FEBuilderGBA.Core+FEBuilderGBA.Avalonia. WinForms is not browser-capable and is excluded.
| Area | How it works |
|---|---|
| UI / lifetime | The shared single-view shell (Views/MainView) under ISingleViewApplicationLifetime, same as Android/iOS — no browser-specific UI code. |
| Rendering |
Avalonia.Browser 11.2.3 + SkiaSharp.NativeAssets.WebAssembly 2.88.9 + HarfBuzzSharp.NativeAssets.WebAssembly 7.3.0.3 (BOTH wasm natives are emcc-relinked into dotnet.wasm) + Avalonia.Fonts.Inter (wasm has no system fonts). |
config/ |
There is no real filesystem: config/** (excl. patch2) is zipped into wwwroot/config.zip (rooted so entries keep the config/ prefix), fetched over HTTP on first run and extracted into the writable in-memory filesystem (MEMFS) via the pure FEBuilderGBA.Core/ZipAssetSource + AndroidConfigExtractorCore, then App.BaseDirectoryOverride points Core there. Config load is non-fatal (the shell renders with defaults if it fails). |
| Threads OFF | GitHub Pages sends no COOP/COEP headers → no SharedArrayBuffer → WasmEnableThreads=false (also selects Avalonia's single-threaded st Skia/HarfBuzz natives). The shell boot path has no background threads, so it renders fine single-threaded. |
| No trimming |
PublishTrimmed=false — the reflection-heavy Core would break under aggressive wasm trimming. |
| No compression |
CompressionEnabled=false — GitHub Pages does no Brotli/gzip content-negotiation, so plain .wasm is served. |
Not in FEBuilderGBA.sln (the required desktop build check has no wasm-tools). Build standalone:
dotnet workload install wasm-tools
dotnet publish FEBuilderGBA.Browser/FEBuilderGBA.Browser.csproj -c Release \
-p:EnableBrowserTarget=true -p:WasmEnableThreads=false -p:PublishTrimmed=false -p:CompressionEnabled=false
# serve FEBuilderGBA.Browser/bin/Release/net10.0-browser/publish/wwwroot with any static server-p:EnableBrowserTarget=true is required as a global property (NuGet restore's static graph ignores the ProjectReference AdditionalProperties, else NETSDK1005 — same as the android/iOS heads).
pages.yml installs wasm-tools, publishes the head, rewrites the <base href> to /FEBuilderGBA/ (the Pages project path), adds .nojekyll (so _framework/ isn't Jekyll-stripped), verifies the bundle, then upload-pages-artifact + deploy-pages. The build job runs on PRs (validating the wasm build); the deploy job runs only on master. Pages source is set to GitHub Actions.
- On-device parity maturing — threading-dependent caches + some file-flows aren't browser-ported (single-threaded on Pages). The milestone is builds + deploys + loads/renders the shell.
-
config/patch2/ FE-Repo not bundled — same as the mobile heads (large git-delivered payloads). - Large first-load — no trimming + the config tree (downloaded + unzipped before boot); a loading splash is shown.
-
docs/WEBASSEMBLY.md— authoritative, full detail - Native Android / Native iOS — the sibling heads (shared seams)
- Avalonia GUI — the shared cross-platform frontend the web head consumes
- Getting Started — platforms & downloads