@almadar/std 16.200.0 → 16.202.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.
Files changed (90) hide show
  1. package/behaviors/lolo/ui/core/molecules/ui-command-palette.lolo +116 -0
  2. package/behaviors/lolo/ui/core/molecules/ui-file-tree.lolo +5 -0
  3. package/behaviors/lolo/ui/core/molecules/ui-floating-toolbar.lolo +55 -0
  4. package/behaviors/lolo/ui/core/organisms/ui-dock-layout.lolo +186 -0
  5. package/behaviors/lolo/ui/core/organisms/ui-split-pane.lolo +37 -1
  6. package/behaviors/lolo/ui/game/atoms/std-audio-cue.lolo +138 -0
  7. package/behaviors/lolo/ui/game/atoms/std-camera-rig.lolo +158 -0
  8. package/behaviors/lolo/ui/game/atoms/std-coef-pad.lolo +5 -3
  9. package/behaviors/lolo/ui/game/atoms/std-platformer-body.lolo +14 -5
  10. package/behaviors/lolo/ui/game/atoms/ui-canvas-2d.lolo +42 -0
  11. package/behaviors/lolo/ui/game/atoms/ui-canvas.lolo +42 -0
  12. package/behaviors/lolo/ui/game/atoms/ui-game-audio-cue.lolo +68 -0
  13. package/behaviors/lolo/ui/game/atoms/ui-game-audio-toggle.lolo +13 -0
  14. package/behaviors/lolo/ui/learning/atoms/ui-algo-graph-canvas.lolo +1 -0
  15. package/behaviors/lolo/ui/learning/atoms/ui-algorithm-canvas.lolo +1 -0
  16. package/behaviors/lolo/ui/learning/atoms/ui-biology-canvas.lolo +1 -0
  17. package/behaviors/lolo/ui/learning/atoms/ui-chemistry-canvas.lolo +1 -0
  18. package/behaviors/lolo/ui/learning/atoms/ui-learning-canvas.lolo +7 -0
  19. package/behaviors/lolo/ui/learning/atoms/ui-math-canvas.lolo +19 -0
  20. package/behaviors/lolo/ui/learning/atoms/ui-physics-canvas.lolo +1 -0
  21. package/behaviors/registry/infra/atoms/std-approval-gate.orb +20 -10
  22. package/behaviors/registry/infra/atoms/std-cache-aside.orb +62 -31
  23. package/behaviors/registry/infra/atoms/std-circuit-breaker.orb +32 -16
  24. package/behaviors/registry/infra/atoms/std-data-erasure.orb +16 -8
  25. package/behaviors/registry/infra/atoms/std-mod-queue.orb +16 -8
  26. package/behaviors/registry/infra/atoms/std-rate-limiter.orb +28 -14
  27. package/behaviors/registry/infra/organisms/std-status-lifecycle-control.orb +2 -1
  28. package/behaviors/registry/ml/organisms/std-escalating-decision.orb +10 -5
  29. package/behaviors/registry/ml/organisms/std-knowledge-tracing.orb +4 -2
  30. package/behaviors/registry/ui/core/atoms/std-billable-hour.orb +2 -1
  31. package/behaviors/registry/ui/core/atoms/std-browse.orb +6 -3
  32. package/behaviors/registry/ui/core/atoms/std-dashboard-grid-embedded.orb +2 -1
  33. package/behaviors/registry/ui/core/atoms/std-esign-flow.orb +4 -2
  34. package/behaviors/registry/ui/core/atoms/std-esign-request.orb +6 -3
  35. package/behaviors/registry/ui/core/atoms/std-export.orb +4 -2
  36. package/behaviors/registry/ui/core/atoms/std-gallery.orb +18 -9
  37. package/behaviors/registry/ui/core/atoms/std-import.orb +4 -2
  38. package/behaviors/registry/ui/core/atoms/std-list.orb +6 -3
  39. package/behaviors/registry/ui/core/molecules/ui-command-palette.orb +589 -0
  40. package/behaviors/registry/ui/core/molecules/ui-file-tree.orb +8 -0
  41. package/behaviors/registry/ui/core/molecules/ui-floating-toolbar.orb +285 -0
  42. package/behaviors/registry/ui/core/organisms/ui-dock-layout.orb +521 -0
  43. package/behaviors/registry/ui/core/organisms/ui-split-pane.orb +109 -2
  44. package/behaviors/registry/ui/game/atoms/std-audio-cue.orb +653 -0
  45. package/behaviors/registry/ui/game/atoms/std-camera-rig.orb +813 -0
  46. package/behaviors/registry/ui/game/atoms/std-coef-pad.orb +170 -4
  47. package/behaviors/registry/ui/game/atoms/std-platformer-body.orb +84 -7
  48. package/behaviors/registry/ui/game/atoms/ui-canvas-2d.orb +135 -0
  49. package/behaviors/registry/ui/game/atoms/ui-canvas.orb +134 -0
  50. package/behaviors/registry/ui/game/atoms/ui-game-audio-cue.orb +258 -0
  51. package/behaviors/registry/ui/game/atoms/ui-game-audio-toggle.orb +48 -0
  52. package/behaviors/registry/ui/game/organisms/std-arcade-board-3d.orb +8 -4
  53. package/behaviors/registry/ui/game/organisms/std-crew-board-2d.orb +6 -3
  54. package/behaviors/registry/ui/game/organisms/std-dungeon-board-2d.orb +10 -5
  55. package/behaviors/registry/ui/game/organisms/std-market-board-3d.orb +8 -4
  56. package/behaviors/registry/ui/game/organisms/std-objective-board-3d.orb +8 -4
  57. package/behaviors/registry/ui/game/organisms/std-platformer-board-2d.orb +6 -3
  58. package/behaviors/registry/ui/game/organisms/std-survival-board-3d.orb +8 -4
  59. package/behaviors/registry/ui/game/organisms/std-tactics-board-2d.orb +12 -6
  60. package/behaviors/registry/ui/game/organisms/std-tactics-board-3d.orb +8 -4
  61. package/behaviors/registry/ui/game/organisms/std-worldmap-board-2d.orb +6 -3
  62. package/behaviors/registry/ui/learning/atoms/ui-algo-graph-canvas.orb +9 -0
  63. package/behaviors/registry/ui/learning/atoms/ui-algorithm-canvas.orb +13 -0
  64. package/behaviors/registry/ui/learning/atoms/ui-biology-canvas.orb +13 -0
  65. package/behaviors/registry/ui/learning/atoms/ui-chemistry-canvas.orb +13 -0
  66. package/behaviors/registry/ui/learning/atoms/ui-learning-canvas.orb +21 -0
  67. package/behaviors/registry/ui/learning/atoms/ui-math-canvas.orb +39 -0
  68. package/behaviors/registry/ui/learning/atoms/ui-physics-canvas.orb +13 -0
  69. package/behaviors/registry/ui/marketing/atoms/std-marketing-article.orb +2 -1
  70. package/behaviors/registry/ui/marketing/atoms/std-marketing-footer.orb +2 -1
  71. package/behaviors/registry/ui/marketing/atoms/std-marketing-split.orb +2 -1
  72. package/behaviors/registry/ui/marketing/atoms/std-marketing-stats.orb +2 -1
  73. package/behaviors/registry/ui/marketing/atoms/std-marketing-steps.orb +2 -1
  74. package/behaviors/registry/ui/marketing/atoms/std-marketing-team.orb +2 -1
  75. package/dist/behaviors/exports-reader.js +3668 -2878
  76. package/dist/behaviors/functions/index.d.ts +673 -6
  77. package/dist/behaviors/functions/index.js +3650 -2879
  78. package/dist/behaviors/index.d.ts +2 -2
  79. package/dist/behaviors/index.js +3679 -2879
  80. package/dist/behaviors/query.d.ts +88 -4
  81. package/dist/behaviors/query.js +3679 -2879
  82. package/dist/behaviors-embeddings.hash.json +3 -3
  83. package/dist/behaviors-embeddings.json +33 -9
  84. package/dist/behaviors-registry.json +125308 -3773
  85. package/dist/index.d.ts +2 -2
  86. package/dist/index.js +3679 -2879
  87. package/dist/knob-embeddings.hash.json +3 -3
  88. package/dist/knob-embeddings.json +1 -1
  89. package/dist/registry/factory-signatures.json +1 -1
  90. package/package.json +3 -3
@@ -0,0 +1,158 @@
1
+ app std-camera-rig "1.0.0"
2
+ "Headless camera authority: the SOLE writer of camX/camY/camZoom on side-view and top-down boards. Every 33ms camera tick it eases camX/camY toward (camTargetX + camLead, camTargetY) — a dead-zone camera: inside deadzoneX/deadzoneY the axis holds, outside it lerps by stiffness — clamps the result to bounds, eases camZoom toward camTargetZoom the same way, and decays camShake toward 0 by shakeDecay. Intents: FOLLOW retargets from a moving body's x/y/vx (vx feeds camLead, the horizontal look-ahead), CUT snaps position+target instantly (no ease, for teleports/cutscenes), SET_ZOOM retargets zoom (clamped to minZoom/maxZoom), SHAKE sets camShake for a consumer to jitter with at bind time — this atom never writes shake into camX/camY itself, RESTART reseeds from config. Emits CAMERA_MOVED every tick. Renders nothing — a board binds its own canvas camera prop straight to camX/camY/camZoom."
3
+ orbital CameraRigOrbital {
4
+ type CameraPos = {
5
+ x : number!
6
+ y : number!
7
+ }
8
+ type CameraBounds = {
9
+ xMin : number!
10
+ xMax : number!
11
+ yMin : number!
12
+ yMax : number!
13
+ }
14
+
15
+ entity CameraState [runtime, shared] {
16
+ id : string!
17
+ camX : number = 0
18
+ camY : number = 0
19
+ camZoom : number = 1
20
+ camTargetX : number = 0
21
+ camTargetY : number = 0
22
+ camTargetZoom : number = 1
23
+ camLead : number = 0
24
+ camShake : number = 0
25
+ }
26
+
27
+ trait CameraRig -> @rebindable CameraState [lifecycle] {
28
+ initial: active
29
+
30
+ state active {
31
+ INIT -> active
32
+ (set @entity.camX @config.start.x)
33
+ (set @entity.camY @config.start.y)
34
+ (set @entity.camZoom @config.zoom)
35
+ (set @entity.camTargetX @config.start.x)
36
+ (set @entity.camTargetY @config.start.y)
37
+ (set @entity.camTargetZoom @config.zoom)
38
+ (set @entity.camLead 0)
39
+ (set @entity.camShake 0)
40
+
41
+ FOLLOW -> active
42
+ (set @entity.camTargetX ?x)
43
+ (set @entity.camTargetY ?y)
44
+ (set @entity.camLead (* ?vx @config.lead))
45
+
46
+ CUT -> active
47
+ (set @entity.camX ?x)
48
+ (set @entity.camY ?y)
49
+ (set @entity.camTargetX ?x)
50
+ (set @entity.camTargetY ?y)
51
+ (set @entity.camLead 0)
52
+
53
+ SET_ZOOM -> active
54
+ (set @entity.camTargetZoom (math/clamp ?zoom @config.minZoom @config.maxZoom))
55
+
56
+ SHAKE -> active
57
+ (set @entity.camShake ?magnitude)
58
+
59
+ RESTART -> active
60
+ (set @entity.camX @config.start.x)
61
+ (set @entity.camY @config.start.y)
62
+ (set @entity.camZoom @config.zoom)
63
+ (set @entity.camTargetX @config.start.x)
64
+ (set @entity.camTargetY @config.start.y)
65
+ (set @entity.camTargetZoom @config.zoom)
66
+ (set @entity.camLead 0)
67
+ (set @entity.camShake 0)
68
+ }
69
+
70
+ ticks {
71
+ camTick every 33ms
72
+ when @config.running
73
+ (do
74
+ (set @entity.camX (math/clamp (if (> (math/abs (- (+ @entity.camTargetX @entity.camLead) @entity.camX)) @config.deadzoneX) (math/lerp @entity.camX (+ @entity.camTargetX @entity.camLead) @config.stiffness) @entity.camX) @config.bounds.xMin @config.bounds.xMax))
75
+ (set @entity.camY (math/clamp (if (> (math/abs (- @entity.camTargetY @entity.camY)) @config.deadzoneY) (math/lerp @entity.camY @entity.camTargetY @config.stiffness) @entity.camY) @config.bounds.yMin @config.bounds.yMax))
76
+ (set @entity.camZoom (math/clamp (math/lerp @entity.camZoom @entity.camTargetZoom @config.stiffness) @config.minZoom @config.maxZoom))
77
+ (set @entity.camShake (math/max 0 (- @entity.camShake @config.shakeDecay))))
78
+ (emit CAMERA_MOVED { x: @entity.camX, y: @entity.camY, zoom: @entity.camZoom })
79
+ }
80
+
81
+ emits {
82
+ CAMERA_MOVED -> external {
83
+ x : number!
84
+ y : number!
85
+ zoom : number!
86
+ }
87
+ @description "Eased camera position/zoom after this tick."
88
+ @tier "domain"
89
+ }
90
+
91
+ listens {
92
+ FOLLOW { x : number!, y : number!, vx : number! }
93
+ @description "Retarget from a moving body's position and horizontal velocity (vx drives camLead)."
94
+ @tier "domain"
95
+ CUT { x : number!, y : number! }
96
+ @description "Snap position and target instantly, no ease — teleports and cutscenes."
97
+ @tier "domain"
98
+ SET_ZOOM { zoom : number! }
99
+ @description "Retarget zoom, clamped to minZoom/maxZoom."
100
+ @tier "domain"
101
+ SHAKE { magnitude : number! }
102
+ @description "Set camShake; a consumer jitters camX/camY with it at bind time — this atom never writes shake into position."
103
+ @tier "domain"
104
+ RESTART
105
+ @description "Reseed position/zoom/lead/shake from config."
106
+ @tier "domain"
107
+ }
108
+
109
+ config {
110
+ running : boolean = true
111
+ @label "Running"
112
+ @description "When true the 33ms camera tick eases toward target; toggle to freeze the camera"
113
+ @tier "domain"
114
+ start : CameraPos = { x: 0, y: 0 }
115
+ @label "Start Position"
116
+ @description "Initial and RESTART camera position/target"
117
+ @tier "domain"
118
+ zoom : number = 1
119
+ @label "Zoom"
120
+ @description "Initial and RESTART zoom level"
121
+ @tier "domain"
122
+ minZoom : number = 0.5
123
+ @label "Min Zoom"
124
+ @description "Lower clamp for SET_ZOOM and the eased zoom"
125
+ @tier "presentation"
126
+ maxZoom : number = 3
127
+ @label "Max Zoom"
128
+ @description "Upper clamp for SET_ZOOM and the eased zoom"
129
+ @tier "presentation"
130
+ stiffness : number = 0.1
131
+ @label "Stiffness"
132
+ @description "Per-tick lerp factor easing position/zoom toward target (0-1, higher = snappier)"
133
+ @tier "presentation"
134
+ deadzoneX : number = 0
135
+ @label "Dead Zone X"
136
+ @description "Horizontal distance from target the camera tolerates without easing"
137
+ @tier "presentation"
138
+ deadzoneY : number = 0
139
+ @label "Dead Zone Y"
140
+ @description "Vertical distance from target the camera tolerates without easing"
141
+ @tier "presentation"
142
+ lead : number = 0
143
+ @label "Lead"
144
+ @description "Horizontal look-ahead multiplier applied to FOLLOW's vx"
145
+ @tier "presentation"
146
+ bounds : CameraBounds = { xMin: -1000000, xMax: 1000000, yMin: -1000000, yMax: 1000000 }
147
+ @label "Bounds"
148
+ @description "World-space clamp applied to the eased camera position every tick"
149
+ @tier "presentation"
150
+ shakeDecay : number = 0.1
151
+ @label "Shake Decay"
152
+ @description "Amount camShake reduces toward 0 every tick"
153
+ @tier "presentation"
154
+ }
155
+ }
156
+
157
+ page "/camera-rig" as CameraRigPage -> CameraRig
158
+ }
@@ -5,6 +5,7 @@ orbital CoefPadOrbital {
5
5
  x0 : number!
6
6
  x1 : number!
7
7
  a : number!
8
+ b : number
8
9
  h : number!
9
10
  k : number!
10
11
  }
@@ -50,7 +51,7 @@ orbital CoefPadOrbital {
50
51
  (let ((remaining (array/len (array/filter @entity.coefPads (fn c (and (== (object/get @c applied) false) (!= (object/get @c id) (object/get @p id))))))))
51
52
  (do
52
53
  (set @entity.coefPads (array/map @entity.coefPads (fn c (if (== (object/get @c id) (object/get @p id)) (object/merge @c { applied: true }) @c))))
53
- (emit COEF_PAD_APPLIED { id: (object/get @p id), x: (object/get @p x), y: (object/get @p y), x0: (object/get @m x0), x1: (object/get @m x1), a: (object/get @m a), h: (object/get @m h), k: (object/get @m k), hint: (object/get @p hint), hop: (object/get @p hop), samples: (object/get @p samples) })
54
+ (emit COEF_PAD_APPLIED { id: (object/get @p id), x: (object/get @p x), y: (object/get @p y), x0: (object/get @m x0), x1: (object/get @m x1), a: (object/get @m a), b: (if (== (object/get @m b) null) 1 (object/get @m b)), h: (object/get @m h), k: (object/get @m k), hint: (object/get @p hint), hop: (object/get @p hop), samples: (object/get @p samples) })
54
55
  (if (and (== @entity.coefCompleted false) (== @remaining 0))
55
56
  (do
56
57
  (set @entity.coefCompleted true)
@@ -71,13 +72,14 @@ orbital CoefPadOrbital {
71
72
  x0 : number!
72
73
  x1 : number!
73
74
  a : number!
75
+ b : number
74
76
  h : number!
75
77
  k : number!
76
78
  hint : string
77
79
  hop : boolean
78
80
  samples : [CoefModSample]
79
81
  }
80
- @description "The player stood on an unapplied coefficient pad; carries the pad position and the full mod (x0, x1, a, h, k) so the board appends it to the body authority's curveMods and hops the player onto the reshaped road. Fires once per pad per run."
82
+ @description "The player stood on an unapplied coefficient pad; carries the pad position and the full mod (x0, x1, a, b, h, k) so the board appends it to the body authority's curveMods and hops the player onto the reshaped road. Fires once per pad per run."
81
83
  @tier "domain"
82
84
  COEF_PAD_SET_COMPLETED -> external {
83
85
  }
@@ -97,7 +99,7 @@ orbital CoefPadOrbital {
97
99
  @tier "domain"
98
100
  coefPads : [CoefPad] = []
99
101
  @label "Coefficient Pads"
100
- @description "One row per pad: id, center (x, y in world units), the mod applied to the road while inside x0..x1 (a scales slope+height, h shifts horizontally, k lifts), and the hint floated on apply, and hop (true = the board teleports the player onto the reshaped surface — use when the mod steps the road far from the pad; false = the skate snap carries the player, preserving speed). applied is stamped at runtime."
102
+ @description "One row per pad: id, center (x, y in world units), the mod applied to the road while inside x0..x1 (a scales slope+height, b compresses/stretch period, h shifts horizontally, k lifts), and the hint floated on apply, and hop (true = the board teleports the player onto the reshaped surface — use when the mod steps the road far from the pad; false = the skate snap carries the player, preserving speed). applied is stamped at runtime."
101
103
  @tier "domain"
102
104
  reachX : number = 0.7
103
105
  @label "Reach X"
@@ -36,6 +36,7 @@ orbital PlatformerBodyOrbital {
36
36
  x0 : number!
37
37
  x1 : number!
38
38
  a : number!
39
+ b : number!
39
40
  h : number!
40
41
  k : number!
41
42
  }
@@ -81,7 +82,10 @@ orbital PlatformerBodyOrbital {
81
82
  (set @entity.skating false)
82
83
 
83
84
  CURVE_MOD_ADD -> active when @config.curveModsEnabled
84
- (set @entity.curveMods (array/append @entity.curveMods { x0: @payload.x0, x1: @payload.x1, a: @payload.a, h: @payload.h, k: @payload.k }))
85
+ (set @entity.curveMods (array/append @entity.curveMods { x0: @payload.x0, x1: @payload.x1, a: @payload.a, b: (if (== @payload.b null) 1 @payload.b), h: @payload.h, k: @payload.k }))
86
+
87
+ CURVE_MOD_CLEAR -> active when @config.curveModsEnabled
88
+ (set @entity.curveMods [])
85
89
 
86
90
  SET_TUNING -> active
87
91
  (set @entity.tuning (object/merge @entity.tuning (if (== @payload.jumpStrength null) {} { jumpStrength: @payload.jumpStrength })))
@@ -123,7 +127,7 @@ orbital PlatformerBodyOrbital {
123
127
  (let ((gapBreak (and (> @config.skateMaxGap 0) (> (- (object/get @rightSamp x) (object/get @leftSamp x)) @config.skateMaxGap))))
124
128
  (let ((mods (if (and @config.curveModsEnabled @inRange) (array/filter @entity.curveMods (fn m (and (>= @cx (object/get @m x0)) (<= @cx (object/get @m x1))))) [])))
125
129
  (let ((modded (array/reduce @mods { y: @curveY, s: @slope } (fn (acc m)
126
- (let ((modX (- @cx (object/get @m h))))
130
+ (let ((modX (* (object/get @m b) (- @cx (object/get @m h)))))
127
131
  (let ((modInRange (and (>= @modX (object/get (array/first @config.skateCurve) x)) (< @modX (object/get (array/last @config.skateCurve) x)))))
128
132
  (let ((modLeft (if @modInRange (array/last (array/filter @config.skateCurve (fn s (<= (object/get @s x) @modX)))) null)))
129
133
  (let ((modRight (if @modInRange (array/first (array/filter @config.skateCurve (fn s (> (object/get @s x) @modX)))) null)))
@@ -131,7 +135,7 @@ orbital PlatformerBodyOrbital {
131
135
  (let ((modSlope (if @modOK (/ (- (object/get @modRight y) (object/get @modLeft y)) (- (object/get @modRight x) (object/get @modLeft x))) 0)))
132
136
  (let ((modCurveY (if @modOK (+ (object/get @modLeft y) (* @modSlope (- @modX (object/get @modLeft x)))) 0)))
133
137
  (if @modOK
134
- { y: (+ (object/get @acc y) (- (+ (* (object/get @m a) @modCurveY) (object/get @m k)) @curveY)), s: (+ (object/get @acc s) (- (* (object/get @m a) @modSlope) @slope)) }
138
+ { y: (+ (object/get @acc y) (- (+ (* (object/get @m a) @modCurveY) (object/get @m k)) @curveY)), s: (+ (object/get @acc s) (- (* (* (object/get @m a) (object/get @m b)) @modSlope) @slope)) }
135
139
  @acc))))))))))))
136
140
  (let ((slope (object/get @modded s)))
137
141
  (let ((curveY (object/get @modded y)))
@@ -236,13 +240,18 @@ orbital PlatformerBodyOrbital {
236
240
  }
237
241
  @description "Body crossed killY in the gravity direction (pit fall); fires once per fall and re-arms on PLACE/RESTART, leaving the respawn rule to the board"
238
242
  @tier "domain"
243
+ CURVE_MOD_CLEAR -> external {
244
+ }
245
+ @description "Curve mods were cleared; the skate surface is back to the base skateCurve until a new mod is added."
246
+ @tier "domain"
239
247
  }
240
248
 
241
249
  listens {
242
250
  STEER { dir : number! }
243
251
  JUMP { id : string }
244
252
  PLACE { x : number!, y : number! }
245
- CURVE_MOD_ADD { x0 : number!, x1 : number!, a : number!, h : number!, k : number! }
253
+ CURVE_MOD_ADD { x0 : number!, x1 : number!, a : number!, b : number, h : number!, k : number! }
254
+ CURVE_MOD_CLEAR { }
246
255
  SET_TUNING { jumpStrength : number, moveSpeed : number, gravity : number }
247
256
  RESTART { id : string }
248
257
  }
@@ -266,7 +275,7 @@ orbital PlatformerBodyOrbital {
266
275
  @tier "domain"
267
276
  curveModsEnabled : boolean = false
268
277
  @label "Curve Mods Enabled"
269
- @description "When true, entity.curveMods reshape the skate surface inside each mod's x-range: the road samples the base curve at (x − h) and applies a·y + k (slope scales by a) — coefficient pads lift/tilt the segment the player is riding. Multiple overlapping mods stack by summing each mod's delta from the base surface; a mod whose shifted sample leaves the curve range is skipped. Default off: boards without coef pads pay nothing."
278
+ @description "When true, entity.curveMods reshape the skate surface inside each mod's x-range: the road samples the base curve at b·(x − h) and applies a·y + k (slope scales by a·b) — coefficient pads lift/tilt/compress the segment the player is riding. Multiple overlapping mods stack by summing each mod's delta from the base surface; a mod whose shifted sample leaves the curve range is skipped. Default off: boards without coef pads pay nothing."
270
279
  @tier "domain"
271
280
  jumpStrength : number = 11
272
281
  @label "Jump Strength"
@@ -40,6 +40,12 @@ orbital Canvas2dOrbital {
40
40
  tileLeaveEvent: @config.tileLeaveEvent
41
41
  keyMap: @config.keyMap
42
42
  keyUpMap: @config.keyUpMap
43
+ editable: @config.editable
44
+ selectedId: @config.selectedId
45
+ onSelect: @config.onSelect
46
+ onMove: @config.onMove
47
+ selectEvent: @config.selectEvent
48
+ moveEvent: @config.moveEvent
43
49
  camera: @config.camera
44
50
  scale: @config.scale
45
51
  tileWidth: @config.tileWidth
@@ -74,6 +80,18 @@ orbital Canvas2dOrbital {
74
80
  @config.tileLeaveEvent -> external { }
75
81
  @description "Emits UI:{tileLeaveEvent} with {} on pointer leave."
76
82
  @tier "essential"
83
+ @config.onSelect -> external {
84
+ id : string
85
+ }
86
+ @description "Fired on a click that changes selection — before `selectEvent`."
87
+ @tier "essential"
88
+ @config.onMove -> external {
89
+ id : string
90
+ x : number
91
+ y : number
92
+ }
93
+ @description "Fired once per drag gesture, on drop — before `moveEvent`."
94
+ @tier "essential"
77
95
  }
78
96
 
79
97
  config {
@@ -125,6 +143,30 @@ orbital Canvas2dOrbital {
125
143
  @label "Key Up Map"
126
144
  @description "Maps a keyup `e.code` → the board's SEMANTIC event."
127
145
  @tier "presentation"
146
+ editable : boolean = false
147
+ @label "Editable"
148
+ @description "--- Scene-edit mode (a game studio selecting/dragging drawables). Purely"
149
+ @tier "presentation"
150
+ selectedId : string
151
+ @label "Selected Id"
152
+ @description "The currently-selected drawable id (controlled); `null`/undefined = none."
153
+ @tier "presentation"
154
+ onSelect : event = "SELECT"
155
+ @label "On Select"
156
+ @description "Fired on a click that changes selection — before `selectEvent`."
157
+ @tier "presentation"
158
+ onMove : event = "MOVE"
159
+ @label "On Move"
160
+ @description "Fired once per drag gesture, on drop — before `moveEvent`."
161
+ @tier "presentation"
162
+ selectEvent : event = "SELECT"
163
+ @label "Select Event"
164
+ @description "Declarative selection event, `UI:{selectEvent} { id }`."
165
+ @tier "presentation"
166
+ moveEvent : event = "MOVE"
167
+ @label "Move Event"
168
+ @description "Declarative move event, `UI:{moveEvent} { id, x, y }` — fired once on drop."
169
+ @tier "presentation"
128
170
  camera : "pan-zoom" | "follow" | "fixed" = "pan-zoom"
129
171
  @label "Camera"
130
172
  @description "--- View config (pure render) ---"
@@ -103,6 +103,12 @@ orbital CanvasOrbital {
103
103
  featureClickEvent: @config.featureClickEvent
104
104
  keyMap: @config.keyMap
105
105
  keyUpMap: @config.keyUpMap
106
+ editable: @config.editable
107
+ selectedId: @config.selectedId
108
+ onSelect: @config.onSelect
109
+ onMove: @config.onMove
110
+ selectEvent: @config.selectEvent
111
+ moveEvent: @config.moveEvent
106
112
  children: @config.children
107
113
  type: canvas
108
114
  })
@@ -143,6 +149,18 @@ orbital CanvasOrbital {
143
149
  }
144
150
  @description "Feature-click event (3D only)."
145
151
  @tier "essential"
152
+ @config.onSelect -> external {
153
+ id : string
154
+ }
155
+ @description "Fired on a click that changes selection — before `selectEvent`."
156
+ @tier "essential"
157
+ @config.onMove -> external {
158
+ id : string
159
+ x : number
160
+ y : number
161
+ }
162
+ @description "Fired once per drag gesture, on drop — before `moveEvent`."
163
+ @tier "essential"
146
164
  }
147
165
 
148
166
  config {
@@ -262,6 +280,30 @@ orbital CanvasOrbital {
262
280
  @label "Key Up Map"
263
281
  @description "keyUpMap prop"
264
282
  @tier "presentation"
283
+ editable : boolean
284
+ @label "Editable"
285
+ @description "--- Scene-edit mode (a game studio selecting/dragging drawables). Purely"
286
+ @tier "presentation"
287
+ selectedId : string
288
+ @label "Selected Id"
289
+ @description "The currently-selected drawable id (controlled); `null`/undefined = none."
290
+ @tier "presentation"
291
+ onSelect : event = "SELECT"
292
+ @label "On Select"
293
+ @description "Fired on a click that changes selection — before `selectEvent`."
294
+ @tier "presentation"
295
+ onMove : event = "MOVE"
296
+ @label "On Move"
297
+ @description "Fired once per drag gesture, on drop — before `moveEvent`."
298
+ @tier "presentation"
299
+ selectEvent : event = "SELECT"
300
+ @label "Select Event"
301
+ @description "Declarative selection event, `UI:{selectEvent} { id }`."
302
+ @tier "presentation"
303
+ moveEvent : event = "MOVE"
304
+ @label "Move Event"
305
+ @description "Declarative move event, `UI:{moveEvent} { id, x, y }` — fired once on drop."
306
+ @tier "presentation"
265
307
  children : node
266
308
  @label "Children"
267
309
  @description "Declarative JSX drawable children (`<DrawShape .../>` composed in paint order). Forwarded to the 2D host, which collects them via drawable registry context."
@@ -0,0 +1,68 @@
1
+ app ui-game-audio-cue "1.0.0"
2
+ "GameAudioCue — UI factory (1:1 with the @almadar/ui game-audio-cue pattern)."
3
+ orbital GameAudioCueOrbital {
4
+ type GameAudioCueManifestValue = {
5
+ path : string!
6
+ volume : number
7
+ loop : boolean
8
+ poolSize : number
9
+ autostart : boolean
10
+ crossfade : boolean
11
+ crossfadeDurationMs : number
12
+ }
13
+
14
+ entity GameAudioCueItem [runtime] {
15
+ id : string!
16
+ }
17
+
18
+ trait GameAudioCueRender -> @rebindable GameAudioCueItem [interaction, instance] {
19
+ initial: idle
20
+
21
+ state idle {
22
+ INIT -> idle
23
+ (render-ui main {
24
+ cue: @config.cue
25
+ cueSeq: @config.cueSeq
26
+ music: @config.music
27
+ muted: @config.muted
28
+ volume: @config.volume
29
+ manifest: @config.manifest
30
+ baseUrl: @config.baseUrl
31
+ type: game-audio-cue
32
+ })
33
+ }
34
+
35
+ config {
36
+ cue : string
37
+ @label "Cue"
38
+ @description "Manifest key played as a one-shot SFX each time `cueSeq` advances."
39
+ @tier "presentation"
40
+ cueSeq : number
41
+ @label "Cue Seq"
42
+ @description "Monotonically increasing counter — bumping it re-triggers `cue`."
43
+ @tier "presentation"
44
+ music : string
45
+ @label "Music"
46
+ @description "Manifest key to crossfade to as looping background music; unset/empty stops music."
47
+ @tier "presentation"
48
+ muted : boolean
49
+ @label "Muted"
50
+ @description "Muted state, owned externally and mirrored into the hook."
51
+ @tier "presentation"
52
+ volume : number
53
+ @label "Volume"
54
+ @description "Master volume 0-1, owned externally and mirrored into the hook."
55
+ @tier "presentation"
56
+ manifest : Map string GameAudioCueManifestValue = {}
57
+ @label "Manifest"
58
+ @description "Sound manifest — keys mapped to sound definitions (path, volume, loop, ...)."
59
+ @tier "presentation"
60
+ baseUrl : string
61
+ @label "Base Url"
62
+ @description "Base URL prepended to every manifest path."
63
+ @tier "presentation"
64
+ }
65
+ }
66
+
67
+ page "/game-audio-cue" as GameAudioCuePage -> GameAudioCueRender
68
+ }
@@ -52,10 +52,19 @@ orbital GameAudioToggleOrbital {
52
52
  error: @config.error
53
53
  onAsset: @config.onAsset
54
54
  offAsset: @config.offAsset
55
+ toggleEvent: @config.toggleEvent
55
56
  type: game-audio-toggle
56
57
  })
57
58
  }
58
59
 
60
+ emits {
61
+ @config.toggleEvent -> external {
62
+ muted : boolean!
63
+ }
64
+ @description "Event dispatched via event bus on toggle, carrying the new muted state."
65
+ @tier "essential"
66
+ }
67
+
59
68
  config {
60
69
  size : "sm" | "md" | "lg" = sm
61
70
  @label "Size"
@@ -81,6 +90,10 @@ orbital GameAudioToggleOrbital {
81
90
  @label "Off Asset"
82
91
  @description "Asset rendered when sound is OFF (muted). Falls back to 🔇 emoji."
83
92
  @tier "presentation"
93
+ toggleEvent : event = "TOGGLE"
94
+ @label "Toggle Event"
95
+ @description "Event dispatched via event bus on toggle, carrying the new muted state."
96
+ @tier "presentation"
84
97
  }
85
98
  }
86
99
 
@@ -41,6 +41,7 @@ orbital AlgoGraphCanvasOrbital {
41
41
  text : string
42
42
  label : string
43
43
  fontSize : number
44
+ fontFamily : string
44
45
  align : "left" | "center" | "right"
45
46
  axis : "x" | "y"
46
47
  min : number
@@ -84,6 +84,7 @@ orbital AlgorithmCanvasOrbital {
84
84
  text : string
85
85
  label : string
86
86
  fontSize : number
87
+ fontFamily : string
87
88
  align : "left" | "center" | "right"
88
89
  axis : "x" | "y"
89
90
  min : number
@@ -159,6 +159,7 @@ orbital BiologyCanvasOrbital {
159
159
  text : string
160
160
  label : string
161
161
  fontSize : number
162
+ fontFamily : string
162
163
  align : "left" | "center" | "right"
163
164
  axis : "x" | "y"
164
165
  min : number
@@ -156,6 +156,7 @@ orbital ChemistryCanvasOrbital {
156
156
  text : string
157
157
  label : string
158
158
  fontSize : number
159
+ fontFamily : string
159
160
  align : "left" | "center" | "right"
160
161
  axis : "x" | "y"
161
162
  min : number
@@ -18,6 +18,7 @@ orbital LearningCanvasOrbital {
18
18
  text : string
19
19
  label : string
20
20
  fontSize : number
21
+ fontFamily : string
21
22
  align : "left" | "center" | "right"
22
23
  axis : "x" | "y"
23
24
  min : number
@@ -101,6 +102,7 @@ orbital LearningCanvasOrbital {
101
102
  width: @config.width
102
103
  height: @config.height
103
104
  backgroundColor: @config.backgroundColor
105
+ fontFamily: @config.fontFamily
104
106
  shapes: @config.shapes
105
107
  drawables: @config.drawables
106
108
  projector: @config.projector
@@ -120,6 +122,7 @@ orbital LearningCanvasOrbital {
120
122
  width: @config.width
121
123
  height: @config.height
122
124
  backgroundColor: @config.backgroundColor
125
+ fontFamily: @config.fontFamily
123
126
  shapes: @payload.shapes
124
127
  drawables: @payload.drawables
125
128
  projector: @config.projector
@@ -177,6 +180,10 @@ orbital LearningCanvasOrbital {
177
180
  @label "Background Color"
178
181
  @description "Background color (default transparent)."
179
182
  @tier "presentation"
183
+ fontFamily : string
184
+ @label "Font Family"
185
+ @description "Canvas text font family. Falls back to the theme's --font-family-body."
186
+ @tier "presentation"
180
187
  shapes : [LearningCanvasShapesItem] = []
181
188
  @label "Shapes"
182
189
  @description "Declarative shapes to draw."
@@ -90,6 +90,7 @@ orbital MathCanvasOrbital {
90
90
  text : string
91
91
  label : string
92
92
  fontSize : number
93
+ fontFamily : string
93
94
  align : "left" | "center" | "right"
94
95
  axis : "x" | "y"
95
96
  min : number
@@ -172,6 +173,9 @@ orbital MathCanvasOrbital {
172
173
  gridColor: @config.gridColor
173
174
  axisColor: @config.axisColor
174
175
  showTickLabels: @config.showTickLabels
176
+ tickLabelFontSize: @config.tickLabelFontSize
177
+ labelFontSize: @config.labelFontSize
178
+ fontFamily: @config.fontFamily
175
179
  showCurveLabels: @config.showCurveLabels
176
180
  curves: @config.curves
177
181
  points: @config.points
@@ -211,6 +215,9 @@ orbital MathCanvasOrbital {
211
215
  gridColor: @config.gridColor
212
216
  axisColor: @config.axisColor
213
217
  showTickLabels: @config.showTickLabels
218
+ tickLabelFontSize: @config.tickLabelFontSize
219
+ labelFontSize: @config.labelFontSize
220
+ fontFamily: @config.fontFamily
214
221
  showCurveLabels: @config.showCurveLabels
215
222
  curves: @payload.curves
216
223
  points: @payload.points
@@ -324,6 +331,18 @@ orbital MathCanvasOrbital {
324
331
  @label "Show Tick Labels"
325
332
  @description "Draw numeric labels on grid lines (default false)."
326
333
  @tier "presentation"
334
+ tickLabelFontSize : number = 10
335
+ @label "Tick Label Font Size"
336
+ @description "Font size in px for axis tick labels (default 10)."
337
+ @tier "presentation"
338
+ labelFontSize : number = 12
339
+ @label "Label Font Size"
340
+ @description "Base font size in px for all other canvas annotations (points, vectors, guides, curves, regions, angles, hops; default 12)."
341
+ @tier "presentation"
342
+ fontFamily : string
343
+ @label "Font Family"
344
+ @description "Canvas text font family. Accepts a known game-font key (e.g. 'future-narrow') or a CSS font-family string."
345
+ @tier "presentation"
327
346
  showCurveLabels : boolean = false
328
347
  @label "Show Curve Labels"
329
348
  @description "Draw each curve's `label` at its last in-range sample (default false)."
@@ -193,6 +193,7 @@ orbital PhysicsCanvasOrbital {
193
193
  text : string
194
194
  label : string
195
195
  fontSize : number
196
+ fontFamily : string
196
197
  align : "left" | "center" | "right"
197
198
  axis : "x" | "y"
198
199
  min : number