gamedev 0.0.4-alpha.1 → 0.0.4-alpha.2
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/app-server/scaffold.js +86 -1
- package/bin/gamedev.mjs +3 -0
- package/build/public/admin.html +2 -2
- package/build/public/index.html +2 -2
- package/build/world-node-client.js +1339 -214
- package/build/world-node-client.js.map +4 -4
- package/package.json +1 -1
package/app-server/scaffold.js
CHANGED
|
@@ -202,6 +202,58 @@ function resolveBuiltinScriptPath(filename) {
|
|
|
202
202
|
return null
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
function resolveBuiltinAssetPath(filename) {
|
|
206
|
+
const buildPath = path.join(__dirname, '..', 'build', 'world', 'assets', filename)
|
|
207
|
+
if (fs.existsSync(buildPath)) return buildPath
|
|
208
|
+
const srcPath = path.join(__dirname, '..', 'src', 'world', 'assets', filename)
|
|
209
|
+
if (fs.existsSync(srcPath)) return srcPath
|
|
210
|
+
return null
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function collectAssetFilenames(value, out) {
|
|
214
|
+
if (!out) out = new Set()
|
|
215
|
+
if (typeof value === 'string') {
|
|
216
|
+
if (value.startsWith('asset://')) {
|
|
217
|
+
out.add(value.slice('asset://'.length))
|
|
218
|
+
} else if (value.startsWith('assets/')) {
|
|
219
|
+
out.add(value.slice('assets/'.length))
|
|
220
|
+
}
|
|
221
|
+
return out
|
|
222
|
+
}
|
|
223
|
+
if (Array.isArray(value)) {
|
|
224
|
+
for (const item of value) {
|
|
225
|
+
collectAssetFilenames(item, out)
|
|
226
|
+
}
|
|
227
|
+
return out
|
|
228
|
+
}
|
|
229
|
+
if (value && typeof value === 'object') {
|
|
230
|
+
for (const item of Object.values(value)) {
|
|
231
|
+
collectAssetFilenames(item, out)
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return out
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function toLocalAssetUrls(value) {
|
|
238
|
+
if (typeof value === 'string') {
|
|
239
|
+
if (value.startsWith('asset://')) {
|
|
240
|
+
return `assets/${value.slice('asset://'.length)}`
|
|
241
|
+
}
|
|
242
|
+
return value
|
|
243
|
+
}
|
|
244
|
+
if (Array.isArray(value)) {
|
|
245
|
+
return value.map(item => toLocalAssetUrls(item))
|
|
246
|
+
}
|
|
247
|
+
if (value && typeof value === 'object') {
|
|
248
|
+
const next = {}
|
|
249
|
+
for (const [key, item] of Object.entries(value)) {
|
|
250
|
+
next[key] = toLocalAssetUrls(item)
|
|
251
|
+
}
|
|
252
|
+
return next
|
|
253
|
+
}
|
|
254
|
+
return value
|
|
255
|
+
}
|
|
256
|
+
|
|
205
257
|
function readBuiltinScript(template) {
|
|
206
258
|
const scriptPath = resolveBuiltinScriptPath(template.scriptAsset)
|
|
207
259
|
if (!scriptPath) {
|
|
@@ -296,16 +348,21 @@ export function createDefaultManifest() {
|
|
|
296
348
|
export function scaffoldBuiltins({ rootDir, force = false, writeFile } = {}) {
|
|
297
349
|
const report = { created: [], updated: [], skipped: [] }
|
|
298
350
|
const appsDir = path.join(rootDir, 'apps')
|
|
351
|
+
const assetsDir = path.join(rootDir, 'assets')
|
|
299
352
|
ensureDir(appsDir)
|
|
300
353
|
|
|
301
354
|
const templates = [...BUILTIN_APP_TEMPLATES, SCENE_TEMPLATE]
|
|
355
|
+
const assetFiles = new Set()
|
|
356
|
+
|
|
302
357
|
for (const template of templates) {
|
|
358
|
+
collectAssetFilenames(template.config, assetFiles)
|
|
303
359
|
const appDir = path.join(appsDir, template.appName)
|
|
304
360
|
ensureDir(appDir)
|
|
305
361
|
|
|
306
362
|
const blueprintPath = path.join(appDir, `${template.fileBase}.json`)
|
|
307
363
|
if (!fs.existsSync(blueprintPath) || force) {
|
|
308
|
-
|
|
364
|
+
const localConfig = toLocalAssetUrls(template.config)
|
|
365
|
+
writeFileWithPolicy(blueprintPath, JSON.stringify(localConfig, null, 2) + '\n', {
|
|
309
366
|
force,
|
|
310
367
|
writeFile,
|
|
311
368
|
report,
|
|
@@ -320,6 +377,34 @@ export function scaffoldBuiltins({ rootDir, force = false, writeFile } = {}) {
|
|
|
320
377
|
}
|
|
321
378
|
}
|
|
322
379
|
|
|
380
|
+
if (assetFiles.size) {
|
|
381
|
+
ensureDir(assetsDir)
|
|
382
|
+
for (const filename of assetFiles) {
|
|
383
|
+
const srcPath = resolveBuiltinAssetPath(filename)
|
|
384
|
+
if (!srcPath) {
|
|
385
|
+
throw new Error(`missing_builtin_asset:${filename}`)
|
|
386
|
+
}
|
|
387
|
+
const destPath = path.join(assetsDir, filename)
|
|
388
|
+
const exists = fs.existsSync(destPath)
|
|
389
|
+
if (exists && !force) {
|
|
390
|
+
report.skipped.push(destPath)
|
|
391
|
+
continue
|
|
392
|
+
}
|
|
393
|
+
const buffer = fs.readFileSync(srcPath)
|
|
394
|
+
if (writeFile) {
|
|
395
|
+
writeFile(destPath, buffer)
|
|
396
|
+
} else {
|
|
397
|
+
ensureDir(path.dirname(destPath))
|
|
398
|
+
fs.writeFileSync(destPath, buffer)
|
|
399
|
+
}
|
|
400
|
+
if (exists) {
|
|
401
|
+
report.updated.push(destPath)
|
|
402
|
+
} else {
|
|
403
|
+
report.created.push(destPath)
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
323
408
|
return { report, manifest: createDefaultManifest() }
|
|
324
409
|
}
|
|
325
410
|
|
package/bin/gamedev.mjs
CHANGED
package/build/public/admin.html
CHANGED
|
@@ -25,14 +25,14 @@
|
|
|
25
25
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
26
26
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
27
27
|
<link rel="preload" href="/rubik.woff2" as="font" type="font/woff2" crossorigin />
|
|
28
|
-
<link rel="stylesheet" type="text/css" href="/index.css?v=
|
|
28
|
+
<link rel="stylesheet" type="text/css" href="/index.css?v=1768878465145" />
|
|
29
29
|
<script>
|
|
30
30
|
window.PARTICLES_PATH = '/particles-4YQR4CFO.js'
|
|
31
31
|
</script>
|
|
32
32
|
</head>
|
|
33
33
|
<body>
|
|
34
34
|
<div id="root"></div>
|
|
35
|
-
<script src="/env.js?v=
|
|
35
|
+
<script src="/env.js?v=1768878465145"></script>
|
|
36
36
|
<script src="/admin-EJMJPJ7M.js" type="module"></script>
|
|
37
37
|
</body>
|
|
38
38
|
</html>
|
package/build/public/index.html
CHANGED
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
27
27
|
<!-- <link rel='icon' href='/favicon.ico' /> -->
|
|
28
28
|
<link rel="preload" href="/rubik.woff2" as="font" type="font/woff2" crossorigin />
|
|
29
|
-
<link rel="stylesheet" type="text/css" href="/index.css?v=
|
|
29
|
+
<link rel="stylesheet" type="text/css" href="/index.css?v=1768878465144" />
|
|
30
30
|
<script>
|
|
31
31
|
window.PARTICLES_PATH = '/particles-4YQR4CFO.js'
|
|
32
32
|
</script>
|
|
33
33
|
</head>
|
|
34
34
|
<body>
|
|
35
35
|
<div id="root"></div>
|
|
36
|
-
<script src="/env.js?v=
|
|
36
|
+
<script src="/env.js?v=1768878465144"></script>
|
|
37
37
|
<script src="/index-RJRKEY6V.js" type="module"></script>
|
|
38
38
|
</body>
|
|
39
39
|
</html>
|