create-threejs-game 1.0.0 → 1.0.4
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/bin/cli.js +113 -16
- package/package.json +1 -1
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
|
-
|
|
248
|
-
|
|
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
|
-
//
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
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
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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) {
|