@almadar/std 16.187.0 → 16.189.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 (102) hide show
  1. package/behaviors/lolo/ui/core/.hand-authored.json +4 -4
  2. package/behaviors/lolo/ui/core/atoms/std-board.lolo +138 -4
  3. package/behaviors/lolo/ui/core/atoms/std-browse.lolo +148 -8
  4. package/behaviors/lolo/ui/core/atoms/std-calendar.lolo +161 -11
  5. package/behaviors/lolo/ui/core/atoms/std-event-log.lolo +255 -2
  6. package/behaviors/lolo/ui/core/atoms/std-gallery.lolo +148 -1
  7. package/behaviors/lolo/ui/core/atoms/std-list.lolo +193 -1
  8. package/behaviors/lolo/ui/core/atoms/std-record-detail.lolo +731 -0
  9. package/behaviors/lolo/ui/core/atoms/std-related.lolo +5 -1
  10. package/behaviors/lolo/ui/core/atoms/std-selection.lolo +182 -1
  11. package/behaviors/lolo/ui/core/atoms/std-tree.lolo +113 -3
  12. package/behaviors/lolo/ui/core/atoms/std-version-history.lolo +1 -1
  13. package/behaviors/lolo/ui/core/molecules/ui-document-details.lolo +80 -0
  14. package/behaviors/lolo/ui/core/molecules/ui-document-panel.lolo +213 -0
  15. package/behaviors/lolo/ui/core/molecules/{ui-rich-block-editor.lolo → ui-rich-text-editor.lolo} +25 -25
  16. package/behaviors/lolo/ui/game/atoms/std-area-fill.lolo +93 -0
  17. package/behaviors/lolo/ui/game/atoms/std-choice-gate.lolo +100 -0
  18. package/behaviors/lolo/ui/game/atoms/std-coef-pad.lolo +114 -0
  19. package/behaviors/lolo/ui/game/atoms/std-curve-fog.lolo +50 -0
  20. package/behaviors/lolo/ui/game/atoms/std-loop-lock.lolo +79 -0
  21. package/behaviors/lolo/ui/game/atoms/std-pad-lock.lolo +97 -0
  22. package/behaviors/lolo/ui/game/atoms/std-patrol-hazard.lolo +14 -7
  23. package/behaviors/lolo/ui/game/atoms/std-platformer-body.lolo +48 -5
  24. package/behaviors/lolo/ui/game/atoms/std-velocity-gate.lolo +101 -0
  25. package/behaviors/lolo/ui/game/atoms/std-zone-card.lolo +95 -0
  26. package/behaviors/lolo/ui/game/organisms/std-platformer-board-2d.lolo +9 -0
  27. package/behaviors/registry/infra/atoms/std-approval-gate.orb +16 -8
  28. package/behaviors/registry/infra/atoms/std-cache-aside.orb +62 -31
  29. package/behaviors/registry/infra/atoms/std-circuit-breaker.orb +32 -16
  30. package/behaviors/registry/infra/atoms/std-data-erasure.orb +16 -8
  31. package/behaviors/registry/infra/atoms/std-mod-queue.orb +16 -8
  32. package/behaviors/registry/infra/atoms/std-rate-limiter.orb +28 -14
  33. package/behaviors/registry/infra/organisms/std-status-lifecycle-control.orb +2 -1
  34. package/behaviors/registry/ml/organisms/std-escalating-decision.orb +10 -5
  35. package/behaviors/registry/ml/organisms/std-knowledge-tracing.orb +4 -2
  36. package/behaviors/registry/ui/core/atoms/std-billable-hour.orb +2 -1
  37. package/behaviors/registry/ui/core/atoms/std-board.orb +355 -2
  38. package/behaviors/registry/ui/core/atoms/std-browse.orb +304 -31
  39. package/behaviors/registry/ui/core/atoms/std-calendar.orb +393 -25
  40. package/behaviors/registry/ui/core/atoms/std-dashboard-grid-embedded.orb +2 -1
  41. package/behaviors/registry/ui/core/atoms/std-esign-flow.orb +4 -2
  42. package/behaviors/registry/ui/core/atoms/std-esign-request.orb +6 -3
  43. package/behaviors/registry/ui/core/atoms/std-event-log.orb +773 -0
  44. package/behaviors/registry/ui/core/atoms/std-export.orb +4 -2
  45. package/behaviors/registry/ui/core/atoms/std-gallery.orb +390 -0
  46. package/behaviors/registry/ui/core/atoms/std-import.orb +4 -2
  47. package/behaviors/registry/ui/core/atoms/std-list.orb +451 -0
  48. package/behaviors/registry/ui/core/atoms/std-record-detail.orb +3360 -0
  49. package/behaviors/registry/ui/core/atoms/std-related.orb +23 -1
  50. package/behaviors/registry/ui/core/atoms/std-selection.orb +436 -0
  51. package/behaviors/registry/ui/core/atoms/std-tree.orb +292 -1
  52. package/behaviors/registry/ui/core/atoms/std-version-history.orb +1 -1
  53. package/behaviors/registry/ui/core/molecules/ui-document-details.orb +342 -0
  54. package/behaviors/registry/ui/core/molecules/ui-document-panel.orb +655 -0
  55. package/behaviors/registry/ui/core/molecules/{ui-rich-block-editor.orb → ui-rich-text-editor.orb} +84 -97
  56. package/behaviors/registry/ui/game/atoms/std-area-fill.orb +955 -0
  57. package/behaviors/registry/ui/game/atoms/std-choice-gate.orb +855 -0
  58. package/behaviors/registry/ui/game/atoms/std-coef-pad.orb +928 -0
  59. package/behaviors/registry/ui/game/atoms/std-curve-fog.orb +337 -0
  60. package/behaviors/registry/ui/game/atoms/std-fx-trail.orb +1 -1
  61. package/behaviors/registry/ui/game/atoms/std-gate-lock.orb +1 -1
  62. package/behaviors/registry/ui/game/atoms/std-lives.orb +1 -1
  63. package/behaviors/registry/ui/game/atoms/std-loop-lock.orb +785 -0
  64. package/behaviors/registry/ui/game/atoms/std-pad-lock.orb +933 -0
  65. package/behaviors/registry/ui/game/atoms/std-patrol-hazard.orb +190 -44
  66. package/behaviors/registry/ui/game/atoms/std-platformer-body.orb +1330 -653
  67. package/behaviors/registry/ui/game/atoms/std-velocity-gate.orb +1040 -0
  68. package/behaviors/registry/ui/game/atoms/std-zone-card.orb +642 -0
  69. package/behaviors/registry/ui/game/organisms/std-arcade-board-3d.orb +8 -4
  70. package/behaviors/registry/ui/game/organisms/std-crew-board-2d.orb +6 -3
  71. package/behaviors/registry/ui/game/organisms/std-dungeon-board-2d.orb +10 -5
  72. package/behaviors/registry/ui/game/organisms/std-market-board-3d.orb +8 -4
  73. package/behaviors/registry/ui/game/organisms/std-objective-board-3d.orb +8 -4
  74. package/behaviors/registry/ui/game/organisms/std-platformer-board-2d.orb +36 -1
  75. package/behaviors/registry/ui/game/organisms/std-survival-board-3d.orb +8 -4
  76. package/behaviors/registry/ui/game/organisms/std-tactics-board-2d.orb +12 -6
  77. package/behaviors/registry/ui/game/organisms/std-tactics-board-3d.orb +8 -4
  78. package/behaviors/registry/ui/game/organisms/std-worldmap-board-2d.orb +6 -3
  79. package/behaviors/registry/ui/learning/atoms/std-learn-slope-probe.orb +1 -1
  80. package/behaviors/registry/ui/marketing/atoms/std-marketing-article.orb +2 -1
  81. package/behaviors/registry/ui/marketing/atoms/std-marketing-footer.orb +2 -1
  82. package/behaviors/registry/ui/marketing/atoms/std-marketing-split.orb +2 -1
  83. package/behaviors/registry/ui/marketing/atoms/std-marketing-stats.orb +2 -1
  84. package/behaviors/registry/ui/marketing/atoms/std-marketing-steps.orb +2 -1
  85. package/behaviors/registry/ui/marketing/atoms/std-marketing-team.orb +2 -1
  86. package/dist/behaviors/exports-reader.js +10971 -6255
  87. package/dist/behaviors/functions/index.d.ts +1205 -256
  88. package/dist/behaviors/functions/index.js +10932 -6245
  89. package/dist/behaviors/index.d.ts +1 -1
  90. package/dist/behaviors/index.js +10972 -6256
  91. package/dist/behaviors/query.js +10971 -6255
  92. package/dist/behaviors-embeddings.hash.json +3 -3
  93. package/dist/behaviors-embeddings.json +485 -469
  94. package/dist/behaviors-registry.json +6125 -2940
  95. package/dist/index.d.ts +1 -1
  96. package/dist/index.js +10972 -6256
  97. package/dist/knob-embeddings.hash.json +3 -3
  98. package/dist/knob-embeddings.json +1 -1
  99. package/dist/registry/factory-signatures.json +1 -1
  100. package/package.json +4 -4
  101. package/behaviors/lolo/ui/core/atoms/std-rich-editor.lolo +0 -790
  102. package/behaviors/registry/ui/core/atoms/std-rich-editor.orb +0 -2225
@@ -0,0 +1,213 @@
1
+ app ui-document-panel "1.0.0"
2
+ "DocumentPanel — a record rendered as one continuous document: editable title over the rich-text body, editing controls tucked into the header corner. — UI factory (1:1 with the @almadar/ui document-panel pattern)."
3
+ ;; @capabilities "document page, note editor, wiki page, article editor, writing surface, rich text document, content editing canvas"
4
+ orbital DocumentPanelOrbital {
5
+ type DocumentPanelLoaded = Event { data : [DocumentPanelItem] } "DocumentPanel rows finished loading; payload.data holds the collection"
6
+ type DocumentPanelActionsItem = {
7
+ label : string!
8
+ event : string
9
+ icon : icon
10
+ variant : "primary" | "secondary" | "ghost" | "danger"
11
+ }
12
+
13
+ entity DocumentPanelItem [runtime] {
14
+ id : string!
15
+ title : string
16
+ value : string
17
+ }
18
+
19
+ trait DocumentPanelRender -> @rebindable DocumentPanelItem [interaction, instance] {
20
+ initial: idle
21
+
22
+ state idle {
23
+ INIT -> idle
24
+ (fetch DocumentPanelItem { emit: { success: DocumentPanelLoaded } })
25
+ (set @entity.title @config.title)
26
+ (set @entity.value @config.value)
27
+ (render-ui main {
28
+ entity: @entity
29
+ title: @entity.title
30
+ subtitle: @config.subtitle
31
+ value: @entity.value
32
+ actions: @config.actions
33
+ maxInlineActions: @config.maxInlineActions
34
+ editing: @config.editing
35
+ titleCommitEvent: @config.titleCommitEvent
36
+ contentChangeEvent: @config.contentChangeEvent
37
+ editEvent: @config.editEvent
38
+ doneEvent: @config.doneEvent
39
+ editLabel: @config.editLabel
40
+ doneLabel: @config.doneLabel
41
+ autosaveHint: @config.autosaveHint
42
+ placeholder: @config.placeholder
43
+ className: @config.className
44
+ type: document-panel
45
+ })
46
+ DocumentPanelLoaded -> idle
47
+ (render-ui main {
48
+ entity: @payload.data
49
+ title: @entity.title
50
+ subtitle: @config.subtitle
51
+ value: @entity.value
52
+ actions: @config.actions
53
+ maxInlineActions: @config.maxInlineActions
54
+ editing: @config.editing
55
+ titleCommitEvent: @config.titleCommitEvent
56
+ contentChangeEvent: @config.contentChangeEvent
57
+ editEvent: @config.editEvent
58
+ doneEvent: @config.doneEvent
59
+ editLabel: @config.editLabel
60
+ doneLabel: @config.doneLabel
61
+ autosaveHint: @config.autosaveHint
62
+ placeholder: @config.placeholder
63
+ className: @config.className
64
+ type: document-panel
65
+ })
66
+ TITLE_COMMIT -> idle
67
+ (set @entity.title ?title)
68
+ (render-ui main {
69
+ entity: @entity
70
+ title: @entity.title
71
+ subtitle: @config.subtitle
72
+ value: @entity.value
73
+ actions: @config.actions
74
+ maxInlineActions: @config.maxInlineActions
75
+ editing: @config.editing
76
+ titleCommitEvent: @config.titleCommitEvent
77
+ contentChangeEvent: @config.contentChangeEvent
78
+ editEvent: @config.editEvent
79
+ doneEvent: @config.doneEvent
80
+ editLabel: @config.editLabel
81
+ doneLabel: @config.doneLabel
82
+ autosaveHint: @config.autosaveHint
83
+ placeholder: @config.placeholder
84
+ className: @config.className
85
+ type: document-panel
86
+ })
87
+ CONTENT_CHANGE -> idle
88
+ (set @entity.value ?value)
89
+ (render-ui main {
90
+ entity: @entity
91
+ title: @entity.title
92
+ subtitle: @config.subtitle
93
+ value: @entity.value
94
+ actions: @config.actions
95
+ maxInlineActions: @config.maxInlineActions
96
+ editing: @config.editing
97
+ titleCommitEvent: @config.titleCommitEvent
98
+ contentChangeEvent: @config.contentChangeEvent
99
+ editEvent: @config.editEvent
100
+ doneEvent: @config.doneEvent
101
+ editLabel: @config.editLabel
102
+ doneLabel: @config.doneLabel
103
+ autosaveHint: @config.autosaveHint
104
+ placeholder: @config.placeholder
105
+ className: @config.className
106
+ type: document-panel
107
+ })
108
+ }
109
+
110
+ emits {
111
+ @config.titleCommitEvent -> external {
112
+ title : string!
113
+ id : string!
114
+ }
115
+ @description "Emitted when the title commits: { title, id }"
116
+ @tier "essential"
117
+ @config.contentChangeEvent -> external {
118
+ value : string!
119
+ }
120
+ @description "Forwarded to the embedded RichTextEditor's autosave stream: { value }"
121
+ @tier "essential"
122
+ @config.editEvent -> external {
123
+ id : string!
124
+ }
125
+ @description "Emitted by the header Edit affordance and a click on the read body: { id }"
126
+ @tier "essential"
127
+ @config.doneEvent -> external {
128
+ id : string!
129
+ }
130
+ @description "Emitted by the Done button that ends the editing session: { id }"
131
+ @tier "essential"
132
+ DocumentPanelLoaded
133
+ @description "DocumentPanel rows finished loading; payload.data holds the collection."
134
+ @synonyms "loaded, fetched, retrieved"
135
+ @tier "essential"
136
+ }
137
+
138
+ listens {
139
+ TITLE_COMMIT {
140
+ title : string!
141
+ id : string!
142
+ }
143
+ CONTENT_CHANGE {
144
+ value : string!
145
+ }
146
+ }
147
+
148
+ config {
149
+ title : string
150
+ @label "Title"
151
+ @description "Document title (falls back to 'Untitled' for a blank draft)"
152
+ @tier "presentation"
153
+ subtitle : string
154
+ @label "Subtitle"
155
+ @description "Muted byline under the title; hidden when empty"
156
+ @tier "presentation"
157
+ value : string
158
+ @label "Value"
159
+ @description "The document body as rich-text HTML"
160
+ @tier "presentation"
161
+ actions : [DocumentPanelActionsItem] = []
162
+ @label "Actions"
163
+ @description "Header actions (settings, history, …). At most one explicit primary stays inline; the rest live under a single '⋯' menu — the title owns its row."
164
+ @tier "presentation"
165
+ maxInlineActions : number
166
+ @label "Max Inline Actions"
167
+ @description "0 collapses even the primary action into the menu"
168
+ @tier "presentation"
169
+ editing : boolean = false
170
+ @label "Editing"
171
+ @description "false = read surface with click-to-edit body; true = live editor"
172
+ @tier "presentation"
173
+ titleCommitEvent : string = "TITLE_COMMIT"
174
+ @label "Title Commit Event"
175
+ @description "Emitted when the title commits: { title, id }"
176
+ @tier "presentation"
177
+ contentChangeEvent : string = "CONTENT_CHANGE"
178
+ @label "Content Change Event"
179
+ @description "Forwarded to the embedded RichTextEditor's autosave stream: { value }"
180
+ @tier "presentation"
181
+ editEvent : string = "EDIT"
182
+ @label "Edit Event"
183
+ @description "Emitted by the header Edit affordance and a click on the read body: { id }"
184
+ @tier "presentation"
185
+ doneEvent : string = "DONE"
186
+ @label "Done Event"
187
+ @description "Emitted by the Done button that ends the editing session: { id }"
188
+ @tier "presentation"
189
+ editLabel : string
190
+ @label "Edit Label"
191
+ @description "editLabel prop"
192
+ @tier "presentation"
193
+ doneLabel : string
194
+ @label "Done Label"
195
+ @description "doneLabel prop"
196
+ @tier "presentation"
197
+ autosaveHint : string
198
+ @label "Autosave Hint"
199
+ @description "Muted caption beside Done telling the author work persists on its own"
200
+ @tier "presentation"
201
+ placeholder : string
202
+ @label "Placeholder"
203
+ @description "Placeholder for an empty body"
204
+ @tier "presentation"
205
+ className : string
206
+ @label "Class Name"
207
+ @description "className prop"
208
+ @tier "presentation"
209
+ }
210
+ }
211
+
212
+ page "/document-panel" as DocumentPanelPage -> DocumentPanelRender
213
+ }
@@ -1,56 +1,60 @@
1
- app ui-rich-block-editor "1.0.0"
2
- "RichBlockEditor — UI factory (1:1 with the @almadar/ui rich-block-editor pattern)."
3
- orbital RichBlockEditorOrbital {
4
- type RichBlockEditorLoaded = Event { data : [RichBlockEditorItem] } "RichBlockEditor rows finished loading; payload.data holds the collection"
5
-
6
- entity RichBlockEditorItem [runtime] {
1
+ app ui-rich-text-editor "1.0.0"
2
+ "RichTextEditor — UI factory (1:1 with the @almadar/ui rich-text-editor pattern)."
3
+ orbital RichTextEditorOrbital {
4
+ entity RichTextEditorItem [runtime] {
7
5
  id : string!
6
+ value : string
8
7
  }
9
8
 
10
- trait RichBlockEditorRender -> @rebindable RichBlockEditorItem [interaction, instance] {
9
+ trait RichTextEditorRender -> @rebindable RichTextEditorItem [interaction, instance] {
11
10
  initial: idle
12
11
 
13
12
  state idle {
14
13
  INIT -> idle
15
- (fetch RichBlockEditorItem { emit: { success: RichBlockEditorLoaded } })
14
+ (set @entity.value @config.value)
16
15
  (render-ui main {
17
- initialBlocks: @entity
16
+ value: @entity.value
18
17
  onChange: @config.onChange
19
18
  changeEvent: @config.changeEvent
20
19
  readOnly: @config.readOnly
21
20
  placeholder: @config.placeholder
22
- enableBlocks: @config.enableBlocks
23
21
  showToolbar: @config.showToolbar
24
22
  className: @config.className
25
- type: rich-block-editor
23
+ type: rich-text-editor
26
24
  })
27
- RichBlockEditorLoaded -> idle
25
+ CHANGE -> idle
26
+ (set @entity.value ?value)
28
27
  (render-ui main {
29
- initialBlocks: @payload.data
28
+ value: @entity.value
30
29
  onChange: @config.onChange
31
30
  changeEvent: @config.changeEvent
32
31
  readOnly: @config.readOnly
33
32
  placeholder: @config.placeholder
34
- enableBlocks: @config.enableBlocks
35
33
  showToolbar: @config.showToolbar
36
34
  className: @config.className
37
- type: rich-block-editor
35
+ type: rich-text-editor
38
36
  })
39
37
  }
40
38
 
41
39
  emits {
42
40
  @config.onChange -> external {
43
- blocks : [object]
41
+ value : string
44
42
  }
45
43
  @description "onChange prop"
46
44
  @tier "essential"
47
- RichBlockEditorLoaded
48
- @description "RichBlockEditor rows finished loading; payload.data holds the collection."
49
- @synonyms "loaded, fetched, retrieved"
50
- @tier "essential"
45
+ }
46
+
47
+ listens {
48
+ CHANGE {
49
+ value : string
50
+ }
51
51
  }
52
52
 
53
53
  config {
54
+ value : string
55
+ @label "Value"
56
+ @description "The rich text content as HTML. Sanitized before rendering and on every change."
57
+ @tier "presentation"
54
58
  onChange : string = "CHANGE"
55
59
  @label "On Change"
56
60
  @description "onChange prop"
@@ -67,10 +71,6 @@ orbital RichBlockEditorOrbital {
67
71
  @label "Placeholder"
68
72
  @description "placeholder prop"
69
73
  @tier "presentation"
70
- enableBlocks : boolean = true
71
- @label "Enable Blocks"
72
- @description "Opt-in to the Notion-style block authoring chrome (insert toolbar, per-row +/menu gutter, turn-into menu). Off by default: the editor renders as a plain rich text surface that edits block content inline without any add-block affordances."
73
- @tier "presentation"
74
74
  showToolbar : boolean = true
75
75
  @label "Show Toolbar"
76
76
  @description "showToolbar prop"
@@ -82,5 +82,5 @@ orbital RichBlockEditorOrbital {
82
82
  }
83
83
  }
84
84
 
85
- page "/rich-block-editor" as RichBlockEditorPage -> RichBlockEditorRender
85
+ page "/rich-text-editor" as RichTextEditorPage -> RichTextEditorRender
86
86
  }
@@ -0,0 +1,93 @@
1
+ app std-area-fill "1.0.0"
2
+ "Headless area-fill mechanic: the player paints area under a curve by moving through a fill region. Listens BODY_MOVED and, per fill, accumulates height(x) × |dx| while the player is inside the fill's x-range (the per-tick step is clamped to 0.5 world units — the physical per-tick maximum — so teleports and respawns paint nothing) — height is linear interpolation of the config curve samples above the fill's baseline (the platformer body's leftSamp/rightSamp idiom). rateMode picks the rate: \"area\" (height × |dx|, default — fills fastest where the curve is tallest), \"speed\" (|dx| only, flat rate), or \"ride\" (|dx| only while the move reports skating — walking the same distance paints nothing). When a fill's filled reaches its target it flips reported and emits AREA_FILLED once (the shared entity carries the rest); each fill also stamps a frontier (x0 + span × min(1, filled/target)) so boards can shade the painted region left-to-right as the gauge grows. RESTART resets every fill. Renders nothing; boards shade the painted region and read filled/frontier from the shared entity (the render authority)."
3
+ orbital AreaFillOrbital {
4
+ type AreaFillSample = {
5
+ x : number!
6
+ y : number!
7
+ }
8
+ type AreaFill = {
9
+ id : string!
10
+ x0 : number!
11
+ x1 : number!
12
+ baseline : number!
13
+ target : number!
14
+ rateMode : string
15
+ hint : string
16
+ samples : [AreaFillSample]!
17
+ filled : number
18
+ frontier : number
19
+ reported : boolean
20
+ }
21
+
22
+ entity AreaFillData [runtime, shared] {
23
+ id : string!
24
+ fills : [AreaFill] = []
25
+ lastX : number = 0
26
+ }
27
+
28
+ trait AreaFill -> @rebindable AreaFillData [lifecycle] {
29
+ initial: active
30
+
31
+ state active {
32
+ INIT -> active
33
+ (set @entity.fills (array/map @config.fills (fn f (object/merge @f { filled: 0, frontier: (object/get @f x0), reported: false }))))
34
+ (set @entity.lastX 0)
35
+
36
+ BODY_MOVED -> active when @config.running
37
+ (let ((adx (math/abs (- @payload.x @entity.lastX))))
38
+ (set @entity.fills (array/map @entity.fills (fn f
39
+ (let ((inside (and (>= @payload.x (object/get @f x0)) (<= @payload.x (object/get @f x1)))))
40
+ (let ((leftSamp (array/last (array/filter (object/get @f samples) (fn s (<= (object/get @s x) @payload.x))))))
41
+ (let ((rightSamp (array/first (array/filter (object/get @f samples) (fn s (> (object/get @s x) @payload.x))))))
42
+ (let ((h (if (or (== @leftSamp null) (== @rightSamp null)) 0
43
+ (- (+ (object/get @leftSamp y) (* (/ (- (object/get @rightSamp y) (object/get @leftSamp y)) (- (object/get @rightSamp x) (object/get @leftSamp x))) (- @payload.x (object/get @leftSamp x)))) (object/get @f baseline)))))
44
+ (let ((step (math/min @adx 0.5)))
45
+ (let ((rate (if @inside
46
+ (if (== (object/get @f rateMode) "ride") (if @payload.skating @step 0)
47
+ (if (== (object/get @f rateMode) "speed") @step
48
+ (* @step @h)))
49
+ 0)))
50
+ (let ((newFilled (+ (object/get @f filled) @rate)))
51
+ (object/merge @f { filled: @newFilled, frontier: (+ (object/get @f x0) (* (- (object/get @f x1) (object/get @f x0)) (math/min 1 (/ @newFilled (object/get @f target))))) }))))))))))))
52
+ (set @entity.lastX @payload.x)
53
+ (let ((newly (array/filter @entity.fills (fn f (and (>= (object/get @f filled) (object/get @f target)) (== (object/get @f reported) false))))))
54
+ (if (> (array/len @newly) 0)
55
+ (do
56
+ (set @entity.fills (array/map @entity.fills (fn f (if (== (object/get @f id) (object/get (array/first @newly) id)) (object/merge @f { reported: true }) @f))))
57
+ (emit AREA_FILLED { id: (object/get (array/first @newly) id), x: @payload.x, y: @payload.y }))
58
+ null))
59
+
60
+ RESTART -> active
61
+ (set @entity.fills (array/map @config.fills (fn f (object/merge @f { filled: 0, frontier: (object/get @f x0), reported: false }))))
62
+ (set @entity.lastX 0)
63
+ }
64
+
65
+ emits {
66
+ AREA_FILLED -> external {
67
+ id : string!
68
+ x : number!
69
+ y : number!
70
+ }
71
+ @description "A fill's painted area reached its target (x, y = the player's position at completion, for burst placement). When several fills complete on one move, the first reports and the shared entity carries the rest."
72
+ @tier "domain"
73
+ }
74
+
75
+ listens {
76
+ BODY_MOVED { x : number!, y : number!, vx : number!, vy : number!, grounded : boolean!, skating : boolean!, speed : number! }
77
+ RESTART { id : string }
78
+ }
79
+
80
+ config {
81
+ running : boolean = true
82
+ @label "Running"
83
+ @description "When true, BODY_MOVED paints every fill the player moves through; toggle to freeze every fill as-is."
84
+ @tier "domain"
85
+ fills : [AreaFill] = []
86
+ @label "Fills"
87
+ @description "One row per fill region: id, x-range (x0..x1 in world units), baseline the height is measured from, target area, rateMode (area | speed | ride — default area), optional hint, and the curve samples to interpolate. filled/frontier/reported are stamped at runtime."
88
+ @tier "domain"
89
+ }
90
+ }
91
+
92
+ page "/area-fill" as AreaFillPage -> AreaFill
93
+ }
@@ -0,0 +1,100 @@
1
+ app std-choice-gate "1.0.0"
2
+ "Headless choice-gate mechanic for side-view boards: a gate of N labeled option platforms where progress stops until the player commits to an answer. Listens BODY_MOVED and judges a gate when the player stands grounded on one of its option platforms (|dx| <= reachX of the option center, |dy| <= reachY of the gate's option plane — the pad-lock touch pattern): the correct option stamps the gate solved + chosen on the shared entity and emits CHOICE_CORRECT once (a solved gate never judges again, so the path stays open); a wrong option emits CHOICE_WRONG carrying the gate id, the chosen optionId, and the option's world position, so the board can bounce the player back and float the gate's hint (the board owns the bounce — the atom only reports). RESTART unsolves every gate. Renders nothing; boards draw the option platforms and labels from the shared entity (the render authority)."
3
+ orbital ChoiceGateOrbital {
4
+ type ChoiceOption = {
5
+ id : string!
6
+ dx : number!
7
+ label : string!
8
+ correct : boolean!
9
+ }
10
+ type ChoiceGate = {
11
+ id : string!
12
+ x : number!
13
+ y : number!
14
+ hint : string
15
+ options : [ChoiceOption]!
16
+ solved : boolean
17
+ chosen : string
18
+ }
19
+
20
+ entity ChoiceGateData [runtime, shared] {
21
+ id : string!
22
+ choices : [ChoiceGate] = []
23
+ }
24
+
25
+ trait ChoiceGate -> @rebindable ChoiceGateData [lifecycle] {
26
+ initial: active
27
+
28
+ state active {
29
+ INIT -> active
30
+ (set @entity.choices (array/map @config.gates (fn g (object/merge @g { solved: false, chosen: "" }))))
31
+
32
+ BODY_MOVED -> active when @config.running
33
+ (let ((touch (array/filter @entity.choices (fn g
34
+ (and (== (object/get @g solved) false)
35
+ (> (array/len (array/filter (object/get @g options) (fn o
36
+ (and (== @payload.grounded true)
37
+ (and (<= (math/abs (- @payload.x (+ (object/get @g x) (object/get @o dx)))) @config.reachX)
38
+ (<= (math/abs (- @payload.y (object/get @g y))) @config.reachY)))))) 0))))))
39
+ (if (> (array/len @touch) 0)
40
+ (let ((g (array/first @touch)))
41
+ (let ((o (array/first (array/filter (object/get @g options) (fn oo
42
+ (and (== @payload.grounded true)
43
+ (and (<= (math/abs (- @payload.x (+ (object/get @g x) (object/get @oo dx)))) @config.reachX)
44
+ (<= (math/abs (- @payload.y (object/get @g y))) @config.reachY))))))))
45
+ (if (== (object/get @o correct) true)
46
+ (do
47
+ (set @entity.choices (array/map @entity.choices (fn c (if (== (object/get @c id) (object/get @g id)) (object/merge @c { solved: true, chosen: (object/get @o id) }) @c))))
48
+ (emit CHOICE_CORRECT { id: (object/get @g id), x: (object/get @g x), y: (object/get @g y) }))
49
+ (emit CHOICE_WRONG { id: (object/get @g id), optionId: (object/get @o id), x: (+ (object/get @g x) (object/get @o dx)), y: (object/get @g y) }))))
50
+ null))
51
+
52
+ RESTART -> active
53
+ (set @entity.choices (array/map @config.gates (fn g (object/merge @g { solved: false, chosen: "" }))))
54
+ }
55
+
56
+ emits {
57
+ CHOICE_CORRECT -> external {
58
+ id : string!
59
+ x : number!
60
+ y : number!
61
+ }
62
+ @description "The player landed grounded on the gate's correct option; fires once per gate (solved gates stop judging). Carries the gate center so boards can burst the unlock there."
63
+ @tier "domain"
64
+ CHOICE_WRONG -> external {
65
+ id : string!
66
+ optionId : string!
67
+ x : number!
68
+ y : number!
69
+ }
70
+ @description "The player landed grounded on a wrong option; carries the gate id, the chosen optionId, and the option's world position so boards can bounce the player back to the approach and float the gate's hint."
71
+ @tier "domain"
72
+ }
73
+
74
+ listens {
75
+ BODY_MOVED { x : number!, y : number!, vx : number!, vy : number!, grounded : boolean!, skating : boolean!, speed : number! }
76
+ RESTART { id : string }
77
+ }
78
+
79
+ config {
80
+ running : boolean = true
81
+ @label "Running"
82
+ @description "When true, BODY_MOVED judges option landings; toggle to freeze every gate as-is."
83
+ @tier "domain"
84
+ gates : [ChoiceGate] = []
85
+ @label "Choice Gates"
86
+ @description "One row per gate: id, gate center (x, y — y is the option-platform surface the judge tests against), the hint floated on a wrong answer, and the options: id, dx offset from the gate center, the label drawn above the platform, and correct. solved/chosen are stamped at runtime."
87
+ @tier "domain"
88
+ reachX : number = 0.7
89
+ @label "Reach X"
90
+ @description "Horizontal tolerance (world units) around an option platform's center when testing a landing (approximates the body's half-width plus a step)."
91
+ @tier "domain"
92
+ reachY : number = 1.2
93
+ @label "Reach Y"
94
+ @description "Vertical tolerance (world units) around the gate's option plane when testing a landing (covers small hops onto the platform surface)."
95
+ @tier "domain"
96
+ }
97
+ }
98
+
99
+ page "/choice-gate" as ChoiceGatePage -> ChoiceGate
100
+ }
@@ -0,0 +1,114 @@
1
+ app std-coef-pad "1.0.0"
2
+ "Headless coefficient-pad mechanic for graph-riding boards: floor pads that reshape the road the player is riding (y = a·f(x−h) + k). Listens BODY_MOVED and, when the player stands grounded on an unapplied pad (|dx| <= reachX, |dy| <= reachY of the pad center — the pad-lock touch pattern), stamps the pad applied on the shared entity and emits COEF_PAD_APPLIED carrying the pad position AND its mod (x0, x1, a, h, k), so the board can append the mod to the body authority's curveMods (std-platformer-body with curveModsEnabled) and hop the player onto the reshaped surface. When every pad is applied it emits COEF_PAD_SET_COMPLETED once. RESTART un-applies every pad (the board clears curveMods alongside — the pad reports, the board owns the road). Renders nothing; boards draw the pads and read applied from the shared entity (the render authority)."
3
+ orbital CoefPadOrbital {
4
+ type CoefMod = {
5
+ x0 : number!
6
+ x1 : number!
7
+ a : number!
8
+ h : number!
9
+ k : number!
10
+ }
11
+ type CoefModSample = {
12
+ x : number!
13
+ y : number!
14
+ }
15
+ type CoefPad = {
16
+ id : string!
17
+ x : number!
18
+ y : number!
19
+ mod : CoefMod!
20
+ glyph : string
21
+ hint : string
22
+ hop : boolean
23
+ samples : [CoefModSample]
24
+ applied : boolean
25
+ }
26
+
27
+ entity CoefPadData [runtime, shared] {
28
+ id : string!
29
+ coefPads : [CoefPad] = []
30
+ coefCompleted : boolean = false
31
+ }
32
+
33
+ trait CoefPadLock -> @rebindable CoefPadData [lifecycle] {
34
+ initial: active
35
+
36
+ state active {
37
+ INIT -> active
38
+ (set @entity.coefPads (array/map @config.coefPads (fn p (object/merge @p { applied: false }))))
39
+ (set @entity.coefCompleted false)
40
+
41
+ BODY_MOVED -> active when @config.running
42
+ (let ((touch (array/filter @entity.coefPads (fn p
43
+ (and (== (object/get @p applied) false)
44
+ (and (== @payload.grounded true)
45
+ (and (<= (math/abs (- @payload.x (object/get @p x))) @config.reachX)
46
+ (<= (math/abs (- @payload.y (object/get @p y))) @config.reachY))))))))
47
+ (if (> (array/len @touch) 0)
48
+ (let ((p (array/first @touch)))
49
+ (let ((m (object/get @p mod)))
50
+ (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
+ (do
52
+ (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
+ (if (and (== @entity.coefCompleted false) (== @remaining 0))
55
+ (do
56
+ (set @entity.coefCompleted true)
57
+ (emit COEF_PAD_SET_COMPLETED {}))
58
+ null)))))
59
+ null))
60
+
61
+ RESTART -> active
62
+ (set @entity.coefPads (array/map @config.coefPads (fn p (object/merge @p { applied: false }))))
63
+ (set @entity.coefCompleted false)
64
+ }
65
+
66
+ emits {
67
+ COEF_PAD_APPLIED -> external {
68
+ id : string!
69
+ x : number!
70
+ y : number!
71
+ x0 : number!
72
+ x1 : number!
73
+ a : number!
74
+ h : number!
75
+ k : number!
76
+ hint : string
77
+ hop : boolean
78
+ samples : [CoefModSample]
79
+ }
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."
81
+ @tier "domain"
82
+ COEF_PAD_SET_COMPLETED -> external {
83
+ }
84
+ @description "Every coefficient pad in the set is applied; fires once per run. Boards layer the completion fx and dismiss the zone card."
85
+ @tier "domain"
86
+ }
87
+
88
+ listens {
89
+ BODY_MOVED { x : number!, y : number!, vx : number!, vy : number!, grounded : boolean!, skating : boolean!, speed : number! }
90
+ RESTART { id : string }
91
+ }
92
+
93
+ config {
94
+ running : boolean = true
95
+ @label "Running"
96
+ @description "When true, BODY_MOVED applies touched pads; toggle to freeze every pad as-is."
97
+ @tier "domain"
98
+ coefPads : [CoefPad] = []
99
+ @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."
101
+ @tier "domain"
102
+ reachX : number = 0.7
103
+ @label "Reach X"
104
+ @description "Horizontal tolerance (world units) around a pad's center when testing player contact (approximates the body's half-width plus a step)."
105
+ @tier "domain"
106
+ reachY : number = 1.2
107
+ @label "Reach Y"
108
+ @description "Vertical tolerance (world units) around a pad's center when testing player contact (covers riding the surface the pad sits on)."
109
+ @tier "domain"
110
+ }
111
+ }
112
+
113
+ page "/coef-pad" as CoefPadPage -> CoefPadLock
114
+ }
@@ -0,0 +1,50 @@
1
+ app std-curve-fog "1.0.0"
2
+ "Headless prediction-fog mechanic for graph-riding boards: in configured world regions the road ahead is only partially REVEALED — the atom listens BODY_MOVED and stamps fogX (the reveal horizon = player x + the region's lookAhead) onto the shared entity, and the board's render layer clips or ghosts every road sample past it, so the player must commit to jumps before the landing is visible and internalize where the function GOES (blowup, flattening, slow growth, divergence). Outside every region fogX sits at a large sentinel, i.e. fully revealed. Physics is untouched: the collider keeps the whole curve — the fog is purely visual. Renders nothing; boards clip their own curve/region samples against @entity.fogX (the render authority)."
3
+ orbital CurveFogOrbital {
4
+ type CurveFogRegion = {
5
+ x0 : number!
6
+ x1 : number!
7
+ lookAhead : number!
8
+ }
9
+
10
+ entity CurveFogData [runtime, shared] {
11
+ id : string!
12
+ fogX : number = 99999
13
+ }
14
+
15
+ trait CurveFog -> @rebindable CurveFogData [lifecycle] {
16
+ initial: active
17
+
18
+ state active {
19
+ INIT -> active
20
+ (set @entity.fogX 99999)
21
+
22
+ BODY_MOVED -> active when @config.running
23
+ (let ((rmatch (array/filter @config.regions (fn r (and (>= @payload.x (object/get @r x0)) (< @payload.x (object/get @r x1)))))))
24
+ (if (> (array/len @rmatch) 0)
25
+ (set @entity.fogX (+ @payload.x (object/get (array/first @rmatch) lookAhead)))
26
+ (set @entity.fogX 99999)))
27
+
28
+ RESTART -> active
29
+ (set @entity.fogX 99999)
30
+ }
31
+
32
+ listens {
33
+ BODY_MOVED { x : number!, y : number!, vx : number!, vy : number!, grounded : boolean!, skating : boolean!, speed : number! }
34
+ RESTART { id : string }
35
+ }
36
+
37
+ config {
38
+ running : boolean = true
39
+ @label "Running"
40
+ @description "When true, BODY_MOVED tracks the reveal horizon; toggle to freeze the fog where it is."
41
+ @tier "domain"
42
+ regions : [CurveFogRegion] = []
43
+ @label "Fog Regions"
44
+ @description "One row per fogged world span: x-range (x0..x1) and lookAhead — how far past the player the road stays revealed while inside. Small values force prediction (blowups), large values suit slow tail lessons. Empty list = no fog anywhere."
45
+ @tier "domain"
46
+ }
47
+ }
48
+
49
+ page "/curve-fog" as CurveFogPage -> CurveFog
50
+ }