@downdraft/cli 0.0.0 → 0.1.1
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.
- package/README.md +11 -0
- package/package.json +36 -3
- package/scripts/default-icon.png +0 -0
- package/scripts/package-desktop.mjs +931 -0
- package/scripts/package-mobile.mjs +822 -0
- package/scripts/package-native.mjs +638 -0
- package/src/args.ts +333 -0
- package/src/assets.ts +523 -0
- package/src/blob-store-s3.ts +145 -0
- package/src/build-games.ts +45 -0
- package/src/build.ts +40 -0
- package/src/bun-env.d.ts +6 -0
- package/src/debug.ts +56 -0
- package/src/dev.ts +231 -0
- package/src/dist.ts +36 -0
- package/src/export.ts +38 -0
- package/src/index.ts +131 -0
- package/src/list-games.ts +37 -0
- package/src/mcp.ts +320 -0
- package/src/new.ts +63 -0
- package/src/paths.ts +101 -0
- package/src/plugin-command.ts +214 -0
- package/src/process-utils.ts +179 -0
- package/src/release.ts +432 -0
- package/src/scaffold-plugin.ts +280 -0
- package/src/scaffold.ts +207 -0
- package/src/test.ts +187 -0
- package/src/usage.ts +256 -0
- package/templates/_shared/ai-companion/devin-config.eta +11 -0
- package/templates/_shared/ai-companion/engine-prompt.eta +155 -0
- package/templates/_shared/ai-companion/logging-rule.eta +3 -0
- package/templates/_shared/ai-companion/loops-rule.eta +3 -0
- package/templates/_shared/partials/config-json-fields.eta +3 -0
- package/templates/_shared/partials/dev-deps.eta +8 -0
- package/templates/_shared/partials/package-json-fields.eta +12 -0
- package/templates/_shared/partials/tsconfig.eta +16 -0
- package/templates/_shared/partials/vscode-extensions.eta +11 -0
- package/templates/_shared/partials/vscode-settings.eta +29 -0
- package/templates/_shared/partials/vscode-tasks.eta +93 -0
- package/templates/full/.gitignore.eta +5 -0
- package/templates/full/.vscode/extensions.json.eta +1 -0
- package/templates/full/.vscode/settings.json.eta +1 -0
- package/templates/full/.vscode/tasks.json.eta +1 -0
- package/templates/full/README.md.eta +45 -0
- package/templates/full/assets/shaders/.eta +0 -0
- package/templates/full/downdraft.config.json.eta +10 -0
- package/templates/full/package.json.eta +9 -0
- package/templates/full/src/entities/.eta +0 -0
- package/templates/full/src/game-module.ts.eta +30 -0
- package/templates/full/src/native-entry.ts.eta +14 -0
- package/templates/full/src/sim-host.ts.eta +19 -0
- package/templates/full/src/sim-worker.ts.eta +99 -0
- package/templates/full/src/systems/.eta +0 -0
- package/templates/full/tsconfig.json.eta +1 -0
- package/templates/gamemodule/README.md.eta +32 -0
- package/templates/gamemodule/downdraft.config.json.eta +3 -0
- package/templates/gamemodule/package.json.eta +9 -0
- package/templates/gamemodule/src/game-module.ts.eta +63 -0
- package/templates/gamemodule/src/native-entry.ts.eta +14 -0
- package/templates/gamemodule/src/sim-host.ts.eta +25 -0
- package/templates/gamemodule/src/sim-worker.ts.eta +24 -0
- package/templates/gamemodule/tsconfig.json.eta +1 -0
- package/templates/minimal/.gitignore.eta +5 -0
- package/templates/minimal/.vscode/extensions.json.eta +1 -0
- package/templates/minimal/.vscode/settings.json.eta +1 -0
- package/templates/minimal/.vscode/tasks.json.eta +1 -0
- package/templates/minimal/README.md.eta +32 -0
- package/templates/minimal/downdraft.config.json.eta +3 -0
- package/templates/minimal/package.json.eta +9 -0
- package/templates/minimal/src/game-module.ts.eta +44 -0
- package/templates/minimal/src/native-entry.ts.eta +14 -0
- package/templates/minimal/tsconfig.json.eta +1 -0
- package/templates/physics/.gitignore.eta +5 -0
- package/templates/physics/.vscode/extensions.json.eta +1 -0
- package/templates/physics/.vscode/settings.json.eta +1 -0
- package/templates/physics/.vscode/tasks.json.eta +1 -0
- package/templates/physics/README.md.eta +36 -0
- package/templates/physics/downdraft.config.json.eta +6 -0
- package/templates/physics/package.json.eta +9 -0
- package/templates/physics/src/game-module.ts.eta +29 -0
- package/templates/physics/src/native-entry.ts.eta +14 -0
- package/templates/physics/src/sim-host.ts.eta +19 -0
- package/templates/physics/src/sim-worker.ts.eta +155 -0
- package/templates/physics/tsconfig.json.eta +1 -0
|
@@ -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,155 @@
|
|
|
1
|
+
import {
|
|
2
|
+
c,
|
|
3
|
+
Collider,
|
|
4
|
+
Component,
|
|
5
|
+
createBoxCollider,
|
|
6
|
+
createLogger,
|
|
7
|
+
createSimWorker,
|
|
8
|
+
createSphereCollider,
|
|
9
|
+
PhysicsTransform,
|
|
10
|
+
Query,
|
|
11
|
+
RigidBody,
|
|
12
|
+
spawn,
|
|
13
|
+
Stage,
|
|
14
|
+
system,
|
|
15
|
+
Velocity,
|
|
16
|
+
World,
|
|
17
|
+
} from "@downdraft/engine";
|
|
18
|
+
|
|
19
|
+
const log = createLogger();
|
|
20
|
+
|
|
21
|
+
// Physics demo sim worker — an ECS World with gravity + integration systems
|
|
22
|
+
// that spawns falling shapes. createSimWorker owns the tick loop, worker
|
|
23
|
+
// protocol, and stats; this file provides onInit + onTick.
|
|
24
|
+
|
|
25
|
+
type PhysicsBodyData = {
|
|
26
|
+
bodyType: "dynamic" | "static" | "kinematic";
|
|
27
|
+
mass: number;
|
|
28
|
+
restitution: number;
|
|
29
|
+
friction: number;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const PhysicsBody = Component.register<PhysicsBodyData>("PhysicsBody", {
|
|
33
|
+
bodyType: "dynamic",
|
|
34
|
+
mass: 1,
|
|
35
|
+
restitution: 0.4,
|
|
36
|
+
friction: 0.5,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
type FallingShapeData = {
|
|
40
|
+
shape: "box" | "sphere";
|
|
41
|
+
size: number;
|
|
42
|
+
color: [number, number, number];
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const FallingShape = Component.register<FallingShapeData>("FallingShape", {
|
|
46
|
+
shape: "box",
|
|
47
|
+
size: 1,
|
|
48
|
+
color: [1, 1, 1],
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const gravityQuery = new Query([RigidBody.id, Velocity.id, PhysicsTransform.id]);
|
|
52
|
+
|
|
53
|
+
let world: World;
|
|
54
|
+
let spawnTimer = 0;
|
|
55
|
+
|
|
56
|
+
createSimWorker({
|
|
57
|
+
fixedDt: 1 / 60,
|
|
58
|
+
|
|
59
|
+
onInit() {
|
|
60
|
+
world = new World();
|
|
61
|
+
|
|
62
|
+
// Ground entity — static body that shapes bounce on.
|
|
63
|
+
spawn(world,
|
|
64
|
+
c(PhysicsBody, { bodyType: "static", mass: 0, restitution: 0.3, friction: 0.8 }),
|
|
65
|
+
c(Collider, createBoxCollider([10, 0.5, 10])),
|
|
66
|
+
c(PhysicsTransform, { position: [0, -1, 0] }),
|
|
67
|
+
c(FallingShape, { shape: "box", size: 20, color: [0.3, 0.5, 0.3] }),
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
world.schedule.addSystem(system(
|
|
71
|
+
"physics-gravity", Stage.Update,
|
|
72
|
+
(ctx) => {
|
|
73
|
+
gravityQuery.iterate(ctx.tick, (_ent, comps) => {
|
|
74
|
+
const body = comps[0] as any;
|
|
75
|
+
const vel = comps[1] as any;
|
|
76
|
+
if (body && vel && body.bodyType === "dynamic") {
|
|
77
|
+
vel.linear[1] -= 9.81 * ctx.dt * (body.gravityScale as number);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
{ queries: [gravityQuery] },
|
|
82
|
+
));
|
|
83
|
+
|
|
84
|
+
world.schedule.addSystem(system(
|
|
85
|
+
"physics-integrate", Stage.Update,
|
|
86
|
+
(ctx) => {
|
|
87
|
+
gravityQuery.iterate(ctx.tick, (ent, comps) => {
|
|
88
|
+
const body = comps[0] as any;
|
|
89
|
+
const vel = comps[1] as any;
|
|
90
|
+
const transform = comps[2] as any;
|
|
91
|
+
if (body && vel && transform && body.bodyType === "dynamic") {
|
|
92
|
+
const [vx, vy, vz] = vel.linear as [number, number, number];
|
|
93
|
+
const [px, py, pz] = transform.position as [number, number, number];
|
|
94
|
+
const newPy = py + vy * ctx.dt;
|
|
95
|
+
transform.position = [px + vx * ctx.dt, newPy, pz + vz * ctx.dt];
|
|
96
|
+
|
|
97
|
+
if (newPy < -10) {
|
|
98
|
+
world.despawn(ent);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
{ queries: [gravityQuery] },
|
|
104
|
+
));
|
|
105
|
+
|
|
106
|
+
log.info("sim", "physics demo initialized — shapes will fall and bounce on the ground");
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
onTick(dt) {
|
|
110
|
+
spawnTimer += dt;
|
|
111
|
+
if (spawnTimer > 0.5) {
|
|
112
|
+
spawnTimer = 0;
|
|
113
|
+
spawnFallingShape();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
world.step(dt);
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
onShutdown() {
|
|
120
|
+
log.info("sim", "sim worker shutdown");
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
function spawnFallingShape(): void {
|
|
125
|
+
const isBox = Math.random() > 0.5;
|
|
126
|
+
const size = 0.5 + Math.random() * 1.5;
|
|
127
|
+
const x = (Math.random() - 0.5) * 10;
|
|
128
|
+
const z = (Math.random() - 0.5) * 10;
|
|
129
|
+
|
|
130
|
+
spawn(world,
|
|
131
|
+
c(PhysicsBody, {
|
|
132
|
+
bodyType: "dynamic",
|
|
133
|
+
mass: size * size * size,
|
|
134
|
+
restitution: 0.3 + Math.random() * 0.4,
|
|
135
|
+
friction: 0.3 + Math.random() * 0.4,
|
|
136
|
+
}),
|
|
137
|
+
c(RigidBody, {
|
|
138
|
+
bodyType: "dynamic",
|
|
139
|
+
mass: size * size * size,
|
|
140
|
+
gravityScale: 1,
|
|
141
|
+
}),
|
|
142
|
+
c(Velocity, {
|
|
143
|
+
linear: [(Math.random() - 0.5) * 2, 0, (Math.random() - 0.5) * 2],
|
|
144
|
+
}),
|
|
145
|
+
c(PhysicsTransform, { position: [x, 15, z] }),
|
|
146
|
+
c(Collider, isBox
|
|
147
|
+
? createBoxCollider([size / 2, size / 2, size / 2])
|
|
148
|
+
: createSphereCollider(size * 0.5)),
|
|
149
|
+
c(FallingShape, {
|
|
150
|
+
shape: isBox ? "box" : "sphere",
|
|
151
|
+
size: isBox ? size : size * 0.5,
|
|
152
|
+
color: [Math.random(), Math.random(), Math.random()],
|
|
153
|
+
}),
|
|
154
|
+
);
|
|
155
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%~ include("_shared/partials/tsconfig", it) %>
|