create-shallot 0.3.9 → 0.5.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.
- package/index.ts +80 -15
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -42,6 +42,14 @@ writeFileSync(
|
|
|
42
42
|
`,
|
|
43
43
|
);
|
|
44
44
|
|
|
45
|
+
writeFileSync(
|
|
46
|
+
join(dir, ".gitignore"),
|
|
47
|
+
`node_modules/
|
|
48
|
+
dist/
|
|
49
|
+
build/
|
|
50
|
+
`,
|
|
51
|
+
);
|
|
52
|
+
|
|
45
53
|
writeFileSync(
|
|
46
54
|
join(dir, "package.json"),
|
|
47
55
|
JSON.stringify(
|
|
@@ -50,9 +58,34 @@ writeFileSync(
|
|
|
50
58
|
version: "0.0.0",
|
|
51
59
|
private: true,
|
|
52
60
|
type: "module",
|
|
53
|
-
scripts: {
|
|
61
|
+
scripts: {
|
|
62
|
+
dev: "vite",
|
|
63
|
+
build: "vite build",
|
|
64
|
+
preview: "vite preview",
|
|
65
|
+
},
|
|
54
66
|
dependencies: { "@dylanebert/shallot": "latest" },
|
|
55
|
-
devDependencies: { vite: "^8.0.0" },
|
|
67
|
+
devDependencies: { typescript: "^5.9.3", vite: "^8.0.0" },
|
|
68
|
+
},
|
|
69
|
+
null,
|
|
70
|
+
2,
|
|
71
|
+
) + "\n",
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
writeFileSync(
|
|
75
|
+
join(dir, "tsconfig.json"),
|
|
76
|
+
JSON.stringify(
|
|
77
|
+
{
|
|
78
|
+
compilerOptions: {
|
|
79
|
+
target: "ESNext",
|
|
80
|
+
module: "ESNext",
|
|
81
|
+
moduleResolution: "bundler",
|
|
82
|
+
lib: ["ESNext", "DOM", "DOM.Iterable"],
|
|
83
|
+
types: ["@webgpu/types", "vite/client"],
|
|
84
|
+
strict: true,
|
|
85
|
+
noEmit: true,
|
|
86
|
+
skipLibCheck: true,
|
|
87
|
+
},
|
|
88
|
+
include: ["src"],
|
|
56
89
|
},
|
|
57
90
|
null,
|
|
58
91
|
2,
|
|
@@ -66,11 +99,11 @@ writeFileSync(
|
|
|
66
99
|
<head>
|
|
67
100
|
<meta charset="UTF-8" />
|
|
68
101
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
69
|
-
<link rel="icon" type="image/svg+xml" href="
|
|
102
|
+
<link rel="icon" type="image/svg+xml" href="./icon.svg" />
|
|
70
103
|
<title>${name}</title>
|
|
71
104
|
<style>
|
|
72
105
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
73
|
-
body { background: #
|
|
106
|
+
body { background: #0c0a09; overflow: hidden; }
|
|
74
107
|
canvas { display: block; width: 100vw; height: 100vh; }
|
|
75
108
|
</style>
|
|
76
109
|
</head>
|
|
@@ -87,19 +120,44 @@ writeFileSync(
|
|
|
87
120
|
`import { defineConfig } from "vite";
|
|
88
121
|
|
|
89
122
|
export default defineConfig({
|
|
123
|
+
base: "./",
|
|
90
124
|
server: { port: 3000 },
|
|
91
|
-
build: {
|
|
125
|
+
build: {
|
|
126
|
+
target: "esnext",
|
|
127
|
+
outDir: "dist",
|
|
128
|
+
emptyOutDir: true,
|
|
129
|
+
},
|
|
92
130
|
});
|
|
93
131
|
`,
|
|
94
132
|
);
|
|
95
133
|
|
|
96
134
|
writeFileSync(
|
|
97
135
|
join(dir, "src/lib.ts"),
|
|
98
|
-
`import {
|
|
136
|
+
`import { type Config, Part, quat, type State, type System, Transform } from "@dylanebert/shallot";
|
|
137
|
+
|
|
138
|
+
// A system is plain data: an \`update\` the engine runs each frame. This one spins
|
|
139
|
+
// every Part around Y. It runs in the standalone app but not the editor — \`shallot .\`
|
|
140
|
+
// builds in edit mode, where unannotated systems are skipped, so the cube stays put
|
|
141
|
+
// and editable there. Delete it (and the plugin entry below) for a static scene.
|
|
142
|
+
let angle = 0;
|
|
143
|
+
const SpinSystem: System = {
|
|
144
|
+
group: "simulation",
|
|
145
|
+
update(state: State) {
|
|
146
|
+
angle = (angle + state.time.deltaTime * 45) % 360;
|
|
147
|
+
const q = quat(0, angle, 0);
|
|
148
|
+
for (const eid of state.query([Part, Transform])) {
|
|
149
|
+
Transform.rot.set(eid, q.x, q.y, q.z, q.w);
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
};
|
|
99
153
|
|
|
154
|
+
// The project definition, shared by the standalone app (src/main.ts) and the shallot
|
|
155
|
+
// editor (\`shallot .\`). The default plugins (render, lit surface, orbit camera) stay
|
|
156
|
+
// on; the spin plugin adds our one system. The scene lives here too, so main.ts stays
|
|
157
|
+
// untouched as the project grows.
|
|
100
158
|
export const config: Config = {
|
|
101
|
-
plugins: [
|
|
102
|
-
scene: "
|
|
159
|
+
plugins: [{ name: "spin", systems: [SpinSystem] }],
|
|
160
|
+
scene: "scenes/scene.scene",
|
|
103
161
|
};
|
|
104
162
|
`,
|
|
105
163
|
);
|
|
@@ -109,21 +167,28 @@ writeFileSync(
|
|
|
109
167
|
`import { run } from "@dylanebert/shallot";
|
|
110
168
|
import { config } from "./lib";
|
|
111
169
|
|
|
112
|
-
|
|
170
|
+
// One config source (src/lib.ts) drives both this standalone build and the editor. The camera
|
|
171
|
+
// auto-binds to the page's <canvas>.
|
|
172
|
+
const { dispose } = await run(config);
|
|
113
173
|
|
|
174
|
+
// HMR re-runs this module — dispose the old State + RAF loop or each reload stacks another.
|
|
114
175
|
if (import.meta.hot) {
|
|
115
|
-
import.meta.hot.dispose(() =>
|
|
176
|
+
import.meta.hot.dispose(() => dispose());
|
|
116
177
|
}
|
|
117
178
|
`,
|
|
118
179
|
);
|
|
119
180
|
|
|
120
181
|
writeFileSync(
|
|
121
|
-
join(dir, "public/scenes/
|
|
182
|
+
join(dir, "public/scenes/scene.scene"),
|
|
122
183
|
`<scene>
|
|
123
|
-
<a
|
|
124
|
-
<a
|
|
125
|
-
|
|
126
|
-
<
|
|
184
|
+
<a ambient-light="color: 0xd0dcec; intensity: 0.5" />
|
|
185
|
+
<a directional-light="direction: -0.4 -1 -0.55; color: 0xfff4e0; intensity: 1.1" />
|
|
186
|
+
|
|
187
|
+
<!-- the camera auto-binds to the page's <canvas>; drag to orbit, scroll to zoom -->
|
|
188
|
+
<a camera sear orbit="distance: 5; yaw: 0.6; pitch: 0.25" transform />
|
|
189
|
+
|
|
190
|
+
<!-- a Part is the engine's drop-in renderable: a mesh (default "cube") wearing a surface (default "default", lit) -->
|
|
191
|
+
<a part transform="pos: 0 0 0" color="rgba: 0.85 0.55 0.35 1" />
|
|
127
192
|
</scene>
|
|
128
193
|
`,
|
|
129
194
|
);
|