gamedev 0.0.3-alpha.0 → 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.
@@ -22,7 +22,7 @@ export class WorldManifest {
22
22
  if (parsed.formatVersion !== 2) {
23
23
  throw new Error(
24
24
  'Invalid world.json format version. Expected formatVersion 2.\n' +
25
- 'Run "hyperfy world export" to regenerate world.json (formatVersion 2).'
25
+ 'Run "gamedev world export" to regenerate world.json (formatVersion 2).'
26
26
  )
27
27
  }
28
28
 
package/app-server/cli.js CHANGED
@@ -17,7 +17,7 @@ async function main() {
17
17
  console.error(`❌ ${err?.message || err}`)
18
18
  process.exit(1)
19
19
  }
20
- const exitCode = await runAppCommand({ command, args, helpPrefix: 'hyperfy' })
20
+ const exitCode = await runAppCommand({ command, args, helpPrefix: 'gamedev apps' })
21
21
  process.exit(exitCode)
22
22
  }
23
23
 
@@ -246,7 +246,7 @@ export class HyperfyCLI {
246
246
  const blueprints = listLocalBlueprints(this.appsDir)
247
247
  if (blueprints.length === 0) {
248
248
  console.log(`📝 No local blueprints found in ${this.appsDir}`)
249
- console.log(`💡 Run "hyperfy world export" to pull blueprints from the world.`)
249
+ console.log(`💡 Run "gamedev world export" to pull blueprints from the world.`)
250
250
  console.log(` Use --include-built-scripts if you need script code locally.`)
251
251
  return
252
252
  }
@@ -399,7 +399,7 @@ app.on("update", (delta) => {
399
399
  console.log(`✅ Successfully created app in world: ${appName}`)
400
400
  console.log(` • Blueprint: ${blueprintId}`)
401
401
  console.log(` • Entity: ${entityId}`)
402
- console.log(`💡 Run "hyperfy world export" to sync into ${this.appsDir}.`)
402
+ console.log(`💡 Run "gamedev world export" to sync into ${this.appsDir}.`)
403
403
  console.log(` Use --include-built-scripts if you need script code locally.`)
404
404
  } catch (error) {
405
405
  console.error(`❌ Error creating app:`, error?.message || error)
@@ -563,7 +563,7 @@ app.on("update", (delta) => {
563
563
  console.log(`✅ Script validation passed for ${appName}`)
564
564
  console.log(`🔗 Hash: ${localHash}`)
565
565
  } else {
566
- console.log(`💡 Run 'hyperfy apps deploy ${appName}' (or save the file with app-server running)`)
566
+ console.log(`💡 Run 'gamedev apps deploy ${appName}' (or save the file with app-server running)`)
567
567
  }
568
568
  } catch (error) {
569
569
  console.error(`❌ Error validating app:`, error?.message || error)
@@ -677,9 +677,9 @@ app.on("update", (delta) => {
677
677
  }
678
678
  }
679
679
 
680
- showHelp({ commandPrefix = 'hyperfy apps' } = {}) {
680
+ showHelp({ commandPrefix = 'gamedev apps' } = {}) {
681
681
  console.log(`
682
- 🚀 Hyperfy CLI (direct /admin mode)
682
+ 🚀 Gamedev CLI (direct /admin mode)
683
683
 
684
684
  Usage:
685
685
  ${commandPrefix} <command> [options]
@@ -697,7 +697,7 @@ Commands:
697
697
  reset [--force] Delete local apps/assets/world.json
698
698
  status Show /admin snapshot summary
699
699
  help Show this help
700
- --target <name> Use .hyperfy/targets.json entry for WORLD_URL/WORLD_ID/ADMIN_CODE/DEPLOY_CODE
700
+ --target <name> Use .lobby/targets.json entry for WORLD_URL/WORLD_ID/ADMIN_CODE/DEPLOY_CODE
701
701
 
702
702
  Options:
703
703
  --dry-run, -n Show deploy plan without applying changes
@@ -739,7 +739,7 @@ export async function runAppCommand({ command, args = [], rootDir = process.cwd(
739
739
  }
740
740
  }
741
741
  const cli = new HyperfyCLI({ rootDir })
742
- const commandPrefix = helpPrefix || 'hyperfy apps'
742
+ const commandPrefix = helpPrefix || 'gamedev apps'
743
743
  let exitCode = 0
744
744
 
745
745
  switch (command) {
@@ -558,7 +558,7 @@ export class DirectAppServer {
558
558
  } else if (!hasWorldFile && hasApps) {
559
559
  throw new Error(
560
560
  'world.json missing; cannot safely apply exact world layout. ' +
561
- 'Run "hyperfy world export" to generate it from the world, or create world.json to seed a new world.'
561
+ 'Run "gamedev world export" to generate it from the world, or create world.json to seed a new world.'
562
562
  )
563
563
  } else {
564
564
  const manifest = this.manifest.read()
@@ -586,7 +586,7 @@ export class DirectAppServer {
586
586
  const err = new Error(
587
587
  'Local project is empty and this world already has content. ' +
588
588
  'Script code is not downloaded by default. ' +
589
- 'Run "hyperfy world export --include-built-scripts" to scaffold from the world.'
589
+ 'Run "gamedev world export --include-built-scripts" to scaffold from the world.'
590
590
  )
591
591
  err.code = 'empty_project_requires_export'
592
592
  throw err
@@ -657,7 +657,7 @@ export class DirectAppServer {
657
657
  async importWorldFromDisk() {
658
658
  const manifest = this.manifest.read()
659
659
  if (!manifest) {
660
- throw new Error('world.json missing. Run "hyperfy world export" to generate it first.')
660
+ throw new Error('world.json missing. Run "gamedev world export" to generate it first.')
661
661
  }
662
662
  const errors = this.manifest.validate(manifest)
663
663
  if (errors.length) {
@@ -12,7 +12,7 @@ const CLAUDE_SKILL_TEMPLATE = path.join(
12
12
  TEMPLATES_DIR,
13
13
  'claude',
14
14
  'skills',
15
- 'lobby-app-scripting',
15
+ 'hyperfy-app-scripting',
16
16
  'SKILL.md'
17
17
  )
18
18
 
@@ -51,7 +51,7 @@ const DEFAULT_TSCONFIG = {
51
51
  skipLibCheck: true,
52
52
  types: ['gamedev/app-runtime'],
53
53
  },
54
- include: ['apps/**/*', 'lobby.app-runtime.d.ts'],
54
+ include: ['apps/**/*', 'hyperfy.app-runtime.d.ts'],
55
55
  }
56
56
 
57
57
  function normalizePackageName(name, fallback) {
@@ -100,7 +100,7 @@ function resolveSdkVersion() {
100
100
  }
101
101
 
102
102
  function buildEnvExample() {
103
- return `# Lobby project environment (example)
103
+ return `# Hyperfy project environment (example)
104
104
  # Run "gamedev dev" to generate a local .env automatically.
105
105
  WORLD_URL=http://localhost:5000
106
106
  WORLD_ID=local-your-world-id
@@ -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) {
@@ -256,7 +308,7 @@ export function scaffoldBaseProject({
256
308
  report,
257
309
  })
258
310
 
259
- writeFileWithPolicy(path.join(rootDir, 'lobby.app-runtime.d.ts'), APP_RUNTIME_TYPES_REFERENCE, {
311
+ writeFileWithPolicy(path.join(rootDir, 'hyperfy.app-runtime.d.ts'), APP_RUNTIME_TYPES_REFERENCE, {
260
312
  force,
261
313
  writeFile,
262
314
  report,
@@ -266,7 +318,7 @@ export function scaffoldBaseProject({
266
318
  const skillContent = readText(CLAUDE_SKILL_TEMPLATE)
267
319
  if (skillContent != null) {
268
320
  writeFileWithPolicy(
269
- path.join(rootDir, '.claude', 'skills', 'lobby-app-scripting', 'SKILL.md'),
321
+ path.join(rootDir, '.claude', 'skills', 'hyperfy-app-scripting', 'SKILL.md'),
270
322
  skillContent.endsWith('\n') ? skillContent : `${skillContent}\n`,
271
323
  { force, writeFile, report }
272
324
  )
@@ -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
- writeFileWithPolicy(blueprintPath, JSON.stringify(template.config, null, 2) + '\n', {
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
 
@@ -1,7 +1,7 @@
1
1
  import fs from 'fs'
2
2
  import path from 'path'
3
3
 
4
- const TARGETS_FILE = path.join('.hyperfy', 'targets.json')
4
+ const TARGETS_FILE = path.join('.lobby', 'targets.json')
5
5
 
6
6
  export function parseTargetArgs(args = []) {
7
7
  let target = null
@@ -16,7 +16,7 @@ description: Hyperfy world-project app scripting workflow and constraints. Use w
16
16
  1. Identify the target app(s) and update the entry script at `apps/<AppName>/index.ts`.
17
17
  2. Update blueprint defaults in `apps/<AppName>/*.json` (model, props, flags).
18
18
  3. Keep per-instance overrides in `world.json`.
19
- 4. Use `hyperfy dev` for continuous sync; use `hyperfy apps build --all` and `hyperfy apps deploy <app>` for explicit deploys.
19
+ 4. Use `gamedev dev` for continuous sync; use `gamedev apps build --all` and `gamedev apps deploy <app>` for explicit deploys.
20
20
 
21
21
  ## Runtime Constraints
22
22
 
@@ -38,4 +38,4 @@ description: Hyperfy world-project app scripting workflow and constraints. Use w
38
38
  ## Guardrails
39
39
 
40
40
  - Do not edit `dist/` (build output).
41
- - Do not edit `.hyperfy/*` except `targets.json` (local only).
41
+ - Do not edit `.lobby/*` except `targets.json` (local only).
package/bin/gamedev.mjs CHANGED
@@ -7,7 +7,7 @@ import { fileURLToPath } from 'url'
7
7
  import { spawn } from 'child_process'
8
8
  import { customAlphabet } from 'nanoid'
9
9
 
10
- import { HyperfyCLI, runAppCommand } from '../app-server/commands.js'
10
+ import { runAppCommand } from '../app-server/commands.js'
11
11
  import { DirectAppServer } from '../app-server/direct.js'
12
12
  import { scaffoldBaseProject, scaffoldBuiltins, writeManifest } from '../app-server/scaffold.js'
13
13
  import { applyTargetEnv, parseTargetArgs, resolveTarget, readTargets } from '../app-server/targets.js'
@@ -59,7 +59,7 @@ function writeDotEnv(filePath, content) {
59
59
  fs.writeFileSync(filePath, content.endsWith('\n') ? content : `${content}\n`, 'utf8')
60
60
  }
61
61
 
62
- const TARGETS_FILE = path.join('.hyperfy', 'targets.json')
62
+ const TARGETS_FILE = path.join('.lobby', 'targets.json')
63
63
 
64
64
  function writeTargetsFile(targets, rootDir = projectDir) {
65
65
  const filePath = path.join(rootDir, TARGETS_FILE)
@@ -68,13 +68,6 @@ function writeTargetsFile(targets, rootDir = projectDir) {
68
68
  return filePath
69
69
  }
70
70
 
71
- function isProjectEmpty(dirPath) {
72
- const ignore = new Set(['.git', '.DS_Store'])
73
- if (!fs.existsSync(dirPath)) return true
74
- const entries = fs.readdirSync(dirPath, { withFileTypes: true })
75
- return entries.every(entry => ignore.has(entry.name))
76
- }
77
-
78
71
  function generateAdminCode() {
79
72
  return crypto.randomBytes(16).toString('base64url')
80
73
  }
@@ -161,7 +154,7 @@ function isLocalWorld({ worldUrl }) {
161
154
  }
162
155
 
163
156
  function getWorldDir(worldId) {
164
- return path.join(projectDir, '.hyperfy', worldId)
157
+ return path.join(projectDir, '.lobby', worldId)
165
158
  }
166
159
 
167
160
  function hasKey(env, key) {
@@ -282,15 +275,6 @@ function validateLocalEnv(env, derived) {
282
275
  return issues
283
276
  }
284
277
 
285
- async function confirmAction(prompt) {
286
- if (!process.stdin.isTTY) return false
287
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
288
- const answer = await new Promise(resolve => rl.question(prompt, resolve))
289
- rl.close()
290
- const normalized = (answer || '').trim().toLowerCase()
291
- return normalized === 'y' || normalized === 'yes'
292
- }
293
-
294
278
  async function promptValue(prompt) {
295
279
  if (!process.stdin.isTTY) return null
296
280
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
@@ -302,12 +286,6 @@ async function promptValue(prompt) {
302
286
 
303
287
  function ensureEnvForStart() {
304
288
  if (!fs.existsSync(envPath)) {
305
- if (!isProjectEmpty(projectDir)) {
306
- console.error('Error: Missing .env in a non-empty project.')
307
- console.error('Hint: Create a .env with WORLD_URL, WORLD_ID, ADMIN_CODE, and world server settings.')
308
- return { ok: false }
309
- }
310
-
311
289
  const worldId = `local-${uuid()}`
312
290
  const adminCode = generateAdminCode()
313
291
  const jwtSecret = generateJwtSecret()
@@ -469,10 +447,10 @@ async function startCommand(args = []) {
469
447
 
470
448
  function printInitHelp() {
471
449
  console.log(`
472
- Hyperfy Init
450
+ Gamedev Init
473
451
 
474
452
  Usage:
475
- hyperfy init [options]
453
+ gamedev init [options]
476
454
 
477
455
  Options:
478
456
  --name <package> Package name (defaults to folder name)
@@ -563,12 +541,15 @@ async function initCommand(args = []) {
563
541
  console.log(`↪️ Skipped ${skipped.length} existing file(s)`)
564
542
  }
565
543
 
544
+ const envResult = ensureEnvForStart()
545
+ if (!envResult.ok) return 1
546
+
566
547
  return 0
567
548
  }
568
549
 
569
550
  async function appsCommand(args) {
570
551
  if (!args.length || ['help', '--help', '-h'].includes(args[0])) {
571
- await runAppCommand({ command: 'help', args: [], rootDir: projectDir, helpPrefix: 'hyperfy apps' })
552
+ await runAppCommand({ command: 'help', args: [], rootDir: projectDir, helpPrefix: 'gamedev apps' })
572
553
  return 0
573
554
  }
574
555
 
@@ -589,7 +570,7 @@ async function appsCommand(args) {
589
570
  const env = readDotEnv(envPath)
590
571
  if (env) applyEnvToProcess(env)
591
572
 
592
- return runAppCommand({ command, args: commandArgs, rootDir: projectDir, helpPrefix: 'hyperfy apps' })
573
+ return runAppCommand({ command, args: commandArgs, rootDir: projectDir, helpPrefix: 'gamedev apps' })
593
574
  }
594
575
 
595
576
  async function connectAdminServer({ worldUrl, adminCode, rootDir }) {
@@ -610,53 +591,6 @@ async function connectAdminServer({ worldUrl, adminCode, rootDir }) {
610
591
  }
611
592
  }
612
593
 
613
- async function projectCommand(args) {
614
- if (!args.length || ['help', '--help', '-h'].includes(args[0])) {
615
- printHelp()
616
- return 0
617
- }
618
-
619
- if (args[0] !== 'reset') {
620
- console.error(`Error: Unknown project command: ${args[0]}`)
621
- printHelp()
622
- return 1
623
- }
624
-
625
- const force = args.includes('--force') || args.includes('-f')
626
- const cli = new HyperfyCLI({ rootDir: projectDir })
627
- await cli.reset({ force })
628
- return 0
629
- }
630
-
631
- async function worldsCommand(args) {
632
- if (!args.length || ['help', '--help', '-h'].includes(args[0]) || args[0] === 'list') {
633
- const root = path.join(projectDir, '.hyperfy')
634
- if (!fs.existsSync(root)) {
635
- console.log('Worlds: No local worlds found.')
636
- return 0
637
- }
638
- const entries = fs
639
- .readdirSync(root, { withFileTypes: true })
640
- .filter(entry => entry.isDirectory())
641
- .map(entry => entry.name)
642
-
643
- if (!entries.length) {
644
- console.log('Worlds: No local worlds found.')
645
- return 0
646
- }
647
-
648
- console.log('Worlds: Local worlds:')
649
- for (const entry of entries) {
650
- console.log(` - ${entry}`)
651
- }
652
- return 0
653
- }
654
-
655
- console.error(`Error: Unknown worlds command: ${args[0]}`)
656
- printHelp()
657
- return 1
658
- }
659
-
660
594
  async function worldCommand(args) {
661
595
  if (!args.length || ['help', '--help', '-h'].includes(args[0])) {
662
596
  printHelp()
@@ -665,7 +599,7 @@ async function worldCommand(args) {
665
599
 
666
600
  const action = args[0]
667
601
 
668
- if (action === 'export' || action === 'import' || action === 'wipe') {
602
+ if (action === 'export' || action === 'import') {
669
603
  const env = readDotEnv(envPath)
670
604
  if (!env) {
671
605
  console.error('Error: Missing .env in this project.')
@@ -680,37 +614,6 @@ async function worldCommand(args) {
680
614
  return 1
681
615
  }
682
616
 
683
- if (action === 'wipe') {
684
- if (!isLocalWorld({ worldUrl })) {
685
- console.error('Error: WORLD_URL does not indicate a local world. Refusing to wipe.')
686
- return 1
687
- }
688
-
689
- const worldDir = getWorldDir(worldId)
690
- if (!fs.existsSync(worldDir)) {
691
- console.log(`Worlds: No local world found at ${worldDir}`)
692
- return 0
693
- }
694
-
695
- const force = args.includes('--force') || args.includes('-f')
696
- if (!force) {
697
- const ok = await confirmAction(`Delete local world data at ${worldDir}? (y/N): `)
698
- if (!ok) {
699
- console.log('World wipe cancelled')
700
- return 1
701
- }
702
- }
703
-
704
- try {
705
- fs.rmSync(worldDir, { recursive: true, force: true })
706
- console.log(`Deleted ${worldDir}`)
707
- return 0
708
- } catch (error) {
709
- console.error(`Error: Failed to delete ${worldDir}`, error?.message || error)
710
- return 1
711
- }
712
- }
713
-
714
617
  let server
715
618
  try {
716
619
  server = await connectAdminServer({ worldUrl, adminCode: env.ADMIN_CODE, rootDir: projectDir })
@@ -740,10 +643,10 @@ async function worldCommand(args) {
740
643
 
741
644
  function printFlyHelp() {
742
645
  console.log(`
743
- Hyperfy Fly
646
+ Gamedev Fly
744
647
 
745
648
  Usage:
746
- hyperfy fly <command> [options]
649
+ gamedev fly <command> [options]
747
650
 
748
651
  Commands:
749
652
  init Generate fly.toml and optional GitHub workflow
@@ -755,11 +658,11 @@ Init options:
755
658
  --region <code> Fly region (default: ams)
756
659
  --persist Enable volume mount + SAVE_INTERVAL
757
660
  --world-id <id> WORLD_ID override (default: fly-<app>)
758
- --target <name> Update .hyperfy/targets.json with worldUrl/worldId
661
+ --target <name> Update .lobby/targets.json with worldUrl/worldId
759
662
  --force, -f Overwrite existing fly.toml / workflow
760
663
 
761
664
  Secrets options:
762
- --target <name> Update .hyperfy/targets.json with generated codes
665
+ --target <name> Update .lobby/targets.json with generated codes
763
666
  --no-deploy-code Skip DEPLOY_CODE generation
764
667
  --force, -f Overwrite existing target codes
765
668
  `)
@@ -1067,26 +970,22 @@ async function flyCommand(args) {
1067
970
 
1068
971
  function printHelp() {
1069
972
  console.log(`
1070
- Hyperfy CLI
973
+ Gamedev CLI
1071
974
 
1072
975
  Usage:
1073
- hyperfy <command> [options]
976
+ gamedev <command> [options]
1074
977
 
1075
978
  Commands:
1076
979
  init Scaffold a new world project in the current folder
1077
- start Start the world (local or remote) + app-server sync
1078
- dev Alias for start
980
+ dev Start the world (local or remote) + app-server sync
1079
981
  apps <command> Manage apps (create, list, build, clean, deploy, update, validate, status)
1080
982
  fly <command> Fly.io deployment helpers
1081
- project reset [--force] Delete local apps/assets/world.json in this project
1082
983
  world export Export world.json + apps/assets from the world (use --include-built-scripts for scripts)
1083
984
  world import Import local apps + world.json into the world
1084
- world wipe [--force] Delete the local world runtime directory for this project
1085
- worlds list List local world directories in ./.hyperfy
1086
985
  help Show this help
1087
986
 
1088
987
  Options:
1089
- --target <name> Use .hyperfy/targets.json entry (applies to start/dev/apps)
988
+ --target <name> Use .lobby/targets.json entry (applies to dev/apps)
1090
989
  `)
1091
990
  }
1092
991
 
@@ -1096,17 +995,12 @@ async function main() {
1096
995
  switch (command) {
1097
996
  case 'init':
1098
997
  return initCommand(args)
1099
- case 'start':
1100
998
  case 'dev':
1101
999
  return startCommand(args)
1102
1000
  case 'apps':
1103
1001
  return appsCommand(args)
1104
- case 'project':
1105
- return projectCommand(args)
1106
1002
  case 'world':
1107
1003
  return worldCommand(args)
1108
- case 'worlds':
1109
- return worldsCommand(args)
1110
1004
  case 'fly':
1111
1005
  return flyCommand(args)
1112
1006
  case 'help':
@@ -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=1768870916598" />
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=1768870916598"></script>
35
+ <script src="/env.js?v=1768878465145"></script>
36
36
  <script src="/admin-EJMJPJ7M.js" type="module"></script>
37
37
  </body>
38
38
  </html>
@@ -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=1768870916558" />
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=1768870916558"></script>
36
+ <script src="/env.js?v=1768878465144"></script>
37
37
  <script src="/index-RJRKEY6V.js" type="module"></script>
38
38
  </body>
39
39
  </html>