@auraindustry/aurajs 0.1.1 → 0.1.5

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.
Files changed (144) hide show
  1. package/README.md +7 -0
  2. package/benchmarks/perf-thresholds.json +27 -0
  3. package/package.json +6 -1
  4. package/src/ai-guidance.mjs +302 -0
  5. package/src/asset-pack.mjs +2 -1
  6. package/src/authored-project.mjs +498 -2
  7. package/src/authored-runtime.mjs +14 -0
  8. package/src/bin-integrity.mjs +33 -26
  9. package/src/build-contract/capabilities.mjs +87 -1
  10. package/src/build-contract/constants.mjs +1 -0
  11. package/src/build-contract.mjs +2 -0
  12. package/src/bundler.mjs +143 -13
  13. package/src/cli.mjs +681 -13
  14. package/src/commands/packs.mjs +741 -0
  15. package/src/commands/project-authoring.mjs +128 -1
  16. package/src/conformance/cases/app-and-ui-runtime-cases.mjs +1 -2
  17. package/src/conformance/cases/core-runtime-cases.mjs +6 -2
  18. package/src/conformance/cases/scene3d-and-media-cases.mjs +238 -0
  19. package/src/conformance/cases/systems-and-gameplay-cases.mjs +1126 -10
  20. package/src/conformance-mobile.mjs +166 -0
  21. package/src/conformance.mjs +89 -30
  22. package/src/evidence-bundle.mjs +242 -0
  23. package/src/external-package-surface.mjs +1 -1
  24. package/src/headless-test/runtime-coordinator.mjs +186 -33
  25. package/src/headless-test.mjs +2 -0
  26. package/src/helpers/2d/index.mjs +183 -0
  27. package/src/helpers/index.mjs +26 -0
  28. package/src/helpers/starter-utils/adventure-objectives.js +102 -0
  29. package/src/helpers/starter-utils/adventure-world-2d.js +221 -0
  30. package/src/helpers/starter-utils/animation-2d.js +337 -0
  31. package/src/helpers/starter-utils/animation-packaging-2d.js +203 -0
  32. package/src/helpers/starter-utils/atlas-assets-2d.js +111 -0
  33. package/src/helpers/starter-utils/autoplay-debug-2d.js +215 -0
  34. package/src/helpers/starter-utils/avatar-3d.js +404 -0
  35. package/src/helpers/starter-utils/combat-feedback-2d.js +320 -0
  36. package/src/helpers/starter-utils/combat-runtime-2d.js +290 -0
  37. package/src/helpers/starter-utils/core.js +150 -0
  38. package/src/helpers/starter-utils/dialogue-2d.js +351 -0
  39. package/src/helpers/starter-utils/enemy-archetypes-2d.js +68 -0
  40. package/src/helpers/starter-utils/index.js +26 -0
  41. package/src/helpers/starter-utils/inventory-2d.js +268 -0
  42. package/src/helpers/starter-utils/journal-2d.js +267 -0
  43. package/src/helpers/starter-utils/platformer-3d.js +132 -0
  44. package/src/helpers/starter-utils/scene-audio-2d.js +236 -0
  45. package/src/helpers/starter-utils/streamed-world-2d.js +378 -0
  46. package/src/helpers/starter-utils/tilemap-nav-2d.js +499 -0
  47. package/src/helpers/starter-utils/tilemap-world-2d.js +205 -0
  48. package/src/helpers/starter-utils/triggers.js +662 -0
  49. package/src/helpers/starter-utils/tween-2d.js +615 -0
  50. package/src/helpers/starter-utils/wave-director.js +101 -0
  51. package/src/helpers/starter-utils/world-compositor-2d.js +253 -0
  52. package/src/helpers/starter-utils/world-persistence-2d.js +180 -0
  53. package/src/mobile/android/build.mjs +606 -0
  54. package/src/mobile/android/host-artifact.mjs +280 -0
  55. package/src/mobile/ios/build.mjs +1323 -0
  56. package/src/mobile/ios/host-artifact.mjs +819 -0
  57. package/src/mobile/shared/capabilities.mjs +174 -0
  58. package/src/package-integrity.mjs +18 -4
  59. package/src/packs/catalog.mjs +259 -0
  60. package/src/perf-benchmark-runner.mjs +17 -12
  61. package/src/perf-benchmark.mjs +408 -4
  62. package/src/publish-command.mjs +434 -17
  63. package/src/publish-validation.mjs +22 -11
  64. package/src/replay-runtime.mjs +257 -0
  65. package/src/scaffold/config.mjs +2 -0
  66. package/src/scaffold/fs.mjs +8 -1
  67. package/src/scaffold/project-docs.mjs +101 -41
  68. package/src/scaffold.mjs +4 -0
  69. package/src/session-runtime.mjs +4 -3
  70. package/src/web-conformance.mjs +0 -36
  71. package/templates/create/2d/src/runtime/app.js +4 -0
  72. package/templates/create/2d-adventure/config/gameplay/adventure.config.js +9 -6
  73. package/templates/create/2d-adventure/content/gameplay/dialogue.js +85 -0
  74. package/templates/create/2d-adventure/content/gameplay/world.js +32 -36
  75. package/templates/create/2d-adventure/content/gameplay/world.tilemap.json +273 -0
  76. package/templates/create/2d-adventure/docs/design/loop.md +4 -3
  77. package/templates/create/2d-adventure/prefabs/relic.prefab.js +10 -10
  78. package/templates/create/2d-adventure/prefabs/world.prefab.js +127 -74
  79. package/templates/create/2d-adventure/scenes/gameplay.scene.js +603 -112
  80. package/templates/create/2d-adventure/src/runtime/capabilities.js +16 -0
  81. package/templates/create/2d-adventure/ui/hud.screen.js +187 -4
  82. package/templates/create/2d-adventure/ui/journal.screen.js +183 -0
  83. package/templates/create/2d-survivor/src/runtime/app.js +4 -0
  84. package/templates/create/3d/scenes/gameplay.scene.js +30 -3
  85. package/templates/create/3d/src/runtime/app.js +4 -0
  86. package/templates/create/3d/src/runtime/capabilities.js +5 -0
  87. package/templates/create/3d/src/runtime/materials.js +10 -0
  88. package/templates/create/3d-adventure/scenes/gameplay.scene.js +30 -3
  89. package/templates/create/3d-adventure/src/runtime/capabilities.js +5 -0
  90. package/templates/create/3d-adventure/src/runtime/materials.js +11 -0
  91. package/templates/create/3d-collectathon/scenes/gameplay.scene.js +30 -3
  92. package/templates/create/3d-collectathon/src/runtime/app.js +4 -0
  93. package/templates/create/3d-collectathon/src/runtime/capabilities.js +5 -0
  94. package/templates/create/3d-collectathon/src/runtime/materials.js +10 -0
  95. package/templates/create/blank/assets/splash/aurajs-gg-wordmark.webp +0 -0
  96. package/templates/create/blank/assets/splash/bg.webp +0 -0
  97. package/templates/create/blank/assets/splash/boot-loop.wav +0 -0
  98. package/templates/create/blank/assets/splash/boot-sting.wav +0 -0
  99. package/templates/create/blank/assets/splash/logo-mascot-sheet.webp +0 -0
  100. package/templates/create/blank/assets/splash/logoholo.webp +0 -0
  101. package/templates/create/blank/src/main.js +5 -1
  102. package/templates/create/blank/src/runtime/splash.js +305 -0
  103. package/templates/create/local-multiplayer/scenes/gameplay.scene.js +186 -12
  104. package/templates/create/local-multiplayer/src/runtime/capabilities.js +8 -1
  105. package/templates/create/shared/assets/splash/aurajs-gg-wordmark.webp +0 -0
  106. package/templates/create/shared/assets/splash/bg.webp +0 -0
  107. package/templates/create/shared/assets/splash/boot-loop.wav +0 -0
  108. package/templates/create/shared/assets/splash/boot-sting.wav +0 -0
  109. package/templates/create/shared/assets/splash/logo-mascot-sheet.webp +0 -0
  110. package/templates/create/shared/assets/splash/logoholo.webp +0 -0
  111. package/templates/create/shared/src/runtime/splash.js +305 -0
  112. package/templates/create/shared/src/runtime/ui-forms.js +552 -0
  113. package/templates/create/shared/src/starter-utils/adventure-world-2d.js +221 -0
  114. package/templates/create/shared/src/starter-utils/animation-packaging-2d.js +203 -0
  115. package/templates/create/shared/src/starter-utils/atlas-assets-2d.js +111 -0
  116. package/templates/create/shared/src/starter-utils/autoplay-debug-2d.js +215 -0
  117. package/templates/create/shared/src/starter-utils/combat-runtime-2d.js +290 -0
  118. package/templates/create/shared/src/starter-utils/dialogue-2d.js +351 -0
  119. package/templates/create/shared/src/starter-utils/index.js +15 -1
  120. package/templates/create/shared/src/starter-utils/inventory-2d.js +268 -0
  121. package/templates/create/shared/src/starter-utils/journal-2d.js +267 -0
  122. package/templates/create/shared/src/starter-utils/scene-audio-2d.js +236 -0
  123. package/templates/create/shared/src/starter-utils/streamed-world-2d.js +378 -0
  124. package/templates/create/shared/src/starter-utils/tilemap-nav-2d.js +499 -0
  125. package/templates/create/shared/src/starter-utils/tilemap-world-2d.js +205 -0
  126. package/templates/create/shared/src/starter-utils/world-compositor-2d.js +253 -0
  127. package/templates/create/shared/src/starter-utils/world-persistence-2d.js +180 -0
  128. package/templates/create/video-cutscene/src/runtime/app.js +4 -0
  129. package/templates/create-bin/play.js +148 -7
  130. package/templates/skills/auramaxx/SKILL.md +46 -0
  131. package/templates/skills/auramaxx/project-requirements.md +68 -0
  132. package/templates/skills/auramaxx/starter-recipes.md +104 -0
  133. package/templates/skills/auramaxx/validation-checklist.md +49 -0
  134. package/templates/starter/assets/splash/aurajs-gg-wordmark.webp +0 -0
  135. package/templates/starter/assets/splash/bg.webp +0 -0
  136. package/templates/starter/assets/splash/boot-loop.wav +0 -0
  137. package/templates/starter/assets/splash/boot-sting.wav +0 -0
  138. package/templates/starter/assets/splash/logo-mascot-sheet.webp +0 -0
  139. package/templates/starter/assets/splash/logoholo.webp +0 -0
  140. package/templates/starter/src/main.js +4 -0
  141. package/templates/starter/src/runtime/splash.js +305 -0
  142. package/templates/skills/aurajs/SKILL.md +0 -96
  143. package/templates/skills/aurajs/api-contract-3d.md +0 -7
  144. package/templates/skills/aurajs/api-contract.md +0 -7
@@ -16,15 +16,6 @@ export const DEFAULT_WEB_SMOKE_CASES = Object.freeze([
16
16
  testName: 'web loader installs browser-backed aura surface for 2d examples',
17
17
  examples: [],
18
18
  }),
19
- Object.freeze({
20
- id: 'web-supported-render-2d-proof-example',
21
- bucket: 'supported',
22
- expectation: 'supported',
23
- title: 'web-render-2d-proof runs on the committed advanced draw2d browser floor',
24
- file: DEFAULT_TEST_FILE,
25
- testName: 'web loader browser smoke: web-render-2d-proof runs on the committed advanced draw2d browser floor',
26
- examples: ['examples/web-render-2d-proof'],
27
- }),
28
19
  Object.freeze({
29
20
  id: 'web-partial-auramon-example',
30
21
  bucket: 'partial',
@@ -34,33 +25,6 @@ export const DEFAULT_WEB_SMOKE_CASES = Object.freeze([
34
25
  testName: 'web loader browser smoke: auramon runs on the supported 2d subset with input and resize evidence',
35
26
  examples: ['examples/auramon'],
36
27
  }),
37
- Object.freeze({
38
- id: 'web-supported-starter-3d-example',
39
- bucket: 'supported',
40
- expectation: 'supported',
41
- title: 'starter-3d runs on the committed browser 3d floor',
42
- file: DEFAULT_TEST_FILE,
43
- testName: 'web loader browser smoke: starter-3d runs on the committed browser 3d floor',
44
- examples: ['examples/starter-3d'],
45
- }),
46
- Object.freeze({
47
- id: 'web-unsupported-multiplayer-examples',
48
- bucket: 'unsupported',
49
- expectation: 'unsupported',
50
- title: 'multiplayer examples fail before setup with stable capability diagnostics',
51
- file: DEFAULT_TEST_FILE,
52
- testName: 'web loader browser smoke: multiplayer examples fail before setup with stable capability diagnostics',
53
- examples: ['examples/multiplayer-room-client', 'examples/multiplayer-room-host'],
54
- }),
55
- Object.freeze({
56
- id: 'web-unsupported-advanced-3d-example',
57
- bucket: 'unsupported',
58
- expectation: 'unsupported',
59
- title: 'advanced 3d examples outside the committed browser floor fail before setup with stable capability diagnostics',
60
- file: DEFAULT_TEST_FILE,
61
- testName: 'web loader browser smoke: advanced 3d examples still fail before setup with stable capability diagnostics',
62
- examples: ['examples/custom-shader-material-proof'],
63
- }),
64
28
  ]);
65
29
 
66
30
  export class WebConformanceSuiteError extends Error {
@@ -1,6 +1,7 @@
1
1
  import { createSceneRegistry } from './scene-registry.js';
2
2
  import { createProjectInspector } from './project-inspector.js';
3
3
  import { assertRuntimeCapabilities } from './capabilities.js';
4
+ import { initSplash, updateSplash, drawSplash, isSplashActive } from './splash.js';
4
5
 
5
6
  export function createApp() {
6
7
  const sceneRegistry = createSceneRegistry({
@@ -26,13 +27,16 @@ export function createApp() {
26
27
  },
27
28
  setup() {
28
29
  assertRuntimeCapabilities();
30
+ initSplash();
29
31
  activeScene()?.setup?.();
30
32
  },
31
33
  update(dt) {
34
+ if (isSplashActive()) { updateSplash(dt); return; }
32
35
  projectInspector.syncInput(globalThis.aura?.input || null);
33
36
  activeScene()?.update?.(dt);
34
37
  },
35
38
  draw() {
39
+ if (isSplashActive()) { drawSplash(); return; }
36
40
  activeScene()?.draw?.();
37
41
  projectInspector.draw({ activeSceneId });
38
42
  },
@@ -1,14 +1,17 @@
1
1
  export const ADVENTURE_CONFIG = {
2
2
  playerSize: 28,
3
- playerSpeed: 232,
4
- relicRadius: 20,
5
- beaconRadius: 42,
6
- exitPadding: 18,
3
+ playerSpeed: 216,
4
+ pickupSize: 28,
5
+ checkpointSize: 48,
6
+ gateGlowSize: 96,
7
7
  };
8
8
 
9
9
  export const ADVENTURE_TEXT = {
10
10
  started: '{{PROJECT_TITLE}} started (2D adventure template)',
11
- controls: 'Move: Arrows/WASD Interact: E or Enter Hint: H',
12
- clearedTitle: 'RUINS SURVEY COMPLETE',
11
+ controls: 'Move: Arrows/WASD Interact: E or Enter Inventory: I or Tab Journal: J Hint: H',
12
+ inventoryControls: 'Inventory: A/D or Left/Right tabs W/S or Up/Down items I or Tab closes',
13
+ journalControls: 'Journal: A/D or Left/Right sections W/S or Up/Down entries J closes',
14
+ dialogueControls: 'Dialogue: W/S or Up/Down choices E, Enter, or Space confirms',
15
+ clearedTitle: 'ARCHIVE ROUTE SECURED',
13
16
  clearedPrompt: 'Press Enter to restart the route',
14
17
  };
@@ -0,0 +1,85 @@
1
+ export const ARCHIVE_CONSOLE_DIALOGUE_ID = 'archive-console-link';
2
+
3
+ export const JOURNAL_ENTRY_IDS = Object.freeze({
4
+ routeBrief: 'route-brief',
5
+ consoleLog: 'archive-console-log',
6
+ moonGate: 'moon-gate-route',
7
+ });
8
+
9
+ export const JOURNAL_CATEGORIES = [
10
+ { id: 'route', label: 'Route' },
11
+ { id: 'intel', label: 'Archive Intel' },
12
+ ];
13
+
14
+ export const STARTING_JOURNAL_ENTRIES = [
15
+ {
16
+ id: JOURNAL_ENTRY_IDS.routeBrief,
17
+ label: 'Route Brief',
18
+ categoryId: 'route',
19
+ categoryLabel: 'Route',
20
+ description: 'Sweep the Moon Archive, recover the route note, then reopen the Moon Gate.',
21
+ detail: 'The archive console should reveal the final route once the relic anchors are back online.',
22
+ status: 'active',
23
+ badge: 'Active',
24
+ updatedAt: 'Initial route objective',
25
+ },
26
+ ];
27
+
28
+ export const ADVENTURE_DIALOGUES = [
29
+ {
30
+ id: ARCHIVE_CONSOLE_DIALOGUE_ID,
31
+ title: 'Archive Console Link',
32
+ speaker: 'Archivist Sol',
33
+ startNodeId: 'handshake',
34
+ nodes: [
35
+ {
36
+ id: 'handshake',
37
+ lines: [
38
+ 'Moon Archive relay restored. I can mark the exit route once you choose what to review.',
39
+ ],
40
+ nextNodeId: 'prompt',
41
+ },
42
+ {
43
+ id: 'prompt',
44
+ lines: [
45
+ 'Ask for the route or confirm what still blocks the gate.',
46
+ ],
47
+ choices: [
48
+ {
49
+ id: 'ask-route',
50
+ label: 'Ask for the route',
51
+ detail: 'Request the marked path through the lower gallery.',
52
+ nextNodeId: 'route',
53
+ },
54
+ {
55
+ id: 'ask-key',
56
+ label: 'Ask about the Dawn Key',
57
+ detail: 'Confirm what the Moon Gate still needs.',
58
+ nextNodeId: 'key',
59
+ },
60
+ ],
61
+ },
62
+ {
63
+ id: 'route',
64
+ lines: [
65
+ 'The final route runs south, then doubles back to the Moon Gate once the key is recovered.',
66
+ ],
67
+ nextNodeId: 'briefing',
68
+ },
69
+ {
70
+ id: 'key',
71
+ lines: [
72
+ 'The Moon Gate still listens for the Dawn Key. Recover it from the south gallery and the route will hold.',
73
+ ],
74
+ nextNodeId: 'briefing',
75
+ },
76
+ {
77
+ id: 'briefing',
78
+ lines: [
79
+ 'Route note transmitted. Check your journal and carry the Dawn Key back to the gate.',
80
+ ],
81
+ outcomeId: 'route-briefed',
82
+ },
83
+ ],
84
+ },
85
+ ];
@@ -1,46 +1,42 @@
1
- export const WORLD_BOUNDS = { x: 72, y: 72, width: 1136, height: 576 };
1
+ import WORLD_TILEMAP_SOURCE from './world.tilemap.json' with { type: 'json' };
2
2
 
3
- export const PLAYER_SPAWN = { x: 156, y: 584 };
3
+ export const WORLD_ORIGIN = { x: 128, y: 72 };
4
4
 
5
- export const WORLD_OBSTACLES = [
6
- { id: 'fallen-arch', x: 312, y: 236, w: 220, h: 40 },
7
- { id: 'mirror-pool', x: 694, y: 172, w: 164, h: 104 },
8
- { id: 'collapsed-hall', x: 530, y: 422, w: 268, h: 42 },
9
- ];
5
+ export const WORLD_TILEMAP = WORLD_TILEMAP_SOURCE;
6
+
7
+ export const WORLD_OBJECT_LAYERS = Object.freeze({
8
+ markers: 'markers',
9
+ pickups: 'pickups',
10
+ checkpoints: 'checkpoints',
11
+ props: 'props',
12
+ locks: 'locks',
13
+ scenery: 'scenery',
14
+ });
10
15
 
11
- export const RELIC_SPAWNS = [
12
- { id: 'survey-lens', label: 'Survey Lens', x: 214, y: 190, radius: 20 },
13
- { id: 'signal-reel', label: 'Signal Reel', x: 546, y: 152, radius: 20 },
14
- { id: 'chorus-map', label: 'Chorus Map', x: 930, y: 352, radius: 20 },
15
- { id: 'dawn-key', label: 'Dawn Key', x: 792, y: 548, radius: 20 },
16
+ export const INVENTORY_CATEGORIES = [
17
+ { id: 'relics', label: 'Relics' },
18
+ { id: 'keys', label: 'Access Keys' },
19
+ { id: 'field', label: 'Field Notes' },
16
20
  ];
17
21
 
18
- export const BEACON_SITES = [
19
- {
20
- id: 'north-brazier',
21
- label: 'North Brazier',
22
- x: 246,
23
- y: 150,
24
- size: 34,
25
- radius: 42,
26
- requiredRelics: 1,
27
- },
22
+ export const STARTING_INVENTORY_ITEMS = [
28
23
  {
29
- id: 'east-brazier',
30
- label: 'East Brazier',
31
- x: 1034,
32
- y: 276,
33
- size: 34,
34
- radius: 42,
35
- requiredRelics: 3,
24
+ id: 'route-brief',
25
+ label: 'Route Brief',
26
+ categoryId: 'field',
27
+ categoryLabel: 'Field Notes',
28
+ quantity: 1,
29
+ badge: 'BRIEF',
30
+ description: 'Survey the Moon Archive and restore the exit route.',
31
+ detail: 'Recover three relics, inspect the archive console, then use the Dawn Key on the Moon Gate.',
36
32
  },
37
33
  ];
38
34
 
39
- export const EXIT_GATE = {
40
- id: 'moon-gate',
41
- label: 'Moon Gate',
42
- x: 1028,
43
- y: 526,
44
- w: 118,
45
- h: 88,
35
+ export const WORLD_TEXT = {
36
+ zoneLabel: 'Moon Archive',
37
+ objective: 'Recover the relics, inspect the archive console, and leave through the Moon Gate.',
38
+ inventoryHint: 'Inventory stays on the HUD while the journal and dialogue proof move through the overlay screen lane.',
39
+ journalHint: 'Journal tracks route progress and archive intel through one shared starter-owned log surface.',
40
+ consoleNoteTitle: 'Archive Console Log',
41
+ consoleNoteDetail: 'The route seal listens for the Dawn Key. The relic anchors simply restore power to the archive floor.',
46
42
  };
@@ -0,0 +1,273 @@
1
+ {
2
+ "width": 16,
3
+ "height": 9,
4
+ "tilewidth": 64,
5
+ "tileheight": 64,
6
+ "solidLayerNames": [
7
+ "collision"
8
+ ],
9
+ "layers": [
10
+ {
11
+ "name": "ground",
12
+ "type": "tilelayer",
13
+ "width": 16,
14
+ "height": 9,
15
+ "data": [
16
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
17
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
18
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
19
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
20
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
21
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
23
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
24
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
25
+ ]
26
+ },
27
+ {
28
+ "name": "collision",
29
+ "type": "tilelayer",
30
+ "width": 16,
31
+ "height": 9,
32
+ "data": [
33
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
34
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
35
+ 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
36
+ 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,
37
+ 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1,
38
+ 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1,
39
+ 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1,
40
+ 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
41
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
42
+ ]
43
+ },
44
+ {
45
+ "name": "markers",
46
+ "type": "objectgroup",
47
+ "objects": [
48
+ {
49
+ "id": 1,
50
+ "name": "player-start",
51
+ "type": "spawn",
52
+ "x": 128,
53
+ "y": 128,
54
+ "point": true
55
+ },
56
+ {
57
+ "id": 2,
58
+ "name": "camp-west",
59
+ "type": "spawn",
60
+ "x": 320,
61
+ "y": 448,
62
+ "point": true
63
+ }
64
+ ]
65
+ },
66
+ {
67
+ "name": "pickups",
68
+ "type": "objectgroup",
69
+ "objects": [
70
+ {
71
+ "id": 101,
72
+ "name": "Survey Lens",
73
+ "type": "pickup",
74
+ "x": 168,
75
+ "y": 168,
76
+ "width": 28,
77
+ "height": 28,
78
+ "properties": {
79
+ "promptText": "Press E to secure the Survey Lens",
80
+ "grantItemId": "survey-lens",
81
+ "grantCategoryId": "relics",
82
+ "grantCategoryLabel": "Relics",
83
+ "grantDescription": "Calibrates the archive's survey route.",
84
+ "grantDetail": "The brass housing still hums with lunar static.",
85
+ "grantBadge": "RELIC"
86
+ }
87
+ },
88
+ {
89
+ "id": 102,
90
+ "name": "Signal Reel",
91
+ "type": "pickup",
92
+ "x": 456,
93
+ "y": 152,
94
+ "width": 28,
95
+ "height": 28,
96
+ "properties": {
97
+ "promptText": "Press E to pocket the Signal Reel",
98
+ "grantItemId": "signal-reel",
99
+ "grantCategoryId": "relics",
100
+ "grantCategoryLabel": "Relics",
101
+ "grantDescription": "Restores the relay sequence for the east hall.",
102
+ "grantDetail": "Stamped with route marks from the first survey team.",
103
+ "grantBadge": "RELIC"
104
+ }
105
+ },
106
+ {
107
+ "id": 103,
108
+ "name": "Chorus Map",
109
+ "type": "pickup",
110
+ "x": 760,
111
+ "y": 344,
112
+ "width": 28,
113
+ "height": 28,
114
+ "properties": {
115
+ "promptText": "Press E to collect the Chorus Map",
116
+ "grantItemId": "chorus-map",
117
+ "grantCategoryId": "relics",
118
+ "grantCategoryLabel": "Relics",
119
+ "grantDescription": "Pins the resonant floor and old service ducts.",
120
+ "grantDetail": "Enough of it survived to restore the final route.",
121
+ "grantBadge": "RELIC"
122
+ }
123
+ },
124
+ {
125
+ "id": 104,
126
+ "name": "Dawn Key",
127
+ "type": "pickup",
128
+ "x": 888,
129
+ "y": 456,
130
+ "width": 28,
131
+ "height": 28,
132
+ "properties": {
133
+ "promptText": "Press E to recover the Dawn Key",
134
+ "grantItemId": "dawn-key",
135
+ "grantCategoryId": "keys",
136
+ "grantCategoryLabel": "Access Keys",
137
+ "grantDescription": "Still accepted by the Moon Gate lock.",
138
+ "grantDetail": "The key teeth match the seal at the archive exit.",
139
+ "grantBadge": "KEY"
140
+ }
141
+ }
142
+ ]
143
+ },
144
+ {
145
+ "name": "checkpoints",
146
+ "type": "objectgroup",
147
+ "objects": [
148
+ {
149
+ "id": 201,
150
+ "name": "Camp Lantern",
151
+ "type": "checkpoint",
152
+ "x": 288,
153
+ "y": 416,
154
+ "width": 48,
155
+ "height": 48,
156
+ "properties": {
157
+ "promptText": "Press E to mark the west camp checkpoint",
158
+ "checkpointId": "camp-west"
159
+ }
160
+ }
161
+ ]
162
+ },
163
+ {
164
+ "name": "props",
165
+ "type": "objectgroup",
166
+ "objects": [
167
+ {
168
+ "id": 301,
169
+ "name": "Archive Console",
170
+ "type": "prop",
171
+ "x": 616,
172
+ "y": 192,
173
+ "width": 56,
174
+ "height": 40,
175
+ "properties": {
176
+ "promptText": "Press E to inspect the archive console"
177
+ }
178
+ }
179
+ ]
180
+ },
181
+ {
182
+ "name": "locks",
183
+ "type": "objectgroup",
184
+ "objects": [
185
+ {
186
+ "id": 401,
187
+ "name": "Moon Gate",
188
+ "type": "lock",
189
+ "x": 896,
190
+ "y": 448,
191
+ "width": 96,
192
+ "height": 88,
193
+ "properties": {
194
+ "promptText": "Press E to unlock the Moon Gate",
195
+ "lockedPromptText": "Recover the Dawn Key before opening the Moon Gate",
196
+ "openedPromptText": "The Moon Gate is online",
197
+ "requiredItemId": "dawn-key",
198
+ "requiredQuantity": 1,
199
+ "consumeRequiredItem": false
200
+ }
201
+ }
202
+ ]
203
+ },
204
+ {
205
+ "name": "scenery",
206
+ "type": "objectgroup",
207
+ "objects": [
208
+ {
209
+ "id": 501,
210
+ "name": "Central Court",
211
+ "type": "plaza",
212
+ "x": 64,
213
+ "y": 64,
214
+ "width": 896,
215
+ "height": 448,
216
+ "properties": {
217
+ "fill": "#14211b",
218
+ "border": "#294436"
219
+ }
220
+ },
221
+ {
222
+ "id": 502,
223
+ "name": "Mirror Pool",
224
+ "type": "pool",
225
+ "x": 704,
226
+ "y": 128,
227
+ "width": 160,
228
+ "height": 96,
229
+ "properties": {
230
+ "fill": "#173949",
231
+ "border": "#3a728c"
232
+ }
233
+ },
234
+ {
235
+ "id": 503,
236
+ "name": "Collapsed Hall",
237
+ "type": "ruin",
238
+ "x": 256,
239
+ "y": 224,
240
+ "width": 192,
241
+ "height": 48,
242
+ "properties": {
243
+ "fill": "#28302d",
244
+ "border": "#4c5b57"
245
+ }
246
+ },
247
+ {
248
+ "id": 504,
249
+ "name": "South Gallery",
250
+ "type": "ruin",
251
+ "x": 512,
252
+ "y": 384,
253
+ "width": 224,
254
+ "height": 48,
255
+ "properties": {
256
+ "fill": "#242a29",
257
+ "border": "#48504c"
258
+ }
259
+ }
260
+ ]
261
+ }
262
+ ],
263
+ "tilesets": [
264
+ {
265
+ "firstgid": 1,
266
+ "image": "ruins-placeholder.png",
267
+ "tilewidth": 64,
268
+ "tileheight": 64,
269
+ "tilecount": 1,
270
+ "columns": 1
271
+ }
272
+ ]
273
+ }
@@ -1,5 +1,6 @@
1
1
  # 2D Adventure Loop
2
2
 
3
- 1. Sweep the ruin, collect four relics, and light the route beacons.
4
- 1. Keep tuning knobs in `config/gameplay/adventure.config.js` and authored room nouns in `content/gameplay/world.js`.
5
- 1. Extend the loop by adding more relic families, gate rules, or room variants before introducing heavier systems.
3
+ 1. Sweep the Moon Archive, recover the route relics, inspect the archive console, and leave through the Moon Gate.
4
+ 1. Keep authored room nouns in `content/gameplay/world.js`, `content/gameplay/world.tilemap.json`, and `content/gameplay/dialogue.js`, then keep starter-specific render/collision wrappers in `prefabs/world.prefab.js`.
5
+ 1. Use the archive console beat to prove the shared dialogue helper lane plus the shared journal/log owner before widening into heavier narrative or quest systems.
6
+ 1. Extend the loop by adding more object layers, item categories, checkpoints, or lock rules once the dialogue and journal proof still fits in one readable starter scene.
@@ -6,28 +6,28 @@ const relicPrefab = {
6
6
  kind: 'pickup2d',
7
7
  },
8
8
  hooks: {},
9
- notes: ['Treat relics as authored pickups first, then grow them into richer quest nouns later.'],
9
+ notes: ['Treat relics as tilemap-authored pickups first, then grow them into richer quest nouns later.'],
10
10
  };
11
11
 
12
12
  export function createRelicPrefab() {
13
13
  return relicPrefab;
14
14
  }
15
15
 
16
- export function drawAdventureRelics(relics, elapsed = 0) {
17
- for (const relic of relics) {
18
- if (relic.collected) continue;
19
- const pulse = 0.88 + (Math.sin((elapsed * 3.4) + relic.x) * 0.12);
20
- const size = relic.radius * pulse;
16
+ export function drawAdventureRelics(interactables = [], elapsed = 0) {
17
+ for (const entry of interactables) {
18
+ if (!entry || entry.kind !== 'pickup' || entry.collected === true) continue;
19
+ const pulse = 0.88 + (Math.sin((elapsed * 3.4) + entry.x) * 0.12);
20
+ const size = Math.max(12, (Math.max(Number(entry.w) || 0, Number(entry.h) || 0) * 0.5) * pulse);
21
21
  aura.draw2d.rect(
22
- relic.x - size,
23
- relic.y - size,
22
+ entry.x + ((entry.w - (size * 2)) * 0.5),
23
+ entry.y + ((entry.h - (size * 2)) * 0.5),
24
24
  size * 2,
25
25
  size * 2,
26
26
  aura.rgb(0.98, 0.9, 0.42),
27
27
  );
28
28
  aura.draw2d.rect(
29
- relic.x - (size * 0.42),
30
- relic.y - (size * 0.42),
29
+ entry.x + ((entry.w - (size * 0.84)) * 0.5),
30
+ entry.y + ((entry.h - (size * 0.84)) * 0.5),
31
31
  size * 0.84,
32
32
  size * 0.84,
33
33
  aura.rgb(0.18, 0.12, 0.04),