NEOLearn

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.

Updated October 17, 2026

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:

  1. Choose Build in the mode switcher.
  2. Pick the Web target and choose Package.
  3. 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:

Shell
cargo xtask package --target web     # writes dist/<game>-<version>-web/
cargo xtask serve                     # serves the newest package and prints the links

Packaging needs wasm-bindgen on your PATH, at the same version as in Cargo.lock:

Shell
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:

FileWhat it is
index.htmlThe loader page.
<game>.js, <game>_bg.wasm, <game>_bg.wasm.gzThe compiled game.
preload.jsonEvery file the page downloads before the game starts, with its path, address, size and download size.
assets/The game's content.
manifest.jsonThe 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.

  1. The page loads. index.html downloads the WebAssembly module and the game's preload files, showing a progress bar. It unpacks .gz files itself, so no server configuration is needed. It hands each file to the game, then shows Play.
  2. 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#

WhatDesktopWeb
Assets through the asset server (models, the animation library)assets/ on diskThe 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 diskThe 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:

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, playing or failed), loaded and total bytes, files, gpu (webgl2 or webgpu) and errors. 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 serve prints the links; the Studio's status line and editor_build_status show 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#

LimitWhat it means
One threadThe 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.
MemoryWebAssembly 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.
DownloadA 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.

Next steps#