Project Setup
This guide walks you through setting up a complete Web Engine Dev project from scratch using Vite and TypeScript.
Create a New Project
1. Scaffold with Vite
bash
pnpm create vite my-game -- --template vanilla-ts
cd my-game2. Install Engine Packages
Choose one of two approaches:
bash
pnpm add @web-engine-dev/enginebash
pnpm add @web-engine-dev/ecs @web-engine-dev/math @web-engine-dev/renderer @web-engine-dev/time3. Configure TypeScript
Replace the contents of tsconfig.json:
json
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noUncheckedIndexedAccess": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}4. Set Up the HTML Entry Point
Replace index.html:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Game</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 100%; height: 100%; overflow: hidden; }
canvas {
display: block;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<canvas id="game-canvas"></canvas>
<script type="module" src="/src/main.ts"></script>
</body>
</html>5. Create the Entry Point
Replace src/main.ts:
typescript
import { createEngine, Game3DPreset, RenderPlugin } from '@web-engine-dev/engine';
import { createDevice } from '@web-engine-dev/renderer';
async function main() {
// Get the canvas element
const canvas = document.getElementById('game-canvas') as HTMLCanvasElement;
// Create a GPU device (WebGPU runtime)
const { device, backend } = await createDevice({
canvas,
preferredBackend: 'auto',
powerPreference: 'high-performance',
});
console.log(`Rendering with ${backend}`);
// Create the engine with 3D game defaults
const engine = createEngine(Game3DPreset);
// Add rendering plugin (registers render systems and resources)
engine.addPlugin(RenderPlugin);
// Initialize and start
await engine.init();
await engine.start();
}
main().catch(console.error);6. Run the Dev Server
bash
pnpm devOpen the URL shown in the terminal (usually http://localhost:5173). You should see a blank canvas with the GPU backend initialized.
Project Structure
A recommended structure for a game project:
my-game/
├── public/ # Static assets (textures, models, audio)
│ ├── textures/
│ ├── models/
│ └── audio/
├── src/
│ ├── main.ts # Entry point
│ ├── components.ts # Game-specific ECS component definitions
│ ├── systems.ts # Game systems (movement, AI, etc.)
│ ├── resources.ts # Game resources (config, state)
│ └── scenes/ # Scene setup functions
│ └── main-scene.ts
├── index.html
├── tsconfig.json
├── vite.config.ts
└── package.jsonVite Configuration
For most projects, the default Vite config works fine. For advanced setups:
typescript
// vite.config.ts
import { defineConfig } from 'vite';
export default defineConfig({
build: {
target: 'es2022',
},
optimizeDeps: {
// Pre-bundle engine packages for faster dev startup
include: ['@web-engine-dev/engine'],
},
});Engine Presets
The engine provides presets optimized for different game types:
| Preset | Target FPS | Fixed Timestep | Best For |
|---|---|---|---|
MinimalPreset | Uncapped | No | Bare bones, custom setups |
Game2DPreset | 60 | 1/60s | 2D games with physics |
Game3DPreset | 60 | 1/60s | 3D games |
HighPerformancePreset | Uncapped | 1/120s | Fast-paced games |
TurnBasedPreset | 30 | No | Turn-based games |
HeadlessPreset | N/A | No | Server-side, testing |
Use presets as the base and override specific fields:
typescript
import { createEngine, Game3DPreset } from '@web-engine-dev/engine';
const engine = createEngine({
...Game3DPreset,
targetFps: 120,
maxDeltaTime: 0.1,
});Plugin System
Plugins configure the engine with systems, resources, and integrations:
typescript
import {
createEngine,
Game3DPreset,
RenderPlugin,
InputPlugin,
AudioPlugin,
Physics3DPlugin,
AnimationPlugin,
} from '@web-engine-dev/engine';
const engine = createEngine(Game3DPreset);
// Add plugins individually
engine.addPlugin(RenderPlugin);
engine.addPlugin(InputPlugin);
engine.addPlugin(AudioPlugin);
engine.addPlugin(Physics3DPlugin);
engine.addPlugin(AnimationPlugin);Or use plugin groups for common setups:
typescript
import { createEngine, Game3DPreset, Game3DPlugins } from '@web-engine-dev/engine';
const engine = createEngine(Game3DPreset);
// Game3DPlugins includes: Input, Audio, Physics3D, Render, Particle, Animation, Scripting
engine.addPlugin(Game3DPlugins);Available plugin groups:
Game2DPlugins-- Input, Audio, Physics2D, Sprite, Particle, Animation, ScriptingGame3DPlugins-- Input, Audio, Physics3D, Render, Particle, Animation, ScriptingFullPlugins-- All available plugins
Next Steps
- First Game -- Build a playable game using this project setup
- Quick Start -- Learn the ECS API fundamentals
- Rendering -- Understand the rendering pipeline