Web builds
How a NEO game is packaged for the browser, how a web build loads and starts, what it reports while it runs, and the limits of running in a browser.
On this page
A NEO game runs in the browser as WebAssembly, drawn with WebGL 2, which every current browser has. It is the same game as on the desktop: the same code, content and simulation. Games published from the Studio play this way on the platform, and you can package any project for the web yourself.
Package a game for the web#
From the desktop Studio:
- Choose Build in the mode switcher.
- Pick the Web target and choose Package.
- Choose Play in browser ("Package for Web, then play it here or on a phone on this network").
The status line shows the link on this computer and a link for phones and tablets on the same network. Packaging needs the desktop Studio; in the browser Studio the button explains that packaging builds the game with cargo.
From the command line, in the engine workspace:
cargo xtask package --target web # writes dist/<game>-<version>-web/
cargo xtask serve # serves the newest package and prints the linksPackaging needs wasm-bindgen on your PATH, at the same version as in Cargo.lock:
cargo install wasm-bindgen-cli --version <the version in Cargo.lock>Agents use editor_build_package {target: "web"}, then editor_build_play_web; the links come back in editor_build_status's web field.
What's in the package#
dist/<game>-<version>-web/ holds:
| File | What it is |
|---|---|
index.html | The loader page. |
<game>.js, <game>_bg.wasm, <game>_bg.wasm.gz | The compiled game. |
preload.json | Every file the page downloads before the game starts, with its path, address, size and download size. |
assets/ | The game's content. |
manifest.json | The package's manifest. |
Any static web host can serve it as is.
How a web build starts#
A browser has no file system, and a game's content has to download first, so a web build starts in two steps.
- The page loads.
index.htmldownloads the WebAssembly module and the game's preload files, showing a progress bar. It unpacks.gzfiles itself, so no server configuration is needed. It hands each file to the game, then shows Play. - The player clicks Play. The game starts. Starting from a click lets the browser start audio and lock the pointer.
With the neo_autostart=1 launch parameter (#neo_autostart=1 in the address), the game starts as soon as its content is in, with no Play button. The platform's Play overlay uses this.
What the game loads, and from where#
| What | Desktop | Web |
|---|---|---|
| Assets through the asset server (models, the animation library) | assets/ on disk | The preloaded files first (freed once handed over), then the page's assets/ over HTTP |
| Files that loaders open themselves (physics assets, interactions, the audio pack) | Read from disk | The preloaded files |
The web-preload list#
A game lists the files and folders its web build downloads before starting in web-preload, under [package.metadata.neo.game] in its crate's Cargo.toml:
[package.metadata.neo.game]
web-preload = ["my_game/characters", "my_game/audio"]Engine code never reads files straight from the disk: it reads through the platform layer, which works the same on the desktop and the web. A file that's missing in the browser fails with an error that names the web-preload list, so add any file your game opens itself to it.
Observability#
window.neo. The page keeps its state here:phase(loading,compiling,ready,playingorfailed),loadedandtotalbytes,files,gpu(webgl2orwebgpu) anderrors. Test scripts wait on it.- Errors. A load error or a crash before Play shows on the page. After Play, errors go to the browser console, with the game's log.
- Links.
cargo xtask serveprints the links; the Studio's status line andeditor_build_statusshow them too. - On the platform. When the platform's Play overlay frames a web build, the loader reports its progress to the overlay, which shows "Downloading · n of m MB", then "Preparing the game…" and "Starting…", and fades to the game once it's playing.
Limits#
| Limit | What it means |
|---|---|
| One thread | The browser build runs on one thread. Characters step one after another: the same result as in parallel, only slower. Audio is decoded while the game starts. |
| Memory | WebAssembly has at most 4 GB. Large files such as the template's animation library are preloaded once and freed when the asset server takes them. |
| Download | A game downloads its preloaded content the first time it starts. The browser caches it, but the page still checks each file with the server on every visit. |