@downdraft/cli 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +11 -0
  2. package/package.json +36 -3
  3. package/scripts/package-mobile.mjs +779 -0
  4. package/scripts/package-native.mjs +616 -0
  5. package/src/args.ts +333 -0
  6. package/src/assets.ts +523 -0
  7. package/src/blob-store-s3.ts +145 -0
  8. package/src/build-games.ts +45 -0
  9. package/src/build.ts +40 -0
  10. package/src/bun-env.d.ts +6 -0
  11. package/src/debug.ts +56 -0
  12. package/src/dev.ts +231 -0
  13. package/src/dist.ts +36 -0
  14. package/src/export.ts +38 -0
  15. package/src/index.ts +131 -0
  16. package/src/list-games.ts +37 -0
  17. package/src/mcp.ts +320 -0
  18. package/src/new.ts +63 -0
  19. package/src/paths.ts +101 -0
  20. package/src/plugin-command.ts +214 -0
  21. package/src/process-utils.ts +179 -0
  22. package/src/release.ts +374 -0
  23. package/src/scaffold-plugin.ts +280 -0
  24. package/src/scaffold.ts +207 -0
  25. package/src/test.ts +187 -0
  26. package/src/usage.ts +255 -0
  27. package/templates/_shared/ai-companion/devin-config.eta +11 -0
  28. package/templates/_shared/ai-companion/engine-prompt.eta +155 -0
  29. package/templates/_shared/ai-companion/logging-rule.eta +3 -0
  30. package/templates/_shared/ai-companion/loops-rule.eta +3 -0
  31. package/templates/_shared/partials/config-json-fields.eta +3 -0
  32. package/templates/_shared/partials/dev-deps.eta +8 -0
  33. package/templates/_shared/partials/package-json-fields.eta +12 -0
  34. package/templates/_shared/partials/tsconfig.eta +16 -0
  35. package/templates/_shared/partials/vscode-extensions.eta +11 -0
  36. package/templates/_shared/partials/vscode-settings.eta +29 -0
  37. package/templates/_shared/partials/vscode-tasks.eta +93 -0
  38. package/templates/full/.gitignore.eta +5 -0
  39. package/templates/full/.vscode/extensions.json.eta +1 -0
  40. package/templates/full/.vscode/settings.json.eta +1 -0
  41. package/templates/full/.vscode/tasks.json.eta +1 -0
  42. package/templates/full/README.md.eta +45 -0
  43. package/templates/full/assets/shaders/.eta +0 -0
  44. package/templates/full/downdraft.config.json.eta +10 -0
  45. package/templates/full/package.json.eta +9 -0
  46. package/templates/full/src/entities/.eta +0 -0
  47. package/templates/full/src/game-module.ts.eta +30 -0
  48. package/templates/full/src/native-entry.ts.eta +14 -0
  49. package/templates/full/src/sim-host.ts.eta +19 -0
  50. package/templates/full/src/sim-worker.ts.eta +99 -0
  51. package/templates/full/src/systems/.eta +0 -0
  52. package/templates/full/tsconfig.json.eta +1 -0
  53. package/templates/gamemodule/README.md.eta +32 -0
  54. package/templates/gamemodule/downdraft.config.json.eta +3 -0
  55. package/templates/gamemodule/package.json.eta +9 -0
  56. package/templates/gamemodule/src/game-module.ts.eta +63 -0
  57. package/templates/gamemodule/src/native-entry.ts.eta +14 -0
  58. package/templates/gamemodule/src/sim-host.ts.eta +25 -0
  59. package/templates/gamemodule/src/sim-worker.ts.eta +24 -0
  60. package/templates/gamemodule/tsconfig.json.eta +1 -0
  61. package/templates/minimal/.gitignore.eta +5 -0
  62. package/templates/minimal/.vscode/extensions.json.eta +1 -0
  63. package/templates/minimal/.vscode/settings.json.eta +1 -0
  64. package/templates/minimal/.vscode/tasks.json.eta +1 -0
  65. package/templates/minimal/README.md.eta +32 -0
  66. package/templates/minimal/downdraft.config.json.eta +3 -0
  67. package/templates/minimal/package.json.eta +9 -0
  68. package/templates/minimal/src/game-module.ts.eta +44 -0
  69. package/templates/minimal/src/native-entry.ts.eta +14 -0
  70. package/templates/minimal/tsconfig.json.eta +1 -0
  71. package/templates/physics/.gitignore.eta +5 -0
  72. package/templates/physics/.vscode/extensions.json.eta +1 -0
  73. package/templates/physics/.vscode/settings.json.eta +1 -0
  74. package/templates/physics/.vscode/tasks.json.eta +1 -0
  75. package/templates/physics/README.md.eta +36 -0
  76. package/templates/physics/downdraft.config.json.eta +6 -0
  77. package/templates/physics/package.json.eta +9 -0
  78. package/templates/physics/src/game-module.ts.eta +29 -0
  79. package/templates/physics/src/native-entry.ts.eta +14 -0
  80. package/templates/physics/src/sim-host.ts.eta +19 -0
  81. package/templates/physics/src/sim-worker.ts.eta +155 -0
  82. package/templates/physics/tsconfig.json.eta +1 -0
@@ -0,0 +1,155 @@
1
+ # DownDraft Engine — API Reference for AI Companions
2
+
3
+ ## Architecture
4
+
5
+ DownDraft is a TypeScript-first game engine built on winit + wgpu (a single native process, hosted under Bun, Node, or Deno — Bun is the default) + WebGPU, with an MCP server enabling AI agents to design, build, debug, and manage games via natural language.
6
+
7
+ **Execution contexts:**
8
+ 1. **Native host (main thread)** — Game module, renderer, render loop, engine orchestrator, MCP server, asset manager
9
+ 2. **Sim worker** — ECS world, game systems, physics, AI, modules (SharedArrayBuffer channels for frame sync)
10
+ 3. **DB worker** — Persistence layer with schema versioning
11
+
12
+ ## ECS (Entity Component System)
13
+
14
+ - **Entity**: `{ index: u32, generation: u32 }` — generational indices prevent stale-handle corruption
15
+ - **Component**: Plain data class implementing `Component` interface, registered with `ComponentId`
16
+ - **Archetype**: Set of component types, SoA column storage for cache-friendly iteration
17
+ - **Query**: Declares read/write access to component types, returns matching archetypes
18
+ - **System**: Function `(query, resources, commands) => void`
19
+ - **Schedule**: Single-threaded by default, dependency-ordered. Multi-threading via module/SAB.
20
+ - **Events**: Double-buffered channels (written this tick, readable next tick)
21
+ - **Commands**: Deferred operations (spawn/despawn, add/remove component) applied at stage boundaries
22
+
23
+ ### Hierarchy
24
+ - Parent/child tree stored in side table (not archetype columns) — avoids archetype moves on reparenting
25
+ - Dirty-flag propagation: parent Transform change marks children dirty (O(depth))
26
+ - Lazy world matrix: computed on read when dirty
27
+
28
+ ### Change Detection
29
+ - Per-component `lastChanged` tick counter — O(1) check for consumers
30
+ - Cross-thread: `Atomics` on SAB headers for frame sync
31
+
32
+ ## Core API
33
+
34
+ ```typescript
35
+ import { World, Camera, MeshBuilder, Component, system, createLogger } from "@downdraft/engine";
36
+
37
+ // Define components
38
+ const Health = Component.register<{ current: number; max: number }>("Health", { current: 100, max: 100 });
39
+
40
+ // Define a system
41
+ const damageSystem = system(
42
+ (w: World, dt: number) => {
43
+ const view = w.view([Health]);
44
+ for (const ent of view) {
45
+ const health = w.getComponent(ent, Health);
46
+ if (health && health.data.current <= 0) {
47
+ w.despawn(ent);
48
+ }
49
+ }
50
+ }
51
+ );
52
+
53
+ // Setup
54
+ const world = new World();
55
+ const camera = new Camera();
56
+ camera.setAspect(16, 9);
57
+ world.setResource("camera", camera);
58
+
59
+ // Spawn entities
60
+ const entity = world.spawn();
61
+ world.addComponent(entity, Health.create({ current: 50, max: 100 }));
62
+
63
+ // Procedural meshes
64
+ const cube = MeshBuilder.cube(1);
65
+ const sphere = MeshBuilder.sphere(0.5, 16, 16);
66
+ ```
67
+
68
+ ## Module System
69
+
70
+ Modules are loadable packages that register systems, components, resources, and assets.
71
+
72
+ ```typescript
73
+ import { Module } from "@downdraft/engine";
74
+
75
+ const myModule: Module = {
76
+ name: "my-module",
77
+ register(ctx: ModuleContext) {
78
+ // Register components, systems, resources
79
+ },
80
+ };
81
+
82
+ world.registerModule(myModule);
83
+ ```
84
+
85
+ ### Engine Libraries (`@downdraft/engine/libraries/*`)
86
+ - `@downdraft/engine/libraries/water` — Gerstner waves, refraction, reflection
87
+ - `@downdraft/engine/libraries/physics-rapier` — Rapier physics backend
88
+ - `@downdraft/engine/libraries/physics-native` — Pure-TS physics backend
89
+ - `@downdraft/engine/libraries/marching-cubes` — Volumetric deformable terrain
90
+ - `@downdraft/engine/libraries/surface-nets` — Surface nets mesh extraction
91
+ - `@downdraft/engine/libraries/models` — GLTF/GLB/PLY/3DS model loading
92
+ - `@downdraft/engine/libraries/audio-kira` — Kira audio backend
93
+ - `@downdraft/engine/libraries/entities` — Generic model renderer
94
+ - `@downdraft/engine/libraries/lighting` — Lighting system
95
+ - `@downdraft/engine/libraries/weather` — Weather simulation
96
+ - `@downdraft/engine/libraries/weatherfx` — Cloud particle effects
97
+ - `@downdraft/engine/libraries/navmesh` — Navigation meshes
98
+ - `@downdraft/engine/libraries/persistence` — Save system (OPFS, File, IndexedDB)
99
+ - `@downdraft/engine/libraries/networking` — Multiplayer networking
100
+ - `@downdraft/engine/libraries/gaussian-splats` — Gaussian splat rendering
101
+ - `@downdraft/engine/libraries/sand` — Falling-sand simulation
102
+ - `@downdraft/engine/libraries/stickman` — Stickman skeleton rendering
103
+
104
+ ### Engine Modules (`@downdraft/engine/modules/*`)
105
+ - `@downdraft/engine/modules/devtools` — DevTools panel, scene inspector, GPU debugging
106
+ - `@downdraft/engine/modules/camera-controls` — Camera input handling
107
+ - `@downdraft/engine/modules/terrain` — Terrain composition (marching-cubes + LOD)
108
+ - `@downdraft/engine/modules/movement-3d` — 3D player movement
109
+ - `@downdraft/engine/modules/movement-2d` — 2D grid-based movement
110
+ - `@downdraft/engine/modules/sailing` — Sailing mechanics (wind, buoyancy, steering)
111
+ - `@downdraft/engine/modules/mcp` — MCP automation server
112
+ - `@downdraft/engine/modules/xr` — WebXR support
113
+
114
+ ### Game Modules (to-the-ocean example: `@to-the-ocean/module-*`)
115
+ - `@to-the-ocean/module-crafting` — Crafting recipes and system
116
+ - `@to-the-ocean/module-inventory` — Inventory system
117
+ - `@to-the-ocean/module-wildlife` — Wildlife AI (fish, sharks, eels, etc.)
118
+ - `@to-the-ocean/module-buoyancy` — Water buoyancy physics
119
+ - `@to-the-ocean/module-collision` — Entity collision detection
120
+
121
+ ### Game Libraries (to-the-ocean example: `@to-the-ocean/library-*`)
122
+ - `@to-the-ocean/library-items` — Item definitions and management
123
+ - `@to-the-ocean/library-fishing` — Fishing mechanics
124
+ - `@to-the-ocean/library-economy` — Market/trading system
125
+ - `@to-the-ocean/library-survival` — Survival stats (hunger, thirst, oxygen)
126
+ - `@to-the-ocean/library-boats` — Boat building and piloting
127
+
128
+ ## Builder Modes
129
+
130
+ | Mode | Use case |
131
+ |---|---|
132
+ | **dev** | Full DevTools, hot-reload, telemetry. Fastest iteration. |
133
+ | **debug** | Local verification on the production native runtime. |
134
+ | **prod** | Optimized production build. No devtools/debug overhead. |
135
+
136
+ ## CLI Commands
137
+
138
+ ```
139
+ draft new [path] [options] Scaffold a new game project
140
+ draft dev [options] Start dev server with HMR
141
+ draft debug [options] Run engine in debug mode
142
+ draft release [options] Unified build + package + sign pipeline
143
+ (--stage=build|package|release, --target=win|linux|mac|all)
144
+ draft assets <cmd> Manage remote asset packs
145
+ ```
146
+
147
+ ## MCP Tools (for AI agents)
148
+
149
+ The MCP server exposes tools for scene management, entity operations, component manipulation, material/shader editing, mesh import, animation, lighting, camera, physics, audio, scripting, asset management, debugging, checkpoints, and build/export.
150
+
151
+ ## Conventions
152
+
153
+ - **Logging**: No manual `[module]` prefixes — automatic source attribution
154
+ - **Loops**: Prefer indexed `for` loops over `for..of`
155
+ - **Package manager**: Bun (workspace protocol for internal deps)
@@ -0,0 +1,3 @@
1
+ # Logging Convention
2
+
3
+ Logs are automatically sourced to the line from which they are printed. Do NOT manually add `[module]` prefixes to log messages — the logging system handles source attribution automatically.
@@ -0,0 +1,3 @@
1
+ # Loop Convention
2
+
3
+ Always prefer indexed `for` loops (`for (let i = 0; i < arr.length; i++)`) over `for..of` loops.
@@ -0,0 +1,3 @@
1
+ "name": "<%= it.name %>",
2
+ "version": "<%= it.version %>",
3
+ "engine": "downdraft"
@@ -0,0 +1,8 @@
1
+ "devDependencies": {
2
+ "@downdraft/cli": "^0.1.0",
3
+ "@types/node": "^22.10.0",
4
+ "@webgpu/types": "^0.1.71",
5
+ "oxlint": "^1.4.0",
6
+ "typescript": "^5.9.3",
7
+ "vite": "^6.0.0"
8
+ }
@@ -0,0 +1,12 @@
1
+ "version": "<%= it.version %>",<% if (it.description) { %>
2
+ "description": "<%= it.description %>",<% } %><% if (it.author) { %>
3
+ "author": { "name": "<%= it.author %>" },<% } %>
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "draft dev",
7
+ "build": "draft release --stage=build",
8
+ "release": "draft release",
9
+ "typecheck": "tsc --noEmit",
10
+ "lint": "oxlint",
11
+ "test": "npm test"
12
+ },
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ESNext", "DOM", "DOM.Iterable"],
7
+ "types": ["@webgpu/types", "node", "vite/client"],
8
+ "strict": true,
9
+ "noEmit": true,
10
+ "skipLibCheck": true,
11
+ "esModuleInterop": true,
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true
14
+ },
15
+ "include": ["src"]
16
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "recommendations": [
3
+ "antaalt.shader-validator",
4
+ "PKief.material-icon-theme",
5
+ "actboy168.tasks",
6
+ "Gruntfuggly.todo-tree",
7
+ "augustocdias.tasks-shell-input",
8
+ "oxc.oxc-vscode",
9
+ "wgsl-analyzer.wgsl-analyzer"
10
+ ]
11
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "explorer.fileNesting.enabled": true,
3
+ "explorer.fileNesting.expand": false,
4
+ "explorer.fileNesting.patterns": {
5
+ "*.ts": "${capture}.js, ${capture}.spec.ts, ${capture}.*.spec.ts, ${capture}.test.ts",
6
+ "*.tsx": "${capture}.spec.ts, ${capture}.*.spec.ts, ${capture}.test.ts",
7
+ "*.js": "${capture}.js.map, ${capture}.min.js, ${capture}.d.ts, ${capture}.wasm, ${capture}.wasm.map",
8
+ "tsconfig.json": "tsconfig.*.json",
9
+ "package.json": "package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lock"
10
+ },
11
+ "editor.codeActionsOnSave": {
12
+ "source.organizeImports": "explicit"
13
+ },
14
+ "files.associations": {
15
+ "*.wgsl": "wgsl"
16
+ },
17
+ "files.watcherExclude": {
18
+ "**/node_modules/**": true,
19
+ "**/dist/**": true,
20
+ "**/export/**": true,
21
+ "**/tmp/**": true
22
+ },
23
+ "search.exclude": {
24
+ "**/node_modules/**": true,
25
+ "**/dist/**": true,
26
+ "**/export/**": true,
27
+ "**/tmp/**": true
28
+ }
29
+ }
@@ -0,0 +1,93 @@
1
+ {
2
+ "version": "2.0.0",
3
+ "tasks": [
4
+ {
5
+ "label": "Dev",
6
+ "detail": "Start the game in dev mode with hot reload",
7
+ "type": "shell",
8
+ "command": "draft dev",
9
+ "options": {
10
+ "cwd": "${workspaceFolder}"
11
+ },
12
+ "isBackground": true,
13
+ "problemMatcher": [],
14
+ "group": {
15
+ "kind": "build",
16
+ "isDefault": true
17
+ }
18
+ },
19
+ {
20
+ "label": "Release",
21
+ "detail": "Build + package for a desktop target",
22
+ "type": "shell",
23
+ "command": "draft release --target=${input:releaseTarget} --mode=${input:buildMode}",
24
+ "options": {
25
+ "cwd": "${workspaceFolder}"
26
+ },
27
+ "presentation": {
28
+ "echo": true,
29
+ "reveal": "always",
30
+ "panel": "dedicated",
31
+ "clear": true,
32
+ "showReuseMessage": false
33
+ },
34
+ "problemMatcher": []
35
+ },
36
+ {
37
+ "label": "Build Only",
38
+ "detail": "Bundle the game with Vite (no packaging)",
39
+ "type": "shell",
40
+ "command": "draft release --stage=build --mode=${input:buildMode}",
41
+ "options": {
42
+ "cwd": "${workspaceFolder}"
43
+ },
44
+ "problemMatcher": []
45
+ },
46
+ {
47
+ "label": "Typecheck",
48
+ "detail": "Run tsc --noEmit",
49
+ "type": "shell",
50
+ "command": "npm run typecheck",
51
+ "options": {
52
+ "cwd": "${workspaceFolder}"
53
+ },
54
+ "problemMatcher": ["$tsc"]
55
+ },
56
+ {
57
+ "label": "Lint",
58
+ "detail": "Run oxlint",
59
+ "type": "shell",
60
+ "command": "npm run lint",
61
+ "options": {
62
+ "cwd": "${workspaceFolder}"
63
+ },
64
+ "problemMatcher": []
65
+ },
66
+ {
67
+ "label": "Test",
68
+ "detail": "Run tests",
69
+ "type": "shell",
70
+ "command": "npm test",
71
+ "options": {
72
+ "cwd": "${workspaceFolder}"
73
+ },
74
+ "problemMatcher": []
75
+ }
76
+ ],
77
+ "inputs": [
78
+ {
79
+ "id": "releaseTarget",
80
+ "type": "pickString",
81
+ "options": ["all", "win", "linux", "mac"],
82
+ "default": "all",
83
+ "description": "Target platform(s)"
84
+ },
85
+ {
86
+ "id": "buildMode",
87
+ "type": "pickString",
88
+ "options": ["prod", "dev", "debug"],
89
+ "default": "prod",
90
+ "description": "Build mode"
91
+ }
92
+ ]
93
+ }
@@ -0,0 +1,5 @@
1
+ node_modules/
2
+ dist/
3
+ export/
4
+ *.log
5
+ .DS_Store
@@ -0,0 +1 @@
1
+ <%~ include("_shared/partials/vscode-extensions", it) %>
@@ -0,0 +1 @@
1
+ <%~ include("_shared/partials/vscode-settings", it) %>
@@ -0,0 +1 @@
1
+ <%~ include("_shared/partials/vscode-tasks", it) %>
@@ -0,0 +1,45 @@
1
+ # <%= it.name %>
2
+
3
+ <% if (it.description) { %><%= it.description %><% } else { %>A full-featured game built with the DownDraft Engine.<% } %>
4
+
5
+ ## Getting Started
6
+
7
+ ```bash
8
+ # Install dependencies
9
+ bun install
10
+
11
+ # Start dev server (includes DevTools panel)
12
+ npm run dev
13
+
14
+ # Build for production
15
+ npm run build
16
+
17
+ # Export for distribution
18
+ npm run export
19
+ ```
20
+
21
+ ## Project Structure
22
+
23
+ ```
24
+ src/ Game source code
25
+ native-entry.ts Native runtime entry (draft dev)
26
+ systems/ Game systems (ECS)
27
+ entities/ Entity definitions and prefabs
28
+ assets/ Game assets
29
+ shaders/ Custom WGSL shaders
30
+ models/ 3D models (GLTF, PLY, 3DS)
31
+ textures/ Textures (PNG, WebP, KTX2, DDS, HDR)
32
+ downdraft.config.json Engine configuration
33
+ ```
34
+
35
+ ## Plugins
36
+
37
+ - **@downdraft/engine/libraries/water** — Gerstner wave simulation, refraction, reflection
38
+ - **@downdraft/engine/libraries/physics-rapier** — Rapier physics backend
39
+ - **@downdraft/engine/libraries/marching-cubes** — Volumetric deformable terrain
40
+ - **@downdraft/engine/libraries/models** — Model loading (GLTF/GLB, PLY, 3DS)
41
+ - **@downdraft/engine/modules/devtools** — DevTools panel with scene inspector, GPU debugging
42
+
43
+ ## Engine
44
+
45
+ Built with [DownDraft Engine](https://github.com/downdraft-engine) — a TypeScript-first game engine on WebGPU — native runtime (Bun + SDL + wgpu).
File without changes
@@ -0,0 +1,10 @@
1
+ {
2
+ <%~ include("_shared/partials/config-json-fields", it) %>,
3
+ "plugins": [
4
+ "physics-rapier",
5
+ "water",
6
+ "marching-cubes",
7
+ "models",
8
+ "devtools"
9
+ ]
10
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "<%= it.name %>",
3
+ <%~ include("_shared/partials/package-json-fields", it) %>
4
+ "dependencies": {
5
+ "@downdraft/engine": "^0.1.0",
6
+ "@downdraft/platform-native": "^0.1.0"
7
+ },
8
+ <%~ include("_shared/partials/dev-deps", it) %>
9
+ }
File without changes
@@ -0,0 +1,30 @@
1
+ import { GameRenderer } from "@downdraft/engine";
2
+ import type { GameModule } from "@downdraft/engine/app/renderer";
3
+ import { SimHost } from "./sim-host";
4
+
5
+ // ============================================================================
6
+ // Full template — ECS sim worker + GameRenderer + engine libraries
7
+ //
8
+ // The sim runs in sim-worker.ts (a Web Worker): an ECS World with a rotation
9
+ // system. The SAME module drives both entry points:
10
+ // src/native-entry.ts — Bun + SDL + wgpu-native (draft dev, the default)
11
+ // Engine libraries can be declared via GameModule.libraries[] for automatic
12
+ // SAB allocation + DI wiring.
13
+ // ============================================================================
14
+
15
+ export const gameModule: GameModule = {
16
+ // ── Renderer + Sim ──
17
+ renderer: (canvas) => new GameRenderer(canvas),
18
+ sim: () => new SimHost(),
19
+ simConfig: { seed: 12345 },
20
+
21
+ // ── Post-init wiring ──
22
+ onReady: (ctx) => {
23
+ console.log("[game] ready", { simSAB: ctx.simSAB, inputSAB: ctx.inputSAB });
24
+ },
25
+
26
+ // ── Cleanup ──
27
+ onDispose: () => {
28
+ console.log("[game] disposed");
29
+ },
30
+ };
@@ -0,0 +1,14 @@
1
+ import { runNativeGameModule } from "@downdraft/platform-native";
2
+ import { gameModule } from "./game-module";
3
+
4
+ // Native entry — `draft dev`/`draft release` runtime (winit + wgpu under Bun, Node, or Deno).
5
+ // Saves, MCP, display info, and screenshots work through the in-process
6
+ // HostAPI bridge.
7
+
8
+ await runNativeGameModule(gameModule, {
9
+ title: "<%= it.name %> — Native",
10
+ appId: "downdraft-<%= it.name %>",
11
+ }).catch((e) => {
12
+ console.error("[native-entry] Fatal:", e);
13
+ process.exit(1);
14
+ });
@@ -0,0 +1,19 @@
1
+ import { SimWorkerHost } from "@downdraft/engine";
2
+
3
+ // Sim worker host — spawns sim-worker.ts on the main (renderer) thread and
4
+ // exposes the sim SAB + event stream to startGame().
5
+ export class SimHost extends SimWorkerHost {
6
+ constructor() {
7
+ // Replace with your game's sim-buffer allocation (see the SAB APIs in
8
+ // @downdraft/engine, e.g. defineRecordBuffer/allocateSimBuffer).
9
+ super(new SharedArrayBuffer(4096));
10
+ }
11
+
12
+ protected createWorker(): Worker {
13
+ return new Worker(new URL("./sim-worker.ts", import.meta.url), { type: "module" });
14
+ }
15
+
16
+ protected async onInit(): Promise<void> {
17
+ await this.getProxy()!.proxy.init(this.getSimBuffer());
18
+ }
19
+ }
@@ -0,0 +1,99 @@
1
+ import {
2
+ c,
3
+ Component,
4
+ createLogger,
5
+ createSimWorker,
6
+ Query,
7
+ q,
8
+ spawn,
9
+ Stage,
10
+ systemWithParams,
11
+ World,
12
+ } from "@downdraft/engine";
13
+
14
+ const log = createLogger();
15
+
16
+ // Full template sim worker — an ECS World with a rotation system.
17
+ // createSimWorker owns the tick loop, worker protocol, and stats;
18
+ // this file provides onInit + onTick.
19
+
20
+ // --- Components ---
21
+
22
+ type TransformData = {
23
+ position: [number, number, number];
24
+ rotation: [number, number, number];
25
+ scale: number;
26
+ };
27
+
28
+ const Transform = Component.register<TransformData>("Transform", {
29
+ position: [0, 0, 0],
30
+ rotation: [0, 0, 0],
31
+ scale: 1,
32
+ });
33
+
34
+ type RenderableData = {
35
+ mesh: string;
36
+ color: [number, number, number];
37
+ };
38
+
39
+ const Renderable = Component.register<RenderableData>("Renderable", {
40
+ mesh: "cube",
41
+ color: [1, 1, 1],
42
+ });
43
+
44
+ // --- Queries ---
45
+
46
+ const rotateQuery = new Query([Transform.id, Renderable.id]);
47
+
48
+ let world: World;
49
+
50
+ createSimWorker({
51
+ fixedDt: 1 / 60,
52
+
53
+ onInit() {
54
+ world = new World();
55
+
56
+ // Spawn ground entity
57
+ spawn(world,
58
+ c(Transform, { position: [0, -0.5, 0], scale: 10 }),
59
+ c(Renderable, { mesh: "cube", color: [0.3, 0.5, 0.3] }),
60
+ );
61
+
62
+ // Spawn rotating entities
63
+ for (let i = 0; i < 5; i++) {
64
+ spawn(world,
65
+ c(Transform, { position: [(i - 2) * 2, 0.5, 0] }),
66
+ c(Renderable, {
67
+ mesh: i % 2 === 0 ? "cube" : "sphere",
68
+ color: [Math.random(), Math.random(), Math.random()],
69
+ }),
70
+ );
71
+ }
72
+
73
+ // Register system using systemWithParams for typed dependency injection
74
+ const rotateSystem = systemWithParams(
75
+ "rotate-entities",
76
+ Stage.Update,
77
+ [q(Transform, Renderable)],
78
+ (ctx, entities) => {
79
+ entities.iterate(ctx.tick, (_entity, comps) => {
80
+ const transform = comps[0] as TransformData;
81
+ const [rx, ry, rz] = transform.rotation;
82
+ transform.rotation = [rx, ry + ctx.dt * 0.5, rz];
83
+ });
84
+ },
85
+ );
86
+
87
+ world.schedule.addSystem(rotateSystem);
88
+
89
+ log.info("sim", "full demo initialized — 5 entities on a ground plane");
90
+ },
91
+
92
+ onTick(dt) {
93
+ world.step(dt);
94
+ },
95
+
96
+ onShutdown() {
97
+ log.info("sim", "sim worker shutdown");
98
+ },
99
+ });
File without changes
@@ -0,0 +1 @@
1
+ <%~ include("_shared/partials/tsconfig", it) %>
@@ -0,0 +1,32 @@
1
+ # <%= it.name %>
2
+
3
+ <% if (it.description) { %><%= it.description %><% } else { %>A game built with the DownDraft Engine.<% } %>
4
+
5
+ ## Getting Started
6
+
7
+ ```bash
8
+ # Install dependencies
9
+ bun install
10
+
11
+ # Start dev server
12
+ npm run dev
13
+
14
+ # Build for production
15
+ npm run build
16
+
17
+ # Export for distribution
18
+ npm run export
19
+ ```
20
+
21
+ ## Project Structure
22
+
23
+ ```
24
+ src/ Game source code
25
+ native-entry.ts Native runtime entry (draft dev)
26
+ assets/ Game assets (models, textures, shaders)
27
+ downdraft.config.json Engine configuration
28
+ ```
29
+
30
+ ## Engine
31
+
32
+ Built with [DownDraft Engine](https://github.com/downdraft-engine) — a TypeScript-first game engine on WebGPU — native runtime (Bun + SDL + wgpu).
@@ -0,0 +1,3 @@
1
+ {
2
+ <%~ include("_shared/partials/config-json-fields", it) %>
3
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "<%= it.name %>",
3
+ <%~ include("_shared/partials/package-json-fields", it) %>
4
+ "dependencies": {
5
+ "@downdraft/engine": "^0.1.0",
6
+ "@downdraft/platform-native": "^0.1.0"
7
+ },
8
+ <%~ include("_shared/partials/dev-deps", it) %>
9
+ }