Skip to content

Install ​

What you need ​

RequirementVersionWhy
Node.js>= 24Pinned in .nvmrc; engine-strict=true will refuse older versions
npm>= 11Workspaces and overrides
A modern browserWebGPU enabledThe renderer. WebGL is a fallback for splat worlds only
Gitany recentcreate-aosengine runs git init for you

Git LFS is not required to run a generated game, and not required to run this repository's tests. It is only needed if you add real binary content of your own.

Nothing else needs installing by hand. jco, componentize-qjs and its native binding arrive with the game's own npm install, and aosengine doctor tells you if one of them did not.

Start a game ​

create-aosengine is not on npm yet, so run it from a checkout of the engine; see Run from a checkout below.

sh
npm create aosengine my-game -- --template fps
cd my-game
npm run dev

That is a playable game: walk, shoot, kill three capsules, win. Open http://localhost:5173, then edit src/game.ts and save.

--template third-person gives you the other scaffold, and --third-person is a shorthand for it.

Options ​

FlagDoes
--template <name>fps (default) or third-person
--third-personshorthand for --template third-person
--title "<text>"human title for the page and the README; defaults to the directory
--no-installskip npm install
--no-gitskip git init
--aamadd the AvatarOS Asset Manager keys to .env.example
--forcewrite into a directory that already has files in it

With no arguments at all, and an interactive terminal, it asks for the directory and the template. In CI — or when an agent runs it — it takes the defaults and never blocks on a question nobody can answer.

The -- before the flags is npm's, not ours: without it npm eats them.

What you get ​

my-game/
├─ AGENTS.md            the rules, scoped to this game
├─ .env.example         copy to .env.local; VITE_-prefixed keys only
├─ index.html
├─ package.json         dev / build / preview / test
├─ public/              served at the site root
├─ src/
│  ├─ game.ts           the one defineGame call. Start here
│  ├─ assets.json       asset ids to files. The ids are the contract
│  ├─ prefabs.ts        entity templates
│  ├─ hud.ts
│  └─ systems/          one file per behaviour
├─ tests/
└─ vite.config.ts

.aosengine/ and dist/ appear when you build, and both are gitignored.

The commands ​

The template's npm scripts wrap @aosengine/cli:

CommandDoes
npm run devVite in direct mode; edit src/game.ts and save
npm run dev -- --wasmbuild the component first and serve it, to check parity
npm run buildcomponentize the guest, then vite build
npm run build -- --reportthe same, plus size and timing numbers, with budgets
npm testthe smoke spec, headless
npx aosengine doctorcheck the toolchain; exit code is the number of failures
npx aosengine docswhere the llms*.txt bundles are on this machine

Direct mode is the default because a jco componentize run is about thirty seconds and that is not a dev loop. The two modes share the same guest runtime on purpose, and a parity test hashes both — if they diverge, that is an engine bug, not a configuration difference.

Verify ​

sh
node --version          # v24.x
npx aosengine doctor    # 0 failures
npm run dev             # http://localhost:5173

doctor checks node, npm, a single three instance, src/assets.json and the files it references, the aos:engine WIT package, jco, componentize-qjs and its native binding for your platform. Every failure prints a copy-pasteable fix. It cannot probe WebGPU from node, so it always prints the Chrome flags and leaves that one to you.

If something is red, Debug with doctor walks through the failures one at a time.

Run from a checkout ​

Until create-aosengine is on npm, the scaffolder runs from a clone of the engine, and the game it makes links back to that clone:

sh
git clone <repo> aosengine
cd aosengine
npm install
node packages/create-aosengine/bin/create-aosengine.mjs ../my-game --template fps

npm install is the only build step: every package declares a development export condition, so the game resolves the engine straight from packages/*/src with file: dependencies, and an engine change shows up in the game without a publish.

The two templates also run in place, with no scaffolding at all:

sh
npm run dev -w templates/fps            # http://localhost:5179
npm run dev -w templates/third-person   # http://localhost:5181

Next ​

Test a standalone consumer before publishing ​

Use Node 24 or newer. Build the engine and create ordinary npm tarballs:

sh
npm install
npm run build
node tools/pack-consumer.mjs ../aos-engine-packages

Run the packed scaffolder outside the workspace (replace the version when it changes):

sh
npm exec --package ../aos-engine-packages/aosengine-create-aosengine-0.0.0.tgz -- create-aosengine ../my-adventure --template third-person --packages-dir ../aos-engine-packages

The generated project uses exact file dependencies and overrides for transitive engine packages. It selects built package exports, including the SDK's packaged WIT and component entry, and carries its own lockfile and test runner. Keep the tarballs at the recorded relative paths or move them into the game's own vendor directory before installation. No workspace links or aliases to engine sources are needed. Add optional voice/conversation packages explicitly; scaffolding does not activate them.