create-threejs-game 1.0.0 → 1.0.5

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 (3) hide show
  1. package/README.md +56 -52
  2. package/bin/cli.js +113 -16
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -2,70 +2,67 @@
2
2
 
3
3
  Scaffold a Three.js game project with AI-assisted design documents.
4
4
 
5
- ## Quick Start
6
-
7
- ```bash
8
- npx create-threejs-game my-game
9
- cd my-game
10
- # Add assets to public/assets/my_game/
11
- node scripts/pipeline.js
12
- ```
5
+ ## Prerequisites
13
6
 
14
- ## What it does
7
+ Before running the CLI, have these ready:
15
8
 
16
- This CLI creates a Three.js game project with:
9
+ ### 1. 3D Assets (Required)
10
+ Download a GLTF asset pack from:
11
+ - [itch.io](https://itch.io/game-assets/tag-3d)
12
+ - [Kenney.nl](https://kenney.nl/assets)
13
+ - [Quaternius](https://quaternius.com/)
17
14
 
18
- - **Three.js skills** for Claude/Codex AI assistance
19
- - **Automation scripts** to generate:
20
- - Asset index (assets.json)
21
- - Concept mockup (via Google AI Studio)
22
- - Product Requirements Document (PRD)
23
- - Technical Design Document (TDD)
24
- - Implementation plan
25
- - **Prompt templates** for each generation step
15
+ The CLI will ask for the path to your downloaded assets folder and validate it contains `.gltf` or `.glb` files.
26
16
 
27
- ## Interactive Setup
17
+ ### 2. Preview Image (Recommended)
18
+ Most asset packs include a `Preview.jpg`. If not, take a screenshot of your assets. This is used by the AI to generate concept mockups.
28
19
 
29
- Run without arguments for interactive mode:
20
+ ### 3. API Keys (Required for automation)
21
+ Set these as environment variables for the smoothest experience:
30
22
 
31
23
  ```bash
32
- npx create-threejs-game
24
+ export GOOGLE_API_KEY="your-key" # or GOOGLE_AI_STUDIO_API_KEY
25
+ export ANTHROPIC_API_KEY="your-key"
33
26
  ```
34
27
 
35
- You'll be asked for:
36
- 1. Project name
37
- 2. Game description (1-3 sentences)
38
- 3. API keys (only if not found in environment)
39
-
40
- **Supported environment variables:**
41
- - `GOOGLE_API_KEY` or `GOOGLE_AI_STUDIO_API_KEY`
42
- - `ANTHROPIC_API_KEY`
43
-
44
- ## Manual Steps
28
+ Get keys from:
29
+ - [Google AI Studio](https://aistudio.google.com/) - free tier available
30
+ - [Anthropic Console](https://console.anthropic.com/)
45
31
 
46
- After scaffolding, you'll need to:
32
+ If not set, the CLI will prompt for them.
47
33
 
48
- 1. **Add your 3D assets** to `public/assets/{game_name}/`
49
- - Download from itch.io, Kenney.nl, Quaternius, etc.
50
- - GLTF format preferred
51
-
52
- 2. **Add Preview.jpg** to the assets folder
53
- - Most asset packs include one
54
- - Or screenshot your assets
34
+ ## Quick Start
55
35
 
56
- 3. **Configure API keys** in `scripts/config.json`:
57
- - Google AI Studio: for mockup generation
58
- - Anthropic: for PRD/TDD/plan generation
36
+ ```bash
37
+ npx create-threejs-game
38
+ ```
59
39
 
60
- ## Automated Pipeline
40
+ The CLI will:
41
+ 1. Ask for your **project name**
42
+ 2. Ask for a **game description** (1-3 sentences describing your game)
43
+ 3. Check for **API keys** (from env vars, or prompt if missing)
44
+ 4. Ask for **path to your assets folder** (required for automation)
45
+ 5. Validate everything and tell you if anything is missing
46
+ 6. Create your project with assets copied in
61
47
 
62
- Once configured, run:
48
+ Then run the automation:
63
49
 
64
50
  ```bash
51
+ cd my-game
65
52
  node scripts/pipeline.js
66
53
  ```
67
54
 
68
- This generates all design documents automatically, leaving you with an implementation plan to follow in Claude Code or Cursor.
55
+ ## What Gets Generated
56
+
57
+ The automation pipeline creates:
58
+
59
+ | Step | Output | AI Service |
60
+ |------|--------|------------|
61
+ | Asset Index | `public/assets/{game}/assets.json` | Local script |
62
+ | Concept Mockup | `public/{game}/concept.jpg` | Google AI Studio |
63
+ | PRD | `docs/prd.md` | Claude (Anthropic) |
64
+ | TDD | `docs/tdd.md` | Claude (Anthropic) |
65
+ | Execution Plan | `plans/plan.md` | Claude (Anthropic) |
69
66
 
70
67
  ## Project Structure
71
68
 
@@ -75,22 +72,29 @@ my-game/
75
72
  ├── .codex/skills/ # Three.js skills for Codex
76
73
  ├── docs/ # Generated PRD and TDD
77
74
  ├── plans/ # Generated implementation plans
78
- ├── prompts/ # Manual prompt templates (fallback)
75
+ ├── prompts/ # Prompt templates (fallback/reference)
79
76
  ├── public/
80
- │ └── assets/{game}/ # Your 3D assets go here
77
+ │ └── assets/{game}/ # Your 3D assets (copied by CLI)
81
78
  ├── scripts/
82
- │ ├── config.json # Your configuration
79
+ │ ├── config.json # API keys and game config
83
80
  │ ├── pipeline.js # Run full automation
84
81
  │ └── generate-*.js # Individual generators
85
- └── README.md # Detailed workflow guide
82
+ └── README.md
83
+ ```
84
+
85
+ ## Final Step
86
+
87
+ After the pipeline completes, open your project in Claude Code or Cursor and follow the generated execution plan:
88
+
89
+ ```
90
+ Please proceed with implementing based on the plan in plans/plan.md
86
91
  ```
87
92
 
88
93
  ## Requirements
89
94
 
90
95
  - Node.js 18+
91
- - API keys (for automation):
92
- - [Google AI Studio](https://aistudio.google.com/) - free tier available
93
- - [Anthropic](https://console.anthropic.com/) - API access required
96
+ - API keys (see Prerequisites)
97
+ - 3D assets in GLTF format
94
98
 
95
99
  ## License
96
100
 
package/bin/cli.js CHANGED
@@ -194,6 +194,67 @@ async function main() {
194
194
  console.log('');
195
195
  }
196
196
 
197
+ // Ask for assets location (required for automation)
198
+ console.log(c('bright', '📁 3D Assets (Required)'));
199
+ console.log(c('dim', '─'.repeat(50)));
200
+ console.log(c('dim', 'The automation pipeline needs 3D assets to generate mockups and docs.'));
201
+ console.log(c('dim', 'Download a GLTF asset pack from itch.io, Kenney.nl, etc. first.\n'));
202
+
203
+ let assetsSourcePath = '';
204
+
205
+ while (!assetsSourcePath) {
206
+ let inputPath = await ask(c('bright', 'Path to assets folder'));
207
+
208
+ if (!inputPath) {
209
+ const skipAnyway = await confirm(
210
+ c('yellow', 'Without assets, the automation pipeline cannot run. Skip anyway?'),
211
+ false
212
+ );
213
+ if (skipAnyway) {
214
+ console.log(c('yellow', '\n ⚠ No assets provided. You\'ll need to add them manually before running the pipeline.\n'));
215
+ break;
216
+ }
217
+ continue;
218
+ }
219
+
220
+ // Expand ~ to home directory
221
+ if (inputPath.startsWith('~')) {
222
+ inputPath = path.join(process.env.HOME || process.env.USERPROFILE, inputPath.slice(1));
223
+ }
224
+
225
+ // Resolve relative paths
226
+ if (!path.isAbsolute(inputPath)) {
227
+ inputPath = path.resolve(process.cwd(), inputPath);
228
+ }
229
+
230
+ // Validate path
231
+ if (!fs.existsSync(inputPath)) {
232
+ console.log(c('red', ` ✗ Path not found: ${inputPath}`));
233
+ console.log(c('dim', ' Please check the path and try again.\n'));
234
+ continue;
235
+ }
236
+
237
+ const stat = fs.statSync(inputPath);
238
+ if (!stat.isDirectory()) {
239
+ console.log(c('red', ' ✗ Path is not a directory.'));
240
+ console.log(c('dim', ' Please provide a folder path.\n'));
241
+ continue;
242
+ }
243
+
244
+ // Check if it has any gltf/glb files
245
+ const hasModels = fs.readdirSync(inputPath, { recursive: true })
246
+ .some(f => f.endsWith('.gltf') || f.endsWith('.glb'));
247
+
248
+ if (!hasModels) {
249
+ console.log(c('yellow', ' ⚠ No .gltf or .glb files found in this folder.'));
250
+ const useAnyway = await confirm('Use this folder anyway?', false);
251
+ if (!useAnyway) continue;
252
+ }
253
+
254
+ assetsSourcePath = inputPath;
255
+ console.log(c('green', ' ✓ ') + 'Assets folder validated\n');
256
+ }
257
+
197
258
  // Copy template
198
259
  console.log(c('bright', '📦 Creating project...'));
199
260
  console.log(c('dim', '─'.repeat(50)));
@@ -244,8 +305,31 @@ async function main() {
244
305
  // Create assets directory
245
306
  const assetsDir = path.join(projectPath, 'public', 'assets', gameName);
246
307
  fs.mkdirSync(assetsDir, { recursive: true });
247
- fs.writeFileSync(path.join(assetsDir, '.gitkeep'), '');
248
- console.log(c('green', ' ✓ ') + `public/assets/${gameName}/`);
308
+
309
+ // Copy assets if path was provided
310
+ if (assetsSourcePath) {
311
+ console.log(c('dim', ' Copying assets...'));
312
+ copyDir(assetsSourcePath, assetsDir, ['node_modules', '.git', '.DS_Store']);
313
+
314
+ // Count copied files
315
+ const countFiles = (dir) => {
316
+ let count = 0;
317
+ const items = fs.readdirSync(dir, { withFileTypes: true });
318
+ for (const item of items) {
319
+ if (item.isDirectory()) {
320
+ count += countFiles(path.join(dir, item.name));
321
+ } else {
322
+ count++;
323
+ }
324
+ }
325
+ return count;
326
+ };
327
+ const fileCount = countFiles(assetsDir);
328
+ console.log(c('green', ' ✓ ') + `public/assets/${gameName}/ (${fileCount} files copied)`);
329
+ } else {
330
+ fs.writeFileSync(path.join(assetsDir, '.gitkeep'), '');
331
+ console.log(c('green', ' ✓ ') + `public/assets/${gameName}/`);
332
+ }
249
333
 
250
334
  console.log('');
251
335
  console.log(c('green', `✅ Project created at: ${projectPath}`));
@@ -264,21 +348,34 @@ async function main() {
264
348
  const steps = [];
265
349
  let stepNum = 1;
266
350
 
267
- // Step: Add assets
268
- steps.push({
269
- num: stepNum++,
270
- manual: true,
271
- text: `Add your 3D assets to ${c('cyan', `public/assets/${gameName}/`)}`,
272
- detail: 'Download a GLTF asset pack from itch.io, Kenney.nl, or similar'
273
- });
351
+ // Check if assets were copied and if Preview exists
352
+ const hasAssets = assetsSourcePath && fs.existsSync(assetsDir);
353
+ const previewExists = hasAssets && (
354
+ fs.existsSync(path.join(assetsDir, 'Preview.jpg')) ||
355
+ fs.existsSync(path.join(assetsDir, 'Preview.png')) ||
356
+ fs.existsSync(path.join(assetsDir, 'preview.jpg')) ||
357
+ fs.existsSync(path.join(assetsDir, 'preview.png'))
358
+ );
359
+
360
+ // Step: Add assets (only if not already copied)
361
+ if (!hasAssets) {
362
+ steps.push({
363
+ num: stepNum++,
364
+ manual: true,
365
+ text: `Add your 3D assets to ${c('cyan', `public/assets/${gameName}/`)}`,
366
+ detail: 'Download a GLTF asset pack from itch.io, Kenney.nl, or similar'
367
+ });
368
+ }
274
369
 
275
- // Step: Add preview
276
- steps.push({
277
- num: stepNum++,
278
- manual: true,
279
- text: `Ensure ${c('cyan', 'Preview.jpg')} exists in the assets folder`,
280
- detail: 'Most asset packs include one, or take a screenshot of your assets'
281
- });
370
+ // Step: Add preview (only if not found)
371
+ if (!previewExists) {
372
+ steps.push({
373
+ num: stepNum++,
374
+ manual: true,
375
+ text: `Ensure ${c('cyan', 'Preview.jpg')} exists in the assets folder`,
376
+ detail: 'Most asset packs include one, or take a screenshot of your assets'
377
+ });
378
+ }
282
379
 
283
380
  // Step: API keys
284
381
  if (!hasGoogleKey || !hasAnthropicKey) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-threejs-game",
3
- "version": "1.0.0",
3
+ "version": "1.0.5",
4
4
  "description": "Scaffold a Three.js game project with AI-assisted design documents",
5
5
  "bin": {
6
6
  "create-threejs-game": "./bin/cli.js"