gamedev 0.0.2-alpha.0 → 0.0.3-alpha.0

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.
@@ -12,7 +12,7 @@ const CLAUDE_SKILL_TEMPLATE = path.join(
12
12
  TEMPLATES_DIR,
13
13
  'claude',
14
14
  'skills',
15
- 'hyperfy-app-scripting',
15
+ 'lobby-app-scripting',
16
16
  'SKILL.md'
17
17
  )
18
18
 
@@ -29,9 +29,9 @@ dist/
29
29
  !.env.example
30
30
 
31
31
  # Local world state
32
- .hyperfy/*
33
- !.hyperfy/
34
- !.hyperfy/targets.example.json
32
+ .lobby/*
33
+ !.lobby/
34
+ !.lobby/targets.example.json
35
35
 
36
36
  # Claude local settings
37
37
  .claude/settings.local.json
@@ -51,12 +51,12 @@ const DEFAULT_TSCONFIG = {
51
51
  skipLibCheck: true,
52
52
  types: ['gamedev/app-runtime'],
53
53
  },
54
- include: ['apps/**/*', 'hyperfy.app-runtime.d.ts'],
54
+ include: ['apps/**/*', 'lobby.app-runtime.d.ts'],
55
55
  }
56
56
 
57
57
  function normalizePackageName(name, fallback) {
58
58
  const raw = (name || '').trim() || (fallback || '').trim()
59
- const base = raw || 'hyperfy-world'
59
+ const base = raw || 'lobby-world'
60
60
  const scopeMatch = base.startsWith('@') ? base.split('/') : null
61
61
  if (scopeMatch && scopeMatch.length === 2) {
62
62
  const scope = scopeMatch[0].toLowerCase().replace(/[^a-z0-9._-]+/g, '')
@@ -64,7 +64,7 @@ function normalizePackageName(name, fallback) {
64
64
  if (scope && pkg) return `${scope}/${pkg}`
65
65
  }
66
66
  const normalized = base.toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '')
67
- return normalized || 'hyperfy-world'
67
+ return normalized || 'lobby-world'
68
68
  }
69
69
 
70
70
  function buildPackageJson({ packageName, sdkName, sdkVersion }) {
@@ -79,8 +79,8 @@ function buildPackageJson({ packageName, sdkName, sdkVersion }) {
79
79
  private: true,
80
80
  type: 'module',
81
81
  scripts: {
82
- dev: 'hyperfy dev',
83
- build: 'hyperfy apps build --all',
82
+ dev: 'gamedev dev',
83
+ build: 'gamedev apps build --all',
84
84
  typecheck: 'tsc --noEmit',
85
85
  },
86
86
  devDependencies,
@@ -100,8 +100,8 @@ function resolveSdkVersion() {
100
100
  }
101
101
 
102
102
  function buildEnvExample() {
103
- return `# Hyperfy project environment (example)
104
- # Run "hyperfy dev" to generate a local .env automatically.
103
+ return `# Lobby project environment (example)
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
107
107
  ADMIN_CODE=your-admin-code
@@ -250,13 +250,13 @@ export function scaffoldBaseProject({
250
250
  report,
251
251
  })
252
252
 
253
- writeFileWithPolicy(path.join(rootDir, '.hyperfy', 'targets.example.json'), buildTargetsExample(), {
253
+ writeFileWithPolicy(path.join(rootDir, '.lobby', 'targets.example.json'), buildTargetsExample(), {
254
254
  force,
255
255
  writeFile,
256
256
  report,
257
257
  })
258
258
 
259
- writeFileWithPolicy(path.join(rootDir, 'hyperfy.app-runtime.d.ts'), APP_RUNTIME_TYPES_REFERENCE, {
259
+ writeFileWithPolicy(path.join(rootDir, 'lobby.app-runtime.d.ts'), APP_RUNTIME_TYPES_REFERENCE, {
260
260
  force,
261
261
  writeFile,
262
262
  report,
@@ -266,7 +266,7 @@ export function scaffoldBaseProject({
266
266
  const skillContent = readText(CLAUDE_SKILL_TEMPLATE)
267
267
  if (skillContent != null) {
268
268
  writeFileWithPolicy(
269
- path.join(rootDir, '.claude', 'skills', 'hyperfy-app-scripting', 'SKILL.md'),
269
+ path.join(rootDir, '.claude', 'skills', 'lobby-app-scripting', 'SKILL.md'),
270
270
  skillContent.endsWith('\n') ? skillContent : `${skillContent}\n`,
271
271
  { force, writeFile, report }
272
272
  )
@@ -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=1768869532415" />
28
+ <link rel="stylesheet" type="text/css" href="/index.css?v=1768870916598" />
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=1768869532415"></script>
35
+ <script src="/env.js?v=1768870916598"></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=1768869532414" />
29
+ <link rel="stylesheet" type="text/css" href="/index.css?v=1768870916558" />
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=1768869532414"></script>
36
+ <script src="/env.js?v=1768870916558"></script>
37
37
  <script src="/index-RJRKEY6V.js" type="module"></script>
38
38
  </body>
39
39
  </html>
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "gamedev",
3
- "version": "0.0.2-alpha.0",
3
+ "version": "0.0.3-alpha.0",
4
4
  "type": "module",
5
5
  "main": "index.node.js",
6
6
  "types": "index.d.ts",
7
7
  "files": [
8
8
  "build/**",
9
9
  "app-server/**",
10
+ "src/core/packets.js",
10
11
  "index.node.js",
11
12
  "index.node-client.js",
12
13
  "index.d.ts",
@@ -65,7 +66,7 @@
65
66
  "test:integration": "node --test \"test/integration/**/*.test.js\""
66
67
  },
67
68
  "bin": {
68
- "@drama.haus/hyperfy": "bin/hyperfy.mjs"
69
+ "gamedev": "bin/gamedev.mjs"
69
70
  },
70
71
  "dependencies": {
71
72
  "@aws-sdk/client-s3": "^3.859.0",
@@ -0,0 +1,78 @@
1
+ import { Packr } from 'msgpackr'
2
+
3
+ const packr = new Packr({ structuredClone: true })
4
+
5
+ // prettier-ignore
6
+ const names = [
7
+ 'snapshot',
8
+ 'command',
9
+ 'chatAdded',
10
+ 'chatCleared',
11
+ 'blueprintAdded',
12
+ 'blueprintModified',
13
+ 'entityAdded',
14
+ 'entityModified',
15
+ 'entityEvent',
16
+ 'entityRemoved',
17
+ 'playerTeleport',
18
+ 'playerPush',
19
+ 'playerSessionAvatar',
20
+ 'liveKitLevel',
21
+ 'mute',
22
+ 'settingsModified',
23
+ 'spawnModified',
24
+ 'modifyRank',
25
+ 'kick',
26
+ 'ping',
27
+ 'pong',
28
+ 'blueprintRemoved',
29
+ // admin protocol
30
+ 'adminAuth',
31
+ 'adminAuthOk',
32
+ 'adminAuthError',
33
+ 'adminCommand',
34
+ 'adminResult',
35
+ // admin player streaming
36
+ 'playerJoined',
37
+ 'playerUpdated',
38
+ 'playerLeft',
39
+ ]
40
+
41
+ const byName = {}
42
+ const byId = {}
43
+
44
+ let ids = -1
45
+
46
+ for (const name of names) {
47
+ const id = ++ids
48
+ const info = {
49
+ id,
50
+ name,
51
+ method: `on${capitalize(name)}`, // eg 'connect' -> 'onConnect'
52
+ }
53
+ byName[name] = info
54
+ byId[id] = info
55
+ }
56
+
57
+ function capitalize(str) {
58
+ return str.charAt(0).toUpperCase() + str.slice(1)
59
+ }
60
+
61
+ export function writePacket(name, data) {
62
+ const info = byName[name]
63
+ if (!info) throw new Error(`writePacket failed: ${name} (name not found)`)
64
+ const packet = packr.pack([info.id, data])
65
+ return packet
66
+ }
67
+
68
+ export function readPacket(packet) {
69
+ try {
70
+ const [id, data] = packr.unpack(packet)
71
+ const info = byId[id]
72
+ if (!info) throw new Error(`readPacket failed: ${id} (id not found)`)
73
+ return [info.method, data]
74
+ } catch (err) {
75
+ console.error(err)
76
+ return []
77
+ }
78
+ }
File without changes