@pix3/cli 1.6.0 → 1.6.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.
Files changed (126) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +788 -754
  3. package/dist/index.js +208 -203
  4. package/dist/runtime-types.json +1 -1
  5. package/dist/smoke/prebuilt/{chunk-J2SJVMDO.mjs → chunk-7MZGPAUK.mjs} +1 -1
  6. package/dist/smoke/prebuilt/chunk-7WOFGLW3.mjs +239 -0
  7. package/dist/smoke/prebuilt/runtime.mjs +1 -1
  8. package/dist/smoke/prebuilt/smoke-worker.mjs +1 -1
  9. package/dist/smoke/prebuilt/tree-defaults.mjs +1 -1
  10. package/dist/validate/prebuilt/bundle-main.js +13 -13
  11. package/dist/validate/prebuilt/chunk-HKG6YI6Y.js +239 -0
  12. package/dist/validate/prebuilt/runtime.js +1 -1
  13. package/kit/files/.claude/skills/pix3-nodes/SKILL.md +210 -210
  14. package/kit/files/.claude/skills/pix3-nodes/reference.md +32 -24
  15. package/kit/files/.claude/skills/pix3-scene-format/SKILL.md +238 -235
  16. package/kit/files/.claude/skills/pix3-scene-format/reference.md +28 -28
  17. package/kit/files/.claude/skills/pix3-scripts/SKILL.md +285 -281
  18. package/kit/files/.claude/skills/pix3-scripts/reference.md +69 -52
  19. package/kit/files/.claude/skills/pix3-verify/SKILL.md +298 -256
  20. package/kit/files/.claude/skills/pix3-verify/reference.md +21 -21
  21. package/kit/files/AGENTS.md +203 -203
  22. package/kit/files/CLAUDE.md +1 -1
  23. package/kit/kit.json +2 -2
  24. package/package.json +54 -54
  25. package/templates/empty-2d/files/README.md +20 -20
  26. package/templates/empty-2d/files/scenes/main.pix3scene +68 -68
  27. package/templates/empty-2d/template.yaml +7 -7
  28. package/templates/empty-3d/files/README.md +20 -20
  29. package/templates/empty-3d/files/scenes/main.pix3scene +108 -108
  30. package/templates/empty-3d/template.yaml +7 -7
  31. package/templates/idea-blank/files/README.md +22 -22
  32. package/templates/idea-blank/files/scenes/main.pix3scene +37 -37
  33. package/templates/idea-blank/template.yaml +10 -10
  34. package/templates/minigame-2d/files/README.md +44 -44
  35. package/templates/minigame-2d/files/design/tests/reachability.json +1 -1
  36. package/templates/minigame-2d/files/design/tests/routines/mute-music.json +44 -44
  37. package/templates/minigame-2d/files/scenes/main.pix3scene +84 -84
  38. package/templates/minigame-2d/files/scenes/menu.pix3scene +118 -118
  39. package/templates/minigame-2d/files/scenes/ui/settings-window.pix3scene +138 -138
  40. package/templates/minigame-2d/files/scripts/GameFlow.ts +133 -133
  41. package/templates/minigame-2d/files/scripts/MenuFlow.ts +217 -217
  42. package/templates/minigame-2d/files/scripts/SettingsWindow.ts +198 -198
  43. package/templates/minigame-2d/template.yaml +10 -10
  44. package/templates/playable-2d/files/README.md +30 -30
  45. package/templates/playable-2d/files/design/recipe.md +83 -83
  46. package/templates/playable-2d/files/design/tests/reachability.json +4 -4
  47. package/templates/playable-2d/files/design/tests/routines/intro-to-cta.json +32 -32
  48. package/templates/playable-2d/files/scenes/main.pix3scene +111 -111
  49. package/templates/playable-2d/files/scenes/ui/end-screen.pix3scene +91 -91
  50. package/templates/playable-2d/files/scenes/ui/intro.pix3scene +65 -65
  51. package/templates/playable-2d/files/scripts/GameFlow.ts +256 -256
  52. package/templates/playable-2d/template.yaml +9 -9
  53. package/templates/playable-3d/files/README.md +32 -32
  54. package/templates/playable-3d/files/design/recipe.md +127 -127
  55. package/templates/playable-3d/files/design/tests/reachability.json +4 -4
  56. package/templates/playable-3d/files/design/tests/routines/intro-to-cta.json +32 -32
  57. package/templates/playable-3d/files/scenes/main.pix3scene +230 -230
  58. package/templates/playable-3d/files/scenes/ui/end-screen.pix3scene +91 -91
  59. package/templates/playable-3d/files/scenes/ui/intro.pix3scene +65 -65
  60. package/templates/playable-3d/files/scripts/GameFlow.ts +309 -309
  61. package/templates/playable-3d/files/scripts/GameRules.ts +290 -290
  62. package/templates/playable-3d/files/scripts/ScoreHud.ts +113 -113
  63. package/templates/playable-3d/template.yaml +9 -9
  64. package/templates/recipe-arena-2d/files/README.md +48 -48
  65. package/templates/recipe-arena-2d/files/design/recipe.md +127 -127
  66. package/templates/recipe-arena-2d/files/scenes/main.pix3scene +292 -292
  67. package/templates/recipe-arena-2d/files/scenes/menu.pix3scene +100 -100
  68. package/templates/recipe-arena-2d/files/scenes/prefabs/hazard.pix3scene +42 -42
  69. package/templates/recipe-arena-2d/files/scenes/prefabs/pickup.pix3scene +45 -45
  70. package/templates/recipe-arena-2d/files/scenes/ui/result.pix3scene +85 -85
  71. package/templates/recipe-arena-2d/files/scripts/GameRules.ts +368 -368
  72. package/templates/recipe-arena-2d/files/scripts/MenuFlow.ts +106 -106
  73. package/templates/recipe-arena-2d/files/scripts/PlayerController.ts +151 -151
  74. package/templates/recipe-arena-2d/files/scripts/ScoreHud.ts +94 -94
  75. package/templates/recipe-arena-2d/files/scripts/Spawner.ts +214 -214
  76. package/templates/recipe-arena-2d/files/scripts/TouchRules.ts +174 -174
  77. package/templates/recipe-arena-2d/template.yaml +10 -10
  78. package/templates/recipe-blank-2d/files/README.md +61 -61
  79. package/templates/recipe-blank-2d/files/design/recipe.md +148 -148
  80. package/templates/recipe-blank-2d/files/design/tests/reachability.json +4 -4
  81. package/templates/recipe-blank-2d/files/design/tests/routines/restart.json +27 -27
  82. package/templates/recipe-blank-2d/files/scenes/main.pix3scene +224 -224
  83. package/templates/recipe-blank-2d/files/scenes/ui/result.pix3scene +85 -85
  84. package/templates/recipe-blank-2d/files/scripts/GameRules.ts +350 -350
  85. package/templates/recipe-blank-2d/files/scripts/ScoreHud.ts +110 -110
  86. package/templates/recipe-blank-2d/template.yaml +10 -10
  87. package/templates/recipe-bouncer-2d/files/README.md +81 -81
  88. package/templates/recipe-bouncer-2d/files/design/recipe.md +146 -146
  89. package/templates/recipe-bouncer-2d/files/scenes/main.pix3scene +615 -615
  90. package/templates/recipe-bouncer-2d/files/scenes/menu.pix3scene +191 -191
  91. package/templates/recipe-bouncer-2d/files/scenes/ui/result.pix3scene +87 -87
  92. package/templates/recipe-bouncer-2d/files/scripts/BallBody.ts +298 -298
  93. package/templates/recipe-bouncer-2d/files/scripts/GameRules.ts +377 -377
  94. package/templates/recipe-bouncer-2d/files/scripts/MenuFlow.ts +109 -109
  95. package/templates/recipe-bouncer-2d/files/scripts/PaddleController.ts +112 -112
  96. package/templates/recipe-bouncer-2d/files/scripts/ScoreHud.ts +94 -94
  97. package/templates/recipe-bouncer-2d/files/scripts/TouchRules.ts +263 -263
  98. package/templates/recipe-bouncer-2d/files/scripts/ball-collision.ts +307 -307
  99. package/templates/recipe-bouncer-2d/template.yaml +10 -10
  100. package/templates/recipe-grid-3d/files/README.md +22 -22
  101. package/templates/recipe-grid-3d/files/design/recipe.md +110 -110
  102. package/templates/recipe-grid-3d/files/scenes/main.pix3scene +169 -169
  103. package/templates/recipe-grid-3d/files/scenes/menu.pix3scene +100 -100
  104. package/templates/recipe-grid-3d/files/scenes/ui/result.pix3scene +105 -105
  105. package/templates/recipe-grid-3d/files/scripts/GridBoard.ts +319 -319
  106. package/templates/recipe-grid-3d/files/scripts/GridRules.ts +278 -278
  107. package/templates/recipe-grid-3d/files/scripts/MenuFlow.ts +106 -106
  108. package/templates/recipe-grid-3d/files/scripts/ScoreHud.ts +94 -94
  109. package/templates/recipe-grid-3d/template.yaml +10 -10
  110. package/templates/recipe-tapper-2d/files/README.md +39 -39
  111. package/templates/recipe-tapper-2d/files/design/recipe.md +132 -132
  112. package/templates/recipe-tapper-2d/files/design/tests/reachability.json +4 -4
  113. package/templates/recipe-tapper-2d/files/design/tests/routines/terminal-retry.json +23 -23
  114. package/templates/recipe-tapper-2d/files/scenes/main.pix3scene +269 -269
  115. package/templates/recipe-tapper-2d/files/scenes/menu.pix3scene +100 -100
  116. package/templates/recipe-tapper-2d/files/scenes/prefabs/hazard.pix3scene +42 -42
  117. package/templates/recipe-tapper-2d/files/scenes/prefabs/target.pix3scene +45 -45
  118. package/templates/recipe-tapper-2d/files/scenes/ui/result.pix3scene +85 -85
  119. package/templates/recipe-tapper-2d/files/scripts/GameRules.ts +368 -368
  120. package/templates/recipe-tapper-2d/files/scripts/MenuFlow.ts +106 -106
  121. package/templates/recipe-tapper-2d/files/scripts/ScoreHud.ts +94 -94
  122. package/templates/recipe-tapper-2d/files/scripts/Spawner.ts +214 -214
  123. package/templates/recipe-tapper-2d/files/scripts/TouchRules.ts +192 -192
  124. package/templates/recipe-tapper-2d/template.yaml +10 -10
  125. package/dist/smoke/prebuilt/chunk-OJXQXIIQ.mjs +0 -239
  126. package/dist/validate/prebuilt/chunk-BS2OZM7U.js +0 -239
@@ -1,292 +1,292 @@
1
- # Pix3 Scene File (YAML)
2
- # Arena 2D — the GAME scene, and the editor's startup scene: this is the one to
3
- # iterate on and the one agents open and play directly. A full build boots the
4
- # MENU (see menu.pix3scene), whose PLAY button transitions here.
5
- #
6
- # Stable node ids (design/recipe.md is the contract — do not rename these):
7
- # game-root, game-background, board, player,
8
- # spawner-pickups, spawner-hazards,
9
- # hud, score-label, time-label, lives-bar, menu-button,
10
- # result-overlay, result-label, retry-button (scenes/ui/result.pix3scene)
11
- #
12
- # Full-screen UI lives in its own file under scenes/ui/ and is instanced here
13
- # hidden (`visible: false` = editor only), so opening this scene shows the game
14
- # rather than a menu or a GAME OVER card.
15
- #
16
- # 2D coordinates: origin at the canvas centre, X right, Y UP. Node order in the
17
- # tree is paint order (later/deeper draws on top).
18
- version: 1.0.0
19
- metadata:
20
- author: Pix3 Recipe
21
- description: Arena gameplay — spawners drop pickups and hazards into a bounded field
22
- root:
23
- - id: game-root
24
- type: Group2D
25
- name: Game Root
26
- properties:
27
- width: 1080
28
- height: 1920
29
- layout:
30
- enabled: true
31
- horizontalAlign: stretch
32
- verticalAlign: stretch
33
- components:
34
- - id: game-rules
35
- type: user:GameRules
36
- enabled: true
37
- config:
38
- winMode: score
39
- targetScore: 12
40
- timeLimitSec: 45
41
- startingLives: 3
42
- resultNode: result-overlay
43
- resultLabel: result-label
44
- winText: "YOU WIN!"
45
- loseText: "GAME OVER"
46
- retryButton: retry-button
47
- menuButton: menu-button
48
- menuScene: res://scenes/menu.pix3scene
49
- gameScene: res://scenes/main.pix3scene
50
- freezeNodes: spawner-pickups,spawner-hazards,player
51
- - id: touch-rules
52
- type: user:TouchRules
53
- enabled: true
54
- config:
55
- playerNode: player
56
- touchRadius: 62
57
- rules: "pickup:score:1;hazard:damage:1"
58
- consume: true
59
- scoreSound: ""
60
- damageSound: ""
61
- children:
62
- - id: game-background
63
- type: ColorRect2D
64
- name: Game Background
65
- properties:
66
- width: 1080
67
- height: 1920
68
- color: "#141a2e"
69
- transform:
70
- position: [0, 0]
71
- scale: [1, 1]
72
- rotation: 0
73
- layout:
74
- enabled: true
75
- horizontalAlign: stretch
76
- verticalAlign: stretch
77
- children: []
78
- - id: board
79
- type: Group2D
80
- name: Board
81
- properties:
82
- width: 980
83
- height: 1480
84
- transform:
85
- position: [0, -80]
86
- scale: [1, 1]
87
- rotation: 0
88
- children:
89
- - id: board-floor
90
- type: ColorRect2D
91
- name: Board Floor
92
- properties:
93
- width: 980
94
- height: 1480
95
- color: "#1d2743"
96
- transform:
97
- position: [0, 0]
98
- scale: [1, 1]
99
- rotation: 0
100
- children: []
101
- - id: spawner-pickups
102
- type: Group2D
103
- name: Spawner Pickups
104
- properties:
105
- width: 900
106
- height: 60
107
- transform:
108
- position: [0, 690]
109
- scale: [1, 1]
110
- rotation: 0
111
- components:
112
- - id: pickup-spawner
113
- type: user:Spawner
114
- enabled: true
115
- config:
116
- prefab: res://scenes/prefabs/pickup.pix3scene
117
- parentNode: ""
118
- intervalSec: 1.0
119
- intervalJitter: 0.35
120
- maxAlive: 10
121
- spawnWidth: 880
122
- spawnHeight: 60
123
- gridSnap: 0
124
- driftX: 0
125
- driftY: -300
126
- lifetimeSec: 7
127
- despawnRadius: 1450
128
- startDelaySec: 0.3
129
- children: []
130
- - id: spawner-hazards
131
- type: Group2D
132
- name: Spawner Hazards
133
- properties:
134
- width: 900
135
- height: 60
136
- transform:
137
- position: [0, 690]
138
- scale: [1, 1]
139
- rotation: 0
140
- components:
141
- - id: hazard-spawner
142
- type: user:Spawner
143
- enabled: true
144
- config:
145
- prefab: res://scenes/prefabs/hazard.pix3scene
146
- parentNode: ""
147
- intervalSec: 1.8
148
- intervalJitter: 0.6
149
- maxAlive: 8
150
- spawnWidth: 880
151
- spawnHeight: 60
152
- gridSnap: 0
153
- driftX: 0
154
- driftY: -380
155
- lifetimeSec: 6
156
- despawnRadius: 1450
157
- startDelaySec: 1.2
158
- children: []
159
- - id: player
160
- type: Sprite2D
161
- name: Player
162
- properties:
163
- texture: { type: 'texture', url: 'res://sprites/ph-avatar.png' }
164
- width: 120
165
- height: 120
166
- effects:
167
- - type: core:tint
168
- params: { color: "#ffffff", amount: 1 }
169
- transform:
170
- position: [0, -520]
171
- scale: [1, 1]
172
- rotation: 0
173
- components:
174
- - id: player-controller
175
- type: user:PlayerController
176
- enabled: true
177
- config:
178
- mode: pointer
179
- speed: 620
180
- radius: 60
181
- boundsNode: board
182
- deadZone: 4
183
- children: []
184
- - id: hud
185
- type: CanvasLayer2D
186
- name: HUD
187
- properties:
188
- width: 1080
189
- height: 1920
190
- layout:
191
- enabled: true
192
- horizontalAlign: stretch
193
- verticalAlign: stretch
194
- components:
195
- - id: score-hud
196
- type: user:ScoreHud
197
- enabled: true
198
- config:
199
- sourceNode: game-root
200
- scoreLabel: score-label
201
- scoreFormat: "SCORE {value}"
202
- timeLabel: time-label
203
- timeFormat: "{value}"
204
- livesBar: lives-bar
205
- children:
206
- - id: score-label
207
- type: Label2D
208
- name: Score Label
209
- properties:
210
- label: "SCORE 0"
211
- labelFontSize: 44
212
- labelColor: "#ffffff"
213
- labelAlign: left
214
- transform:
215
- position: [-340, 850]
216
- scale: [1, 1]
217
- rotation: 0
218
- layout:
219
- enabled: true
220
- horizontalAlign: left
221
- verticalAlign: top
222
- children: []
223
- - id: time-label
224
- type: Label2D
225
- name: Time Label
226
- properties:
227
- label: "45"
228
- labelFontSize: 44
229
- labelColor: "#f5ae39"
230
- labelAlign: center
231
- transform:
232
- position: [0, 850]
233
- scale: [1, 1]
234
- rotation: 0
235
- layout:
236
- enabled: true
237
- horizontalAlign: center
238
- verticalAlign: top
239
- children: []
240
- - id: lives-bar
241
- type: Bar2D
242
- name: Lives Bar
243
- properties:
244
- width: 240
245
- height: 28
246
- minValue: 0
247
- maxValue: 3
248
- value: 3
249
- barColor: "#ff4d6d"
250
- backBackgroundColor: "#2a3352"
251
- showBorder: false
252
- transform:
253
- position: [340, 855]
254
- scale: [1, 1]
255
- rotation: 0
256
- layout:
257
- enabled: true
258
- horizontalAlign: right
259
- verticalAlign: top
260
- children: []
261
- - id: menu-button
262
- type: Button2D
263
- name: Menu Button
264
- properties:
265
- width: 200
266
- height: 72
267
- label: "MENU"
268
- labelFontSize: 30
269
- labelColor: "#ffffff"
270
- backgroundColor: "#2a3352"
271
- hoverColor: "#3a446b"
272
- pressedColor: "#1d2743"
273
- buttonAction: back-to-menu
274
- transform:
275
- position: [-400, -880]
276
- scale: [1, 1]
277
- rotation: 0
278
- layout:
279
- enabled: true
280
- horizontalAlign: left
281
- verticalAlign: bottom
282
- children: []
283
- # Win/lose screen — authored in scenes/ui/result.pix3scene so this
284
- # scene opens on the GAME, not on a GAME OVER card. `visible: false`
285
- # hides it in the EDITOR only; `initiallyVisible` (in the overlay
286
- # file) is what play mode reads, and GameRules reveals it on the
287
- # win/lose transition. Tick the eye to preview it over the field.
288
- - id: result-overlay
289
- name: Result Overlay
290
- instance: res://scenes/ui/result.pix3scene
291
- properties:
292
- visible: false
1
+ # Pix3 Scene File (YAML)
2
+ # Arena 2D — the GAME scene, and the editor's startup scene: this is the one to
3
+ # iterate on and the one agents open and play directly. A full build boots the
4
+ # MENU (see menu.pix3scene), whose PLAY button transitions here.
5
+ #
6
+ # Stable node ids (design/recipe.md is the contract — do not rename these):
7
+ # game-root, game-background, board, player,
8
+ # spawner-pickups, spawner-hazards,
9
+ # hud, score-label, time-label, lives-bar, menu-button,
10
+ # result-overlay, result-label, retry-button (scenes/ui/result.pix3scene)
11
+ #
12
+ # Full-screen UI lives in its own file under scenes/ui/ and is instanced here
13
+ # hidden (`visible: false` = editor only), so opening this scene shows the game
14
+ # rather than a menu or a GAME OVER card.
15
+ #
16
+ # 2D coordinates: origin at the canvas centre, X right, Y UP. Node order in the
17
+ # tree is paint order (later/deeper draws on top).
18
+ version: 1.0.0
19
+ metadata:
20
+ author: Pix3 Recipe
21
+ description: Arena gameplay — spawners drop pickups and hazards into a bounded field
22
+ root:
23
+ - id: game-root
24
+ type: Group2D
25
+ name: Game Root
26
+ properties:
27
+ width: 1080
28
+ height: 1920
29
+ layout:
30
+ enabled: true
31
+ horizontalAlign: stretch
32
+ verticalAlign: stretch
33
+ components:
34
+ - id: game-rules
35
+ type: user:GameRules
36
+ enabled: true
37
+ config:
38
+ winMode: score
39
+ targetScore: 12
40
+ timeLimitSec: 45
41
+ startingLives: 3
42
+ resultNode: result-overlay
43
+ resultLabel: result-label
44
+ winText: "YOU WIN!"
45
+ loseText: "GAME OVER"
46
+ retryButton: retry-button
47
+ menuButton: menu-button
48
+ menuScene: res://scenes/menu.pix3scene
49
+ gameScene: res://scenes/main.pix3scene
50
+ freezeNodes: spawner-pickups,spawner-hazards,player
51
+ - id: touch-rules
52
+ type: user:TouchRules
53
+ enabled: true
54
+ config:
55
+ playerNode: player
56
+ touchRadius: 62
57
+ rules: "pickup:score:1;hazard:damage:1"
58
+ consume: true
59
+ scoreSound: ""
60
+ damageSound: ""
61
+ children:
62
+ - id: game-background
63
+ type: ColorRect2D
64
+ name: Game Background
65
+ properties:
66
+ width: 1080
67
+ height: 1920
68
+ color: "#141a2e"
69
+ transform:
70
+ position: [0, 0]
71
+ scale: [1, 1]
72
+ rotation: 0
73
+ layout:
74
+ enabled: true
75
+ horizontalAlign: stretch
76
+ verticalAlign: stretch
77
+ children: []
78
+ - id: board
79
+ type: Group2D
80
+ name: Board
81
+ properties:
82
+ width: 980
83
+ height: 1480
84
+ transform:
85
+ position: [0, -80]
86
+ scale: [1, 1]
87
+ rotation: 0
88
+ children:
89
+ - id: board-floor
90
+ type: ColorRect2D
91
+ name: Board Floor
92
+ properties:
93
+ width: 980
94
+ height: 1480
95
+ color: "#1d2743"
96
+ transform:
97
+ position: [0, 0]
98
+ scale: [1, 1]
99
+ rotation: 0
100
+ children: []
101
+ - id: spawner-pickups
102
+ type: Group2D
103
+ name: Spawner Pickups
104
+ properties:
105
+ width: 900
106
+ height: 60
107
+ transform:
108
+ position: [0, 690]
109
+ scale: [1, 1]
110
+ rotation: 0
111
+ components:
112
+ - id: pickup-spawner
113
+ type: user:Spawner
114
+ enabled: true
115
+ config:
116
+ prefab: res://scenes/prefabs/pickup.pix3scene
117
+ parentNode: ""
118
+ intervalSec: 1.0
119
+ intervalJitter: 0.35
120
+ maxAlive: 10
121
+ spawnWidth: 880
122
+ spawnHeight: 60
123
+ gridSnap: 0
124
+ driftX: 0
125
+ driftY: -300
126
+ lifetimeSec: 7
127
+ despawnRadius: 1450
128
+ startDelaySec: 0.3
129
+ children: []
130
+ - id: spawner-hazards
131
+ type: Group2D
132
+ name: Spawner Hazards
133
+ properties:
134
+ width: 900
135
+ height: 60
136
+ transform:
137
+ position: [0, 690]
138
+ scale: [1, 1]
139
+ rotation: 0
140
+ components:
141
+ - id: hazard-spawner
142
+ type: user:Spawner
143
+ enabled: true
144
+ config:
145
+ prefab: res://scenes/prefabs/hazard.pix3scene
146
+ parentNode: ""
147
+ intervalSec: 1.8
148
+ intervalJitter: 0.6
149
+ maxAlive: 8
150
+ spawnWidth: 880
151
+ spawnHeight: 60
152
+ gridSnap: 0
153
+ driftX: 0
154
+ driftY: -380
155
+ lifetimeSec: 6
156
+ despawnRadius: 1450
157
+ startDelaySec: 1.2
158
+ children: []
159
+ - id: player
160
+ type: Sprite2D
161
+ name: Player
162
+ properties:
163
+ texture: { type: 'texture', url: 'res://sprites/ph-avatar.png' }
164
+ width: 120
165
+ height: 120
166
+ effects:
167
+ - type: core:tint
168
+ params: { color: "#ffffff", amount: 1 }
169
+ transform:
170
+ position: [0, -520]
171
+ scale: [1, 1]
172
+ rotation: 0
173
+ components:
174
+ - id: player-controller
175
+ type: user:PlayerController
176
+ enabled: true
177
+ config:
178
+ mode: pointer
179
+ speed: 620
180
+ radius: 60
181
+ boundsNode: board
182
+ deadZone: 4
183
+ children: []
184
+ - id: hud
185
+ type: CanvasLayer2D
186
+ name: HUD
187
+ properties:
188
+ width: 1080
189
+ height: 1920
190
+ layout:
191
+ enabled: true
192
+ horizontalAlign: stretch
193
+ verticalAlign: stretch
194
+ components:
195
+ - id: score-hud
196
+ type: user:ScoreHud
197
+ enabled: true
198
+ config:
199
+ sourceNode: game-root
200
+ scoreLabel: score-label
201
+ scoreFormat: "SCORE {value}"
202
+ timeLabel: time-label
203
+ timeFormat: "{value}"
204
+ livesBar: lives-bar
205
+ children:
206
+ - id: score-label
207
+ type: Label2D
208
+ name: Score Label
209
+ properties:
210
+ label: "SCORE 0"
211
+ labelFontSize: 44
212
+ labelColor: "#ffffff"
213
+ labelAlign: left
214
+ transform:
215
+ position: [-340, 850]
216
+ scale: [1, 1]
217
+ rotation: 0
218
+ layout:
219
+ enabled: true
220
+ horizontalAlign: left
221
+ verticalAlign: top
222
+ children: []
223
+ - id: time-label
224
+ type: Label2D
225
+ name: Time Label
226
+ properties:
227
+ label: "45"
228
+ labelFontSize: 44
229
+ labelColor: "#f5ae39"
230
+ labelAlign: center
231
+ transform:
232
+ position: [0, 850]
233
+ scale: [1, 1]
234
+ rotation: 0
235
+ layout:
236
+ enabled: true
237
+ horizontalAlign: center
238
+ verticalAlign: top
239
+ children: []
240
+ - id: lives-bar
241
+ type: Bar2D
242
+ name: Lives Bar
243
+ properties:
244
+ width: 240
245
+ height: 28
246
+ minValue: 0
247
+ maxValue: 3
248
+ value: 3
249
+ barColor: "#ff4d6d"
250
+ backBackgroundColor: "#2a3352"
251
+ showBorder: false
252
+ transform:
253
+ position: [340, 855]
254
+ scale: [1, 1]
255
+ rotation: 0
256
+ layout:
257
+ enabled: true
258
+ horizontalAlign: right
259
+ verticalAlign: top
260
+ children: []
261
+ - id: menu-button
262
+ type: Button2D
263
+ name: Menu Button
264
+ properties:
265
+ width: 200
266
+ height: 72
267
+ label: "MENU"
268
+ labelFontSize: 30
269
+ labelColor: "#ffffff"
270
+ backgroundColor: "#2a3352"
271
+ hoverColor: "#3a446b"
272
+ pressedColor: "#1d2743"
273
+ buttonAction: back-to-menu
274
+ transform:
275
+ position: [-400, -880]
276
+ scale: [1, 1]
277
+ rotation: 0
278
+ layout:
279
+ enabled: true
280
+ horizontalAlign: left
281
+ verticalAlign: bottom
282
+ children: []
283
+ # Win/lose screen — authored in scenes/ui/result.pix3scene so this
284
+ # scene opens on the GAME, not on a GAME OVER card. `visible: false`
285
+ # hides it in the EDITOR only; `initiallyVisible` (in the overlay
286
+ # file) is what play mode reads, and GameRules reveals it on the
287
+ # win/lose transition. Tick the eye to preview it over the field.
288
+ - id: result-overlay
289
+ name: Result Overlay
290
+ instance: res://scenes/ui/result.pix3scene
291
+ properties:
292
+ visible: false