Create an engine around a canvas
Goal
A page that boots @aosengine/core, renders a scene at 60 Hz on WebGPU (or the WebGL fallback), resizes with its canvas, and shows the F3 debug overlay in development.
Files you will edit
src/main.tsassets.json
Steps
Declare your content. Every asset the game can reference lives here, and game code refers to it by
idonly.json{ "version": 1, "baseUrl": "/assets/", "assets": [{ "id": "arena", "type": "gltf", "src": "arena.glb", "tags": ["world"] }] }Boot the engine in
src/main.ts.createEngineis async because the renderer has to acquire aGPUDevicebefore anything else can use it.tsimport { createEngine } from '@aosengine/core'; const canvas = document.querySelector('canvas'); if (!(canvas instanceof HTMLCanvasElement)) throw new Error('no <canvas> on the page'); const engine = await createEngine({ canvas, manifest: '/assets/assets.json', modules: [], fixedHz: 60, renderer: { backend: 'auto', antialias: true, pixelRatioCap: 2 }, debug: true, }); console.log(engine.ctx.caps.webgpu ? 'webgpu' : 'webgl fallback');Put something in the scene and load the world.
engine.graphmaps numeric entity ids onto three objects;engine.assetsresolves ids to bytes.tsimport type { GLTF } from 'three/addons/loaders/GLTFLoader.js'; import { DirectionalLight } from 'three/webgpu'; engine.scene.add(new DirectionalLight(0xffffff, 2)); engine.camera.position.set(0, 1.7, 4); const arena = (await engine.assets.load('arena')) as GLTF; engine.graph.spawn(1, arena.scene);Start the loop, and stop it again when the page goes away.
tsengine.start(); window.addEventListener('pagehide', () => { void engine.dispose(); });
Verify
sh
npm run devThe canvas fills its container and redraws as you resize the window. Press F3: an overlay appears in the top-left showing the backend name, a frame rate, p50/p95 frame times and the draw-call count. engine.running is true, and the console line printed in step 2 says which backend you got.
See also
- The engine loop
- Engine modules
- Assets and the manifest
packages/core/README.md— @aosengine/core