create-threejs-game 1.1.0 → 1.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 CHANGED
@@ -14,14 +14,18 @@ Download GLTF asset packs from:
14
14
 
15
15
  The CLI will ask for the path to your downloaded assets folder and validate it contains `.gltf` or `.glb` files.
16
16
 
17
- **Multi-Pack Support:** You can combine multiple asset packs by organizing them in subdirectories:
17
+ **Multi-Pack Support:** You can combine multiple asset packs by organizing them in subdirectories (nested to any depth):
18
18
  ```
19
19
  my-assets/
20
- ├── characters/ # Asset pack 1 (with Preview.jpg)
21
- ├── buildings/ # Asset pack 2 (with Preview.jpg)
22
- └── environment/ # Asset pack 3 (with Preview.jpg)
20
+ ├── characters/
21
+ ├── humans/ # Has Preview.jpg
22
+ └── monsters/ # Has Preview.jpg
23
+ ├── buildings/ # Has Preview.jpg
24
+ └── environment/
25
+ ├── trees/ # Has Preview.jpg
26
+ └── rocks/ # Has Preview.jpg
23
27
  ```
24
- The CLI auto-detects this structure and combines all preview images into a single grid.
28
+ The CLI recursively finds all directories with previews and combines them into a single grid.
25
29
 
26
30
  ### 2. Preview Image (Auto-generated for multi-packs)
27
31
  Most asset packs include a `Preview.jpg`. For multi-pack directories, the CLI automatically combines all subdirectory previews into one image. For single packs without a preview, take a screenshot of your assets.
package/bin/cli.js CHANGED
@@ -112,28 +112,41 @@ function findPreview(dir) {
112
112
  return null;
113
113
  }
114
114
 
115
- // Detect if directory is a multi-pack (has subdirs with previews)
116
- function detectMultiPack(sourceDir) {
117
- const entries = fs.readdirSync(sourceDir, { withFileTypes: true });
118
- const subdirs = entries.filter(e => e.isDirectory());
119
-
120
- if (subdirs.length === 0) return null;
121
-
122
- const packsWithPreviews = [];
115
+ // Recursively find all directories with preview images
116
+ function findPacksWithPreviews(dir, basePath = dir) {
117
+ const packs = [];
118
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
119
+
120
+ // Check if this directory has a preview
121
+ const preview = findPreview(dir);
122
+ if (preview && dir !== basePath) {
123
+ // Use relative path from base as the name
124
+ const relativePath = path.relative(basePath, dir);
125
+ packs.push({
126
+ name: relativePath,
127
+ path: dir,
128
+ preview: preview
129
+ });
130
+ }
123
131
 
124
- for (const subdir of subdirs) {
125
- const subdirPath = path.join(sourceDir, subdir.name);
126
- const preview = findPreview(subdirPath);
127
- if (preview) {
128
- packsWithPreviews.push({
129
- name: subdir.name,
130
- path: subdirPath,
131
- preview: preview
132
- });
133
- }
132
+ // Recursively check subdirectories
133
+ for (const entry of entries) {
134
+ if (!entry.isDirectory()) continue;
135
+ if (entry.name.startsWith('.')) continue; // Skip hidden dirs
136
+
137
+ const subdirPath = path.join(dir, entry.name);
138
+ const subPacks = findPacksWithPreviews(subdirPath, basePath);
139
+ packs.push(...subPacks);
134
140
  }
135
141
 
136
- // Consider it a multi-pack if at least 2 subdirs have previews
142
+ return packs;
143
+ }
144
+
145
+ // Detect if directory is a multi-pack (has subdirs with previews)
146
+ function detectMultiPack(sourceDir) {
147
+ const packsWithPreviews = findPacksWithPreviews(sourceDir, sourceDir);
148
+
149
+ // Consider it a multi-pack if at least 2 directories have previews
137
150
  if (packsWithPreviews.length >= 2) {
138
151
  return packsWithPreviews;
139
152
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-threejs-game",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
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"
@@ -23,29 +23,47 @@ try {
23
23
  }
24
24
 
25
25
  /**
26
- * Find all preview images in subdirectories
26
+ * Find preview image in a directory
27
27
  */
28
- function findPreviews(sourceDir) {
28
+ function findPreview(dir) {
29
+ const previewNames = ['Preview.jpg', 'Preview.png', 'preview.jpg', 'preview.png',
30
+ 'Preview.jpeg', 'preview.jpeg'];
31
+ for (const name of previewNames) {
32
+ const previewPath = path.join(dir, name);
33
+ if (fs.existsSync(previewPath)) {
34
+ return previewPath;
35
+ }
36
+ }
37
+ return null;
38
+ }
39
+
40
+ /**
41
+ * Recursively find all preview images in subdirectories (any depth)
42
+ */
43
+ function findPreviews(sourceDir, basePath = sourceDir) {
29
44
  const previews = [];
30
45
  const entries = fs.readdirSync(sourceDir, { withFileTypes: true });
31
46
 
47
+ // Check if this directory has a preview (skip the root)
48
+ if (sourceDir !== basePath) {
49
+ const preview = findPreview(sourceDir);
50
+ if (preview) {
51
+ const relativePath = path.relative(basePath, sourceDir);
52
+ previews.push({
53
+ path: preview,
54
+ name: relativePath
55
+ });
56
+ }
57
+ }
58
+
59
+ // Recursively check subdirectories
32
60
  for (const entry of entries) {
33
61
  if (!entry.isDirectory()) continue;
62
+ if (entry.name.startsWith('.')) continue; // Skip hidden dirs
34
63
 
35
- const subdir = path.join(sourceDir, entry.name);
36
- const previewNames = ['Preview.jpg', 'Preview.png', 'preview.jpg', 'preview.png',
37
- 'Preview.jpeg', 'preview.jpeg'];
38
-
39
- for (const name of previewNames) {
40
- const previewPath = path.join(subdir, name);
41
- if (fs.existsSync(previewPath)) {
42
- previews.push({
43
- path: previewPath,
44
- name: entry.name
45
- });
46
- break;
47
- }
48
- }
64
+ const subdirPath = path.join(sourceDir, entry.name);
65
+ const subPreviews = findPreviews(subdirPath, basePath);
66
+ previews.push(...subPreviews);
49
67
  }
50
68
 
51
69
  return previews;
@@ -182,7 +200,7 @@ async function main() {
182
200
  }
183
201
 
184
202
  // Export for use as module
185
- module.exports = { findPreviews, combineImages, calculateGrid };
203
+ module.exports = { findPreview, findPreviews, combineImages, calculateGrid };
186
204
 
187
205
  // Run if called directly
188
206
  if (require.main === module) {