@almadar/std 16.254.0 → 16.255.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 (455) hide show
  1. package/behaviors/lolo/agent/atoms/std-agent-pool.lolo +10 -10
  2. package/behaviors/lolo/agent/evals/eval-agent-builder.lolo +15 -8
  3. package/behaviors/lolo/agent/organisms/std-agent-builder.lolo +6 -5
  4. package/behaviors/registry/agent/atoms/std-agent-context.orb +1 -1
  5. package/behaviors/registry/agent/atoms/std-agent-fix-loop.orb +1 -1
  6. package/behaviors/registry/agent/atoms/std-agent-planner.orb +1 -1
  7. package/behaviors/registry/agent/atoms/std-agent-pool.orb +1 -1
  8. package/behaviors/registry/agent/atoms/std-agent-proposal.orb +1 -1
  9. package/behaviors/registry/agent/atoms/std-agent-session.orb +1 -1
  10. package/behaviors/registry/agent/atoms/std-agent-suggestions.orb +1 -1
  11. package/behaviors/registry/agent/atoms/std-agent-tool-call.orb +1 -1
  12. package/behaviors/registry/agent/atoms/std-agent-tool-loop.orb +1 -1
  13. package/behaviors/registry/agent/atoms/std-agent-trace.orb +1 -1
  14. package/behaviors/registry/agent/evals/eval-agent-builder.orb +1 -1
  15. package/behaviors/registry/agent/organisms/std-agent-assistant.orb +1 -1
  16. package/behaviors/registry/agent/organisms/std-agent-builder.orb +1 -1
  17. package/behaviors/registry/infra/atoms/std-analytics.orb +1 -1
  18. package/behaviors/registry/infra/atoms/std-approval-gate.orb +1 -1
  19. package/behaviors/registry/infra/atoms/std-audit-capture.orb +1 -1
  20. package/behaviors/registry/infra/atoms/std-cache-aside.orb +1 -1
  21. package/behaviors/registry/infra/atoms/std-calendar-sync.orb +1 -1
  22. package/behaviors/registry/infra/atoms/std-cascade-on-delete.orb +1 -1
  23. package/behaviors/registry/infra/atoms/std-circuit-breaker.orb +1 -1
  24. package/behaviors/registry/infra/atoms/std-cross-reference.orb +1 -1
  25. package/behaviors/registry/infra/atoms/std-data-erasure.orb +1 -1
  26. package/behaviors/registry/infra/atoms/std-data-import.orb +1 -1
  27. package/behaviors/registry/infra/atoms/std-global-search.orb +1 -1
  28. package/behaviors/registry/infra/atoms/std-knowledge-loop.orb +1 -1
  29. package/behaviors/registry/infra/atoms/std-lifecycle.orb +1 -1
  30. package/behaviors/registry/infra/atoms/std-migration-job.orb +1 -1
  31. package/behaviors/registry/infra/atoms/std-mod-queue.orb +1 -1
  32. package/behaviors/registry/infra/atoms/std-notification-center.orb +1 -1
  33. package/behaviors/registry/infra/atoms/std-notification-preferences.orb +1 -1
  34. package/behaviors/registry/infra/atoms/std-notify-on-event.orb +1 -1
  35. package/behaviors/registry/infra/atoms/std-page-search.orb +1 -1
  36. package/behaviors/registry/infra/atoms/std-page-watch.orb +1 -1
  37. package/behaviors/registry/infra/atoms/std-permission-matrix.orb +1 -1
  38. package/behaviors/registry/infra/atoms/std-rate-limiter.orb +1 -1
  39. package/behaviors/registry/infra/atoms/std-reminder-scheduler.orb +1 -1
  40. package/behaviors/registry/infra/atoms/std-review-cycle.orb +1 -1
  41. package/behaviors/registry/infra/atoms/std-row-access-control.orb +1 -1
  42. package/behaviors/registry/infra/atoms/std-status-lifecycle.orb +1 -1
  43. package/behaviors/registry/infra/organisms/std-status-lifecycle-control.orb +1 -1
  44. package/behaviors/registry/ml/atoms/std-data-collector.orb +1 -1
  45. package/behaviors/registry/ml/atoms/std-graph-builder.orb +1 -1
  46. package/behaviors/registry/ml/atoms/std-ml-classify.orb +1 -1
  47. package/behaviors/registry/ml/atoms/std-ml-exact-check.orb +1 -1
  48. package/behaviors/registry/ml/atoms/std-ml-infer.orb +1 -1
  49. package/behaviors/registry/ml/atoms/std-ml-posterior.orb +1 -1
  50. package/behaviors/registry/ml/atoms/std-ml-similarity.orb +1 -1
  51. package/behaviors/registry/ml/atoms/std-tokenizer.orb +1 -1
  52. package/behaviors/registry/ml/atoms/std-weight-validator.orb +1 -1
  53. package/behaviors/registry/ml/organisms/std-escalating-decision.orb +1 -1
  54. package/behaviors/registry/ml/organisms/std-knowledge-tracing.orb +1 -1
  55. package/behaviors/registry/ui/avl/atoms/std-avl-cosmic-zoom.orb +1 -1
  56. package/behaviors/registry/ui/avl/atoms/ui-avl-glyph.orb +1 -1
  57. package/behaviors/registry/ui/avl/atoms/ui-avl-state-machine.orb +1 -1
  58. package/behaviors/registry/ui/avl/atoms/ui-avl-transition-detail.orb +1 -1
  59. package/behaviors/registry/ui/avl/atoms/ui-avl-transition-explainer.orb +1 -1
  60. package/behaviors/registry/ui/avl/atoms/ui-behavior-view.orb +1 -1
  61. package/behaviors/registry/ui/avl/atoms/ui-module-card.orb +1 -1
  62. package/behaviors/registry/ui/avl/organisms/ui-flow-canvas.orb +1 -1
  63. package/behaviors/registry/ui/avl/organisms/ui-layers-panel.orb +1 -1
  64. package/behaviors/registry/ui/avl/organisms/ui-orb-inspector.orb +1 -1
  65. package/behaviors/registry/ui/core/atoms/std-app-layout.orb +1 -1
  66. package/behaviors/registry/ui/core/atoms/std-app-search.orb +1 -1
  67. package/behaviors/registry/ui/core/atoms/std-behavior-catalog.orb +1 -1
  68. package/behaviors/registry/ui/core/atoms/std-behavior-tour.orb +1 -1
  69. package/behaviors/registry/ui/core/atoms/std-billable-hour.orb +1 -1
  70. package/behaviors/registry/ui/core/atoms/std-board.orb +1 -1
  71. package/behaviors/registry/ui/core/atoms/std-book-reader.orb +1 -1
  72. package/behaviors/registry/ui/core/atoms/std-browse.orb +1 -1
  73. package/behaviors/registry/ui/core/atoms/std-calendar.orb +1 -1
  74. package/behaviors/registry/ui/core/atoms/std-card-grid.orb +1 -1
  75. package/behaviors/registry/ui/core/atoms/std-confirmation.orb +1 -1
  76. package/behaviors/registry/ui/core/atoms/std-dashboard-grid-embedded.orb +1 -1
  77. package/behaviors/registry/ui/core/atoms/std-date-range.orb +1 -1
  78. package/behaviors/registry/ui/core/atoms/std-detail-layout.orb +1 -1
  79. package/behaviors/registry/ui/core/atoms/std-doc-page.orb +1 -1
  80. package/behaviors/registry/ui/core/atoms/std-esign-flow.orb +1 -1
  81. package/behaviors/registry/ui/core/atoms/std-esign-request.orb +1 -1
  82. package/behaviors/registry/ui/core/atoms/std-event-log.orb +1 -1
  83. package/behaviors/registry/ui/core/atoms/std-export.orb +1 -1
  84. package/behaviors/registry/ui/core/atoms/std-file-store.orb +1 -1
  85. package/behaviors/registry/ui/core/atoms/std-filter.orb +1 -1
  86. package/behaviors/registry/ui/core/atoms/std-form-advanced.orb +1 -1
  87. package/behaviors/registry/ui/core/atoms/std-gallery.orb +1 -1
  88. package/behaviors/registry/ui/core/atoms/std-gantt-schedule.orb +1 -1
  89. package/behaviors/registry/ui/core/atoms/std-geosearch.orb +1 -1
  90. package/behaviors/registry/ui/core/atoms/std-graphs.orb +1 -1
  91. package/behaviors/registry/ui/core/atoms/std-hero.orb +1 -1
  92. package/behaviors/registry/ui/core/atoms/std-home.orb +1 -1
  93. package/behaviors/registry/ui/core/atoms/std-image-upload-multi.orb +1 -1
  94. package/behaviors/registry/ui/core/atoms/std-import.orb +1 -1
  95. package/behaviors/registry/ui/core/atoms/std-language-picker.orb +1 -1
  96. package/behaviors/registry/ui/core/atoms/std-media-section.orb +1 -1
  97. package/behaviors/registry/ui/core/atoms/std-modal-editor.orb +1 -1
  98. package/behaviors/registry/ui/core/atoms/std-modal.orb +1 -1
  99. package/behaviors/registry/ui/core/atoms/std-multi-party-flow.orb +1 -1
  100. package/behaviors/registry/ui/core/atoms/std-notification-panel.orb +1 -1
  101. package/behaviors/registry/ui/core/atoms/std-panel-launcher.orb +1 -1
  102. package/behaviors/registry/ui/core/atoms/std-pricing.orb +1 -1
  103. package/behaviors/registry/ui/core/atoms/std-proof.orb +1 -1
  104. package/behaviors/registry/ui/core/atoms/std-prose.orb +1 -1
  105. package/behaviors/registry/ui/core/atoms/std-rating-review.orb +1 -1
  106. package/behaviors/registry/ui/core/atoms/std-record-detail.orb +1 -1
  107. package/behaviors/registry/ui/core/atoms/std-recurrence.orb +1 -1
  108. package/behaviors/registry/ui/core/atoms/std-related.orb +1 -1
  109. package/behaviors/registry/ui/core/atoms/std-role-gate.orb +1 -1
  110. package/behaviors/registry/ui/core/atoms/std-saved-search.orb +1 -1
  111. package/behaviors/registry/ui/core/atoms/std-scatter.orb +1 -1
  112. package/behaviors/registry/ui/core/atoms/std-scoped-list.orb +1 -1
  113. package/behaviors/registry/ui/core/atoms/std-search.orb +1 -1
  114. package/behaviors/registry/ui/core/atoms/std-selection.orb +1 -1
  115. package/behaviors/registry/ui/core/atoms/std-site-footer.orb +1 -1
  116. package/behaviors/registry/ui/core/atoms/std-site-header.orb +1 -1
  117. package/behaviors/registry/ui/core/atoms/std-slide-deck.orb +1 -1
  118. package/behaviors/registry/ui/core/atoms/std-stat-band.orb +1 -1
  119. package/behaviors/registry/ui/core/atoms/std-stats.orb +1 -1
  120. package/behaviors/registry/ui/core/atoms/std-step-flow.orb +1 -1
  121. package/behaviors/registry/ui/core/atoms/std-steps.orb +1 -1
  122. package/behaviors/registry/ui/core/atoms/std-tabs.orb +1 -1
  123. package/behaviors/registry/ui/core/atoms/std-tag-strip.orb +1 -1
  124. package/behaviors/registry/ui/core/atoms/std-tag-taxonomy.orb +1 -1
  125. package/behaviors/registry/ui/core/atoms/std-thread.orb +1 -1
  126. package/behaviors/registry/ui/core/atoms/std-tree.orb +1 -1
  127. package/behaviors/registry/ui/core/atoms/std-version-history.orb +1 -1
  128. package/behaviors/registry/ui/core/atoms/std-wizard.orb +1 -1
  129. package/behaviors/registry/ui/core/atoms/std-workspace-layout.orb +1 -1
  130. package/behaviors/registry/ui/core/atoms/ui-animated-graphic.orb +1 -1
  131. package/behaviors/registry/ui/core/atoms/ui-animated-reveal.orb +1 -1
  132. package/behaviors/registry/ui/core/atoms/ui-aside.orb +1 -1
  133. package/behaviors/registry/ui/core/atoms/ui-atlas-image.orb +1 -1
  134. package/behaviors/registry/ui/core/atoms/ui-atlas-panel.orb +1 -1
  135. package/behaviors/registry/ui/core/atoms/ui-avatar.orb +1 -1
  136. package/behaviors/registry/ui/core/atoms/ui-badge.orb +1 -1
  137. package/behaviors/registry/ui/core/atoms/ui-box.orb +1 -1
  138. package/behaviors/registry/ui/core/atoms/ui-button.orb +1 -1
  139. package/behaviors/registry/ui/core/atoms/ui-card.orb +1 -1
  140. package/behaviors/registry/ui/core/atoms/ui-center.orb +1 -1
  141. package/behaviors/registry/ui/core/atoms/ui-checkbox.orb +1 -1
  142. package/behaviors/registry/ui/core/atoms/ui-conditional-wrapper.orb +1 -1
  143. package/behaviors/registry/ui/core/atoms/ui-confetti-effect.orb +1 -1
  144. package/behaviors/registry/ui/core/atoms/ui-day-cell.orb +1 -1
  145. package/behaviors/registry/ui/core/atoms/ui-dialog.orb +1 -1
  146. package/behaviors/registry/ui/core/atoms/ui-divider.orb +1 -1
  147. package/behaviors/registry/ui/core/atoms/ui-filter-pill.orb +1 -1
  148. package/behaviors/registry/ui/core/atoms/ui-flip-container.orb +1 -1
  149. package/behaviors/registry/ui/core/atoms/ui-game-icon.orb +1 -1
  150. package/behaviors/registry/ui/core/atoms/ui-hstack.orb +1 -1
  151. package/behaviors/registry/ui/core/atoms/ui-icon.orb +1 -1
  152. package/behaviors/registry/ui/core/atoms/ui-image.orb +1 -1
  153. package/behaviors/registry/ui/core/atoms/ui-infinite-scroll-sentinel.orb +1 -1
  154. package/behaviors/registry/ui/core/atoms/ui-input.orb +1 -1
  155. package/behaviors/registry/ui/core/atoms/ui-label.orb +1 -1
  156. package/behaviors/registry/ui/core/atoms/ui-law-reference-tooltip.orb +1 -1
  157. package/behaviors/registry/ui/core/atoms/ui-overlay.orb +1 -1
  158. package/behaviors/registry/ui/core/atoms/ui-pattern-tile.orb +1 -1
  159. package/behaviors/registry/ui/core/atoms/ui-presence.orb +1 -1
  160. package/behaviors/registry/ui/core/atoms/ui-progress-bar.orb +1 -1
  161. package/behaviors/registry/ui/core/atoms/ui-radio.orb +1 -1
  162. package/behaviors/registry/ui/core/atoms/ui-range-slider.orb +1 -1
  163. package/behaviors/registry/ui/core/atoms/ui-section-header.orb +1 -1
  164. package/behaviors/registry/ui/core/atoms/ui-select.orb +1 -1
  165. package/behaviors/registry/ui/core/atoms/ui-spacer.orb +1 -1
  166. package/behaviors/registry/ui/core/atoms/ui-sparkline.orb +1 -1
  167. package/behaviors/registry/ui/core/atoms/ui-spinner.orb +1 -1
  168. package/behaviors/registry/ui/core/atoms/ui-stack.orb +1 -1
  169. package/behaviors/registry/ui/core/atoms/ui-status-dot.orb +1 -1
  170. package/behaviors/registry/ui/core/atoms/ui-svg-branch.orb +1 -1
  171. package/behaviors/registry/ui/core/atoms/ui-svg-connection.orb +1 -1
  172. package/behaviors/registry/ui/core/atoms/ui-svg-flow.orb +1 -1
  173. package/behaviors/registry/ui/core/atoms/ui-svg-grid.orb +1 -1
  174. package/behaviors/registry/ui/core/atoms/ui-svg-lobe.orb +1 -1
  175. package/behaviors/registry/ui/core/atoms/ui-svg-mesh.orb +1 -1
  176. package/behaviors/registry/ui/core/atoms/ui-svg-morph.orb +1 -1
  177. package/behaviors/registry/ui/core/atoms/ui-svg-node.orb +1 -1
  178. package/behaviors/registry/ui/core/atoms/ui-svg-pulse.orb +1 -1
  179. package/behaviors/registry/ui/core/atoms/ui-svg-ring.orb +1 -1
  180. package/behaviors/registry/ui/core/atoms/ui-svg-shield.orb +1 -1
  181. package/behaviors/registry/ui/core/atoms/ui-svg-stack.orb +1 -1
  182. package/behaviors/registry/ui/core/atoms/ui-switch.orb +1 -1
  183. package/behaviors/registry/ui/core/atoms/ui-text-highlight.orb +1 -1
  184. package/behaviors/registry/ui/core/atoms/ui-textarea.orb +1 -1
  185. package/behaviors/registry/ui/core/atoms/ui-theme-toggle.orb +1 -1
  186. package/behaviors/registry/ui/core/atoms/ui-time-slot-cell.orb +1 -1
  187. package/behaviors/registry/ui/core/atoms/ui-trend-indicator.orb +1 -1
  188. package/behaviors/registry/ui/core/atoms/ui-typewriter-text.orb +1 -1
  189. package/behaviors/registry/ui/core/atoms/ui-typography.orb +1 -1
  190. package/behaviors/registry/ui/core/atoms/ui-video-embed.orb +1 -1
  191. package/behaviors/registry/ui/core/atoms/ui-vstack.orb +1 -1
  192. package/behaviors/registry/ui/core/molecules/std-stat-rows.orb +1 -1
  193. package/behaviors/registry/ui/core/molecules/ui-accordion.orb +1 -1
  194. package/behaviors/registry/ui/core/molecules/ui-activation-block.orb +1 -1
  195. package/behaviors/registry/ui/core/molecules/ui-activity-rail.orb +1 -1
  196. package/behaviors/registry/ui/core/molecules/ui-agent-activity-feed.orb +1 -1
  197. package/behaviors/registry/ui/core/molecules/ui-agent-activity-row.orb +1 -1
  198. package/behaviors/registry/ui/core/molecules/ui-agent-chat-feed.orb +1 -1
  199. package/behaviors/registry/ui/core/molecules/ui-alert.orb +1 -1
  200. package/behaviors/registry/ui/core/molecules/ui-animated-counter.orb +1 -1
  201. package/behaviors/registry/ui/core/molecules/ui-bloom-quiz-block.orb +1 -1
  202. package/behaviors/registry/ui/core/molecules/ui-branching-logic-builder.orb +1 -1
  203. package/behaviors/registry/ui/core/molecules/ui-breadcrumb.orb +1 -1
  204. package/behaviors/registry/ui/core/molecules/ui-calendar-grid.orb +1 -1
  205. package/behaviors/registry/ui/core/molecules/ui-carousel.orb +1 -1
  206. package/behaviors/registry/ui/core/molecules/ui-change-list.orb +1 -1
  207. package/behaviors/registry/ui/core/molecules/ui-chart-legend.orb +1 -1
  208. package/behaviors/registry/ui/core/molecules/ui-chart.orb +1 -1
  209. package/behaviors/registry/ui/core/molecules/ui-code-block.orb +1 -1
  210. package/behaviors/registry/ui/core/molecules/ui-command-palette.orb +1 -1
  211. package/behaviors/registry/ui/core/molecules/ui-commit-row.orb +1 -1
  212. package/behaviors/registry/ui/core/molecules/ui-confirm-dialog.orb +1 -1
  213. package/behaviors/registry/ui/core/molecules/ui-connection-block.orb +1 -1
  214. package/behaviors/registry/ui/core/molecules/ui-container.orb +1 -1
  215. package/behaviors/registry/ui/core/molecules/ui-content-renderer.orb +1 -1
  216. package/behaviors/registry/ui/core/molecules/ui-data-grid.orb +1 -1
  217. package/behaviors/registry/ui/core/molecules/ui-data-list.orb +1 -1
  218. package/behaviors/registry/ui/core/molecules/ui-date-range-picker.orb +1 -1
  219. package/behaviors/registry/ui/core/molecules/ui-date-range-selector.orb +1 -1
  220. package/behaviors/registry/ui/core/molecules/ui-doc-breadcrumb.orb +1 -1
  221. package/behaviors/registry/ui/core/molecules/ui-doc-pagination.orb +1 -1
  222. package/behaviors/registry/ui/core/molecules/ui-doc-search.orb +1 -1
  223. package/behaviors/registry/ui/core/molecules/ui-doc-sidebar.orb +1 -1
  224. package/behaviors/registry/ui/core/molecules/ui-doc-toc.orb +1 -1
  225. package/behaviors/registry/ui/core/molecules/ui-document-details.orb +1 -1
  226. package/behaviors/registry/ui/core/molecules/ui-document-panel.orb +1 -1
  227. package/behaviors/registry/ui/core/molecules/ui-document-viewer.orb +1 -1
  228. package/behaviors/registry/ui/core/molecules/ui-drawer.orb +1 -1
  229. package/behaviors/registry/ui/core/molecules/ui-edge-decoration.orb +1 -1
  230. package/behaviors/registry/ui/core/molecules/ui-emoji-picker.orb +1 -1
  231. package/behaviors/registry/ui/core/molecules/ui-empty-state.orb +1 -1
  232. package/behaviors/registry/ui/core/molecules/ui-error-boundary.orb +1 -1
  233. package/behaviors/registry/ui/core/molecules/ui-error-state.orb +1 -1
  234. package/behaviors/registry/ui/core/molecules/ui-feature-card.orb +1 -1
  235. package/behaviors/registry/ui/core/molecules/ui-feature-grid.orb +1 -1
  236. package/behaviors/registry/ui/core/molecules/ui-file-tree.orb +1 -1
  237. package/behaviors/registry/ui/core/molecules/ui-filter-group.orb +1 -1
  238. package/behaviors/registry/ui/core/molecules/ui-flex.orb +1 -1
  239. package/behaviors/registry/ui/core/molecules/ui-flip-card.orb +1 -1
  240. package/behaviors/registry/ui/core/molecules/ui-floating-action-button.orb +1 -1
  241. package/behaviors/registry/ui/core/molecules/ui-floating-toolbar.orb +1 -1
  242. package/behaviors/registry/ui/core/molecules/ui-form-actions.orb +1 -1
  243. package/behaviors/registry/ui/core/molecules/ui-form-field.orb +1 -1
  244. package/behaviors/registry/ui/core/molecules/ui-form-layout.orb +1 -1
  245. package/behaviors/registry/ui/core/molecules/ui-form-section-header.orb +1 -1
  246. package/behaviors/registry/ui/core/molecules/ui-fx-overlay.orb +1 -1
  247. package/behaviors/registry/ui/core/molecules/ui-gantt.orb +1 -1
  248. package/behaviors/registry/ui/core/molecules/ui-geometric-pattern.orb +1 -1
  249. package/behaviors/registry/ui/core/molecules/ui-gradient-divider.orb +1 -1
  250. package/behaviors/registry/ui/core/molecules/ui-graph-canvas.orb +1 -1
  251. package/behaviors/registry/ui/core/molecules/ui-graph-view.orb +1 -1
  252. package/behaviors/registry/ui/core/molecules/ui-grid.orb +1 -1
  253. package/behaviors/registry/ui/core/molecules/ui-header.orb +1 -1
  254. package/behaviors/registry/ui/core/molecules/ui-icon-button.orb +1 -1
  255. package/behaviors/registry/ui/core/molecules/ui-import-preview-tree.orb +1 -1
  256. package/behaviors/registry/ui/core/molecules/ui-import-progress.orb +1 -1
  257. package/behaviors/registry/ui/core/molecules/ui-import-source-picker.orb +1 -1
  258. package/behaviors/registry/ui/core/molecules/ui-input-group.orb +1 -1
  259. package/behaviors/registry/ui/core/molecules/ui-jazari-state-machine.orb +1 -1
  260. package/behaviors/registry/ui/core/molecules/ui-lightbox.orb +1 -1
  261. package/behaviors/registry/ui/core/molecules/ui-likert-scale.orb +1 -1
  262. package/behaviors/registry/ui/core/molecules/ui-line-chart.orb +1 -1
  263. package/behaviors/registry/ui/core/molecules/ui-loading-state.orb +1 -1
  264. package/behaviors/registry/ui/core/molecules/ui-map-view.orb +1 -1
  265. package/behaviors/registry/ui/core/molecules/ui-markdown-content.orb +1 -1
  266. package/behaviors/registry/ui/core/molecules/ui-matrix-question.orb +1 -1
  267. package/behaviors/registry/ui/core/molecules/ui-menu.orb +1 -1
  268. package/behaviors/registry/ui/core/molecules/ui-meter.orb +1 -1
  269. package/behaviors/registry/ui/core/molecules/ui-modal.orb +1 -1
  270. package/behaviors/registry/ui/core/molecules/ui-navigation.orb +1 -1
  271. package/behaviors/registry/ui/core/molecules/ui-notification.orb +1 -1
  272. package/behaviors/registry/ui/core/molecules/ui-number-stepper.orb +1 -1
  273. package/behaviors/registry/ui/core/molecules/ui-option-constraint-group.orb +1 -1
  274. package/behaviors/registry/ui/core/molecules/ui-orbital-visualization.orb +1 -1
  275. package/behaviors/registry/ui/core/molecules/ui-page-header.orb +1 -1
  276. package/behaviors/registry/ui/core/molecules/ui-page-transition.orb +1 -1
  277. package/behaviors/registry/ui/core/molecules/ui-pagination.orb +1 -1
  278. package/behaviors/registry/ui/core/molecules/ui-popover.orb +1 -1
  279. package/behaviors/registry/ui/core/molecules/ui-positioned-canvas.orb +1 -1
  280. package/behaviors/registry/ui/core/molecules/ui-progress-dots.orb +1 -1
  281. package/behaviors/registry/ui/core/molecules/ui-pull-to-refresh.orb +1 -1
  282. package/behaviors/registry/ui/core/molecules/ui-qr-scanner.orb +1 -1
  283. package/behaviors/registry/ui/core/molecules/ui-quiz-block.orb +1 -1
  284. package/behaviors/registry/ui/core/molecules/ui-reflection-block.orb +1 -1
  285. package/behaviors/registry/ui/core/molecules/ui-relation-select.orb +1 -1
  286. package/behaviors/registry/ui/core/molecules/ui-repeatable-form-section.orb +1 -1
  287. package/behaviors/registry/ui/core/molecules/ui-reply-tree.orb +1 -1
  288. package/behaviors/registry/ui/core/molecules/ui-rich-text-editor.orb +1 -1
  289. package/behaviors/registry/ui/core/molecules/ui-scaled-diagram.orb +1 -1
  290. package/behaviors/registry/ui/core/molecules/ui-search-input.orb +1 -1
  291. package/behaviors/registry/ui/core/molecules/ui-section.orb +1 -1
  292. package/behaviors/registry/ui/core/molecules/ui-side-panel.orb +1 -1
  293. package/behaviors/registry/ui/core/molecules/ui-sidebar.orb +1 -1
  294. package/behaviors/registry/ui/core/molecules/ui-signature-pad.orb +1 -1
  295. package/behaviors/registry/ui/core/molecules/ui-simple-grid.orb +1 -1
  296. package/behaviors/registry/ui/core/molecules/ui-skeleton.orb +1 -1
  297. package/behaviors/registry/ui/core/molecules/ui-social-proof.orb +1 -1
  298. package/behaviors/registry/ui/core/molecules/ui-sortable-list.orb +1 -1
  299. package/behaviors/registry/ui/core/molecules/ui-split.orb +1 -1
  300. package/behaviors/registry/ui/core/molecules/ui-star-rating.orb +1 -1
  301. package/behaviors/registry/ui/core/molecules/ui-stat-display.orb +1 -1
  302. package/behaviors/registry/ui/core/molecules/ui-swipeable-row.orb +1 -1
  303. package/behaviors/registry/ui/core/molecules/ui-table-view.orb +1 -1
  304. package/behaviors/registry/ui/core/molecules/ui-tabs.orb +1 -1
  305. package/behaviors/registry/ui/core/molecules/ui-tag-input.orb +1 -1
  306. package/behaviors/registry/ui/core/molecules/ui-tooltip.orb +1 -1
  307. package/behaviors/registry/ui/core/molecules/ui-top-nav-item.orb +1 -1
  308. package/behaviors/registry/ui/core/molecules/ui-upload-drop-zone.orb +1 -1
  309. package/behaviors/registry/ui/core/molecules/ui-version-diff.orb +1 -1
  310. package/behaviors/registry/ui/core/molecules/ui-violation-alert.orb +1 -1
  311. package/behaviors/registry/ui/core/molecules/ui-vote-stack.orb +1 -1
  312. package/behaviors/registry/ui/core/molecules/ui-wizard-container.orb +1 -1
  313. package/behaviors/registry/ui/core/molecules/ui-wizard-navigation.orb +1 -1
  314. package/behaviors/registry/ui/core/molecules/ui-wizard-progress.orb +1 -1
  315. package/behaviors/registry/ui/core/organisms/ui-chat-bar.orb +1 -1
  316. package/behaviors/registry/ui/core/organisms/ui-code-runner-panel.orb +1 -1
  317. package/behaviors/registry/ui/core/organisms/ui-dashboard-grid.orb +1 -1
  318. package/behaviors/registry/ui/core/organisms/ui-detail-panel.orb +1 -1
  319. package/behaviors/registry/ui/core/organisms/ui-dock-layout.orb +1 -1
  320. package/behaviors/registry/ui/core/organisms/ui-drawer-slot.orb +1 -1
  321. package/behaviors/registry/ui/core/organisms/ui-form-section.orb +1 -1
  322. package/behaviors/registry/ui/core/organisms/ui-form.orb +1 -1
  323. package/behaviors/registry/ui/core/organisms/ui-master-detail-layout.orb +1 -1
  324. package/behaviors/registry/ui/core/organisms/ui-media-gallery.orb +1 -1
  325. package/behaviors/registry/ui/core/organisms/ui-modal-slot.orb +1 -1
  326. package/behaviors/registry/ui/core/organisms/ui-runtime-debugger.orb +1 -1
  327. package/behaviors/registry/ui/core/organisms/ui-segment-renderer.orb +1 -1
  328. package/behaviors/registry/ui/core/organisms/ui-split-pane.orb +1 -1
  329. package/behaviors/registry/ui/core/organisms/ui-stat-card.orb +1 -1
  330. package/behaviors/registry/ui/core/organisms/ui-state-machine-view.orb +1 -1
  331. package/behaviors/registry/ui/core/organisms/ui-subagent-trace-panel.orb +1 -1
  332. package/behaviors/registry/ui/core/organisms/ui-tabbed-container.orb +1 -1
  333. package/behaviors/registry/ui/core/organisms/ui-timeline.orb +1 -1
  334. package/behaviors/registry/ui/core/organisms/ui-toast-slot.orb +1 -1
  335. package/behaviors/registry/ui/core/templates/ui-auth-layout.orb +1 -1
  336. package/behaviors/registry/ui/core/templates/ui-counter-template.orb +1 -1
  337. package/behaviors/registry/ui/core/templates/ui-dashboard-layout.orb +1 -1
  338. package/behaviors/registry/ui/core/templates/ui-generic-app-template.orb +1 -1
  339. package/behaviors/registry/ui/game/atoms/std-arcade-play.orb +1 -1
  340. package/behaviors/registry/ui/game/atoms/std-area-fill.orb +1 -1
  341. package/behaviors/registry/ui/game/atoms/std-audio-cue.orb +1 -1
  342. package/behaviors/registry/ui/game/atoms/std-camera-rig.orb +1 -1
  343. package/behaviors/registry/ui/game/atoms/std-chase-ai.orb +1 -1
  344. package/behaviors/registry/ui/game/atoms/std-choice-gate.orb +1 -1
  345. package/behaviors/registry/ui/game/atoms/std-coef-pad.orb +1 -1
  346. package/behaviors/registry/ui/game/atoms/std-curve-fog.orb +1 -1
  347. package/behaviors/registry/ui/game/atoms/std-dungeon-combat.orb +1 -1
  348. package/behaviors/registry/ui/game/atoms/std-fx-narrative.orb +1 -1
  349. package/behaviors/registry/ui/game/atoms/std-fx-particles.orb +1 -1
  350. package/behaviors/registry/ui/game/atoms/std-fx-trail.orb +1 -1
  351. package/behaviors/registry/ui/game/atoms/std-gate-lock.orb +1 -1
  352. package/behaviors/registry/ui/game/atoms/std-gather.orb +1 -1
  353. package/behaviors/registry/ui/game/atoms/std-gold.orb +1 -1
  354. package/behaviors/registry/ui/game/atoms/std-grid-tactics.orb +1 -1
  355. package/behaviors/registry/ui/game/atoms/std-hero-nav.orb +1 -1
  356. package/behaviors/registry/ui/game/atoms/std-lives.orb +1 -1
  357. package/behaviors/registry/ui/game/atoms/std-loop-lock.orb +1 -1
  358. package/behaviors/registry/ui/game/atoms/std-market-flow.orb +1 -1
  359. package/behaviors/registry/ui/game/atoms/std-motion-body.orb +1 -1
  360. package/behaviors/registry/ui/game/atoms/std-objective-reach.orb +1 -1
  361. package/behaviors/registry/ui/game/atoms/std-pad-lock.orb +1 -1
  362. package/behaviors/registry/ui/game/atoms/std-patience.orb +1 -1
  363. package/behaviors/registry/ui/game/atoms/std-patrol-hazard.orb +1 -1
  364. package/behaviors/registry/ui/game/atoms/std-pickup.orb +1 -1
  365. package/behaviors/registry/ui/game/atoms/std-platformer-body.orb +1 -1
  366. package/behaviors/registry/ui/game/atoms/std-production.orb +1 -1
  367. package/behaviors/registry/ui/game/atoms/std-score.orb +1 -1
  368. package/behaviors/registry/ui/game/atoms/std-tutorial-autodemo.orb +1 -1
  369. package/behaviors/registry/ui/game/atoms/std-tutorial-overlay.orb +1 -1
  370. package/behaviors/registry/ui/game/atoms/std-velocity-gate.orb +1 -1
  371. package/behaviors/registry/ui/game/atoms/std-xp.orb +1 -1
  372. package/behaviors/registry/ui/game/atoms/std-zone-card.orb +1 -1
  373. package/behaviors/registry/ui/game/atoms/ui-action-palette.orb +1 -1
  374. package/behaviors/registry/ui/game/atoms/ui-action-tile.orb +1 -1
  375. package/behaviors/registry/ui/game/atoms/ui-canvas-2d.orb +1 -1
  376. package/behaviors/registry/ui/game/atoms/ui-canvas.orb +1 -1
  377. package/behaviors/registry/ui/game/atoms/ui-choice-button.orb +1 -1
  378. package/behaviors/registry/ui/game/atoms/ui-control-button.orb +1 -1
  379. package/behaviors/registry/ui/game/atoms/ui-control-grid.orb +1 -1
  380. package/behaviors/registry/ui/game/atoms/ui-dialogue-bubble.orb +1 -1
  381. package/behaviors/registry/ui/game/atoms/ui-draw-fx-layer.orb +1 -1
  382. package/behaviors/registry/ui/game/atoms/ui-draw-group.orb +1 -1
  383. package/behaviors/registry/ui/game/atoms/ui-draw-mesh.orb +1 -1
  384. package/behaviors/registry/ui/game/atoms/ui-draw-shape-layer.orb +1 -1
  385. package/behaviors/registry/ui/game/atoms/ui-draw-shape.orb +1 -1
  386. package/behaviors/registry/ui/game/atoms/ui-draw-skinned-mesh.orb +1 -1
  387. package/behaviors/registry/ui/game/atoms/ui-draw-sprite-layer.orb +1 -1
  388. package/behaviors/registry/ui/game/atoms/ui-draw-sprite.orb +1 -1
  389. package/behaviors/registry/ui/game/atoms/ui-draw-text-layer.orb +1 -1
  390. package/behaviors/registry/ui/game/atoms/ui-draw-text.orb +1 -1
  391. package/behaviors/registry/ui/game/atoms/ui-game-audio-cue.orb +1 -1
  392. package/behaviors/registry/ui/game/atoms/ui-game-audio-toggle.orb +1 -1
  393. package/behaviors/registry/ui/game/atoms/ui-game-hud.orb +1 -1
  394. package/behaviors/registry/ui/game/atoms/ui-game-menu.orb +1 -1
  395. package/behaviors/registry/ui/game/atoms/ui-health-bar.orb +1 -1
  396. package/behaviors/registry/ui/game/atoms/ui-score-display.orb +1 -1
  397. package/behaviors/registry/ui/game/atoms/ui-sequence-bar.orb +1 -1
  398. package/behaviors/registry/ui/game/atoms/ui-stat-badge.orb +1 -1
  399. package/behaviors/registry/ui/game/atoms/ui-state-graph.orb +1 -1
  400. package/behaviors/registry/ui/game/atoms/ui-state-json-view.orb +1 -1
  401. package/behaviors/registry/ui/game/atoms/ui-timer-display.orb +1 -1
  402. package/behaviors/registry/ui/game/atoms/ui-trait-slot.orb +1 -1
  403. package/behaviors/registry/ui/game/organisms/std-arcade-board-3d.orb +1 -1
  404. package/behaviors/registry/ui/game/organisms/std-crew-board-2d.orb +1 -1
  405. package/behaviors/registry/ui/game/organisms/std-dungeon-board-2d.orb +1 -1
  406. package/behaviors/registry/ui/game/organisms/std-market-board-3d.orb +1 -1
  407. package/behaviors/registry/ui/game/organisms/std-objective-board-3d.orb +1 -1
  408. package/behaviors/registry/ui/game/organisms/std-platformer-board-2d.orb +1 -1
  409. package/behaviors/registry/ui/game/organisms/std-platformer-puzzle.orb +1 -1
  410. package/behaviors/registry/ui/game/organisms/std-survival-board-3d.orb +1 -1
  411. package/behaviors/registry/ui/game/organisms/std-tactics-board-2d.orb +1 -1
  412. package/behaviors/registry/ui/game/organisms/std-tactics-board-3d.orb +1 -1
  413. package/behaviors/registry/ui/game/organisms/std-worldmap-board-2d.orb +1 -1
  414. package/behaviors/registry/ui/game/templates/ui-game-shell.orb +1 -1
  415. package/behaviors/registry/ui/learning/atoms/std-learn-arrangement.orb +1 -1
  416. package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1 -1
  417. package/behaviors/registry/ui/learning/atoms/std-learn-compare.orb +1 -1
  418. package/behaviors/registry/ui/learning/atoms/std-learn-coupled-sim.orb +1 -1
  419. package/behaviors/registry/ui/learning/atoms/std-learn-derivation.orb +1 -1
  420. package/behaviors/registry/ui/learning/atoms/std-learn-diagram.orb +1 -1
  421. package/behaviors/registry/ui/learning/atoms/std-learn-doser.orb +1 -1
  422. package/behaviors/registry/ui/learning/atoms/std-learn-estimate.orb +1 -1
  423. package/behaviors/registry/ui/learning/atoms/std-learn-fx-cues.orb +1 -1
  424. package/behaviors/registry/ui/learning/atoms/std-learn-generate.orb +1 -1
  425. package/behaviors/registry/ui/learning/atoms/std-learn-goal-seek.orb +1 -1
  426. package/behaviors/registry/ui/learning/atoms/std-learn-grid-sim.orb +1 -1
  427. package/behaviors/registry/ui/learning/atoms/std-learn-hotspot.orb +1 -1
  428. package/behaviors/registry/ui/learning/atoms/std-learn-live-sim.orb +1 -1
  429. package/behaviors/registry/ui/learning/atoms/std-learn-measure.orb +1 -1
  430. package/behaviors/registry/ui/learning/atoms/std-learn-param-explorer.orb +1 -1
  431. package/behaviors/registry/ui/learning/atoms/std-learn-perturb.orb +1 -1
  432. package/behaviors/registry/ui/learning/atoms/std-learn-predict.orb +1 -1
  433. package/behaviors/registry/ui/learning/atoms/std-learn-sample-accumulator.orb +1 -1
  434. package/behaviors/registry/ui/learning/atoms/std-learn-sandbox.orb +1 -1
  435. package/behaviors/registry/ui/learning/atoms/std-learn-scatter-fit.orb +1 -1
  436. package/behaviors/registry/ui/learning/atoms/std-learn-scenario.orb +1 -1
  437. package/behaviors/registry/ui/learning/atoms/std-learn-sim-3d.orb +1 -1
  438. package/behaviors/registry/ui/learning/atoms/std-learn-slope-probe.orb +1 -1
  439. package/behaviors/registry/ui/learning/atoms/std-learn-speed-drill.orb +1 -1
  440. package/behaviors/registry/ui/learning/atoms/std-learn-stepper.orb +1 -1
  441. package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +1 -1
  442. package/behaviors/registry/ui/learning/atoms/std-learn-trace-player.orb +1 -1
  443. package/behaviors/registry/ui/learning/atoms/std-learn-transport.orb +1 -1
  444. package/behaviors/registry/ui/learning/atoms/std-learn-tree.orb +1 -1
  445. package/behaviors/registry/ui/learning/atoms/ui-algo-graph-canvas.orb +1 -1
  446. package/behaviors/registry/ui/learning/atoms/ui-algorithm-canvas.orb +1 -1
  447. package/behaviors/registry/ui/learning/atoms/ui-biology-canvas.orb +1 -1
  448. package/behaviors/registry/ui/learning/atoms/ui-chemistry-canvas.orb +1 -1
  449. package/behaviors/registry/ui/learning/atoms/ui-learning-canvas.orb +1 -1
  450. package/behaviors/registry/ui/learning/atoms/ui-math-canvas.orb +1 -1
  451. package/behaviors/registry/ui/learning/atoms/ui-physics-canvas.orb +1 -1
  452. package/dist/behaviors-embeddings.hash.json +1 -1
  453. package/dist/behaviors-embeddings.json +1 -1
  454. package/dist/knob-embeddings.hash.json +1 -1
  455. package/package.json +1 -1
@@ -1 +1 @@
1
- {"name":"std-platformer-body","version":"1.0.0","description":"Headless run/jump platformer-physics authority: the SOLE writer of body + fell + hazardId + goalId on side-view boards. Where std-motion-body owns free 2D drift (no collision), this atom owns the platformer contract: every 33ms physics tick it integrates gravity into the body's vertical velocity, steps position in per-second units, and collides the body rect against the platform set with one-way semantics — a body moving in the gravity direction that overlaps a ground/platform tile lands on its anti-gravity face (vy zeroed, grounded set), while a body moving against gravity passes through, so jumping up through a platform and walking up a staircase both just work. The sign of gravity IS the vertical convention: positive pulls toward +y (screen boards, y down — sprite canvases), negative toward −y (math canvases, y up); jumps always fire against it. Geometry lives on the shared entity: config platforms/skateCurve/driftRegions seed entity.platforms/skateCurve/driftRegions on INIT, and SET_PLATFORMS / SET_SKATE_CURVE / SET_DRIFT_REGIONS replace them at runtime (RESTART keeps the live set, so boards that import geometry never lose it on a respawn). Intents: STEER sets horizontal velocity (dir −1/0/1 × moveSpeed, hold-to-run: keydown steers, keyup steers 0), JUMP kicks vertical velocity when grounded, PLACE teleports (spawns, hazard respawns), RESTART reseeds. Emits BODY_MOVED every tick for the render layer (boards that don't subscribe pay nothing), plus the sparse rule signals a board needs to score: BODY_JUMPED, BODY_LANDED (with impact speed), BODY_HAZARD (once per hazard entry, re-arms on exit), BODY_GOAL (same arming), BODY_FELL (once per fall past killY, re-armed by PLACE/RESTART). Drift regions: the driftRegions set lists axis-aligned rects each carrying a constant acceleration (ax, ay) applied with the same 0.033s dt whenever the body's center is inside (empty list = zero behavior change). Curve skating: when config.skate is on and the grounded body comes within skateSnap of the skateCurve surface, the body rides the curve — y snaps to the interpolated surface and tangential gravity (g·slope/(1+slope²)) accelerates vx, and the vertical velocity is the tangential projection (s = vx·cos θ, vy = s·sin θ — no discontinuous jumps at sample boundaries), so the body slides downhill along the graph itself and launches ballistically off its ends; jumping kicks free. Sparse BODY_SKATE_START/BODY_SKATE_END signals fire on engage/disengage so boards can layer fx. Lives, score, and win/lose stay downstream — this atom simulates, it never judges. Renders nothing. Corresponds to the design-sheet field(s): mechanics, dynamics.","orbitals":[{"name":"PlatformerBodyOrbital","id":"orb_54HMS7B1FXGQYPPHAY703PPVKA","entity":{"name":"PlatformerBodyData","id":"ent_A7ZJPNY5DJ2PS13VH2GY789CSY","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"body","type":"object","default":{"x":0,"y":0,"width":1,"height":1,"vx":0,"vy":0,"grounded":false,"facingRight":true},"properties":{"y":{"name":"y","type":"number","required":true},"facingRight":{"name":"facingRight","type":"boolean","required":false},"vx":{"name":"vx","type":"number","required":false},"width":{"name":"width","type":"number","required":true},"grounded":{"name":"grounded","type":"boolean","required":false},"height":{"name":"height","type":"number","required":true},"x":{"name":"x","type":"number","required":true},"vy":{"name":"vy","type":"number","required":false}}},{"name":"fell","type":"boolean","default":false},{"name":"hazardId","type":"string","default":""},{"name":"curveMods","type":"array","default":[],"items":{"type":"object","properties":{"x0":{"name":"x0","type":"number","required":true},"a":{"name":"a","type":"number","required":true},"k":{"name":"k","type":"number","required":true},"h":{"name":"h","type":"number","required":true},"b":{"name":"b","type":"number","required":true},"x1":{"name":"x1","type":"number","required":true}}}},{"name":"goalId","type":"string","default":""},{"name":"skating","type":"boolean","default":false},{"name":"tuning","type":"object","default":{},"properties":{"moveSpeed":{"name":"moveSpeed","type":"number","required":false},"jumpStrength":{"name":"jumpStrength","type":"number","required":false},"gravity":{"name":"gravity","type":"number","required":false}}},{"name":"platforms","type":"array","default":[],"items":{"type":"object","properties":{"type":{"name":"type","type":"string","required":false,"values":["ground","platform","hazard","goal"]},"width":{"name":"width","type":"number","required":true},"y":{"name":"y","type":"number","required":true},"x":{"name":"x","type":"number","required":true},"height":{"name":"height","type":"number","required":true},"id":{"name":"id","type":"string","required":false}}}},{"name":"skateCurve","type":"array","default":[],"items":{"type":"object","properties":{"y":{"name":"y","type":"number","required":true},"x":{"name":"x","type":"number","required":true}}}},{"name":"driftRegions","type":"array","default":[],"items":{"type":"object","properties":{"x1":{"name":"x1","type":"number","required":true},"ax":{"name":"ax","type":"number","required":true},"y0":{"name":"y0","type":"number","required":true},"y1":{"name":"y1","type":"number","required":true},"x0":{"name":"x0","type":"number","required":true},"ay":{"name":"ay","type":"number","required":true},"id":{"name":"id","type":"string","required":true}}}}],"shared":true},"traits":[{"name":"PlatformerBody","id":"trt_VA39R1HDYAPZ589GFPQ0MKP546","entityRebindable":true,"entityContract":{"requires":[],"provides":["body","curveMods","driftRegions","fell","goalId","hazardId","platforms","skateCurve","skating","tuning"]},"effectRow":[{"kind":"emit","resource":"BODY_FELL","site":"tick"},{"kind":"emit","resource":"BODY_GOAL","site":"tick"},{"kind":"emit","resource":"BODY_HAZARD","site":"tick"},{"kind":"emit","resource":"BODY_JUMPED"},{"kind":"emit","resource":"BODY_LANDED","site":"tick"},{"kind":"emit","resource":"BODY_MOVED","site":"tick"},{"kind":"emit","resource":"BODY_SKATE_END","site":"tick"},{"kind":"emit","resource":"BODY_SKATE_START","site":"tick"},{"kind":"set","resource":"@entity.body"},{"kind":"set","resource":"@entity.body","site":"tick"},{"kind":"set","resource":"@entity.curveMods"},{"kind":"set","resource":"@entity.driftRegions"},{"kind":"set","resource":"@entity.fell"},{"kind":"set","resource":"@entity.fell","site":"tick"},{"kind":"set","resource":"@entity.goalId"},{"kind":"set","resource":"@entity.goalId","site":"tick"},{"kind":"set","resource":"@entity.hazardId"},{"kind":"set","resource":"@entity.hazardId","site":"tick"},{"kind":"set","resource":"@entity.platforms"},{"kind":"set","resource":"@entity.skateCurve"},{"kind":"set","resource":"@entity.skating"},{"kind":"set","resource":"@entity.skating","site":"tick"},{"kind":"set","resource":"@entity.tuning"},{"kind":"ticks","site":"tick"}],"category":"lifecycle","linkedEntity":"PlatformerBodyData","linkedEntityId":"ent_A7ZJPNY5DJ2PS13VH2GY789CSY","entityRefIds":{"PlatformerBodyData":"ent_A7ZJPNY5DJ2PS13VH2GY789CSY"},"emits":[{"event":"BODY_MOVED","eventId":"evt_WY87E1EKCM9PAFP30EZWRZKZFF","description":"The body after this physics tick: position, velocity, grounded and skating flags, and scalar speed; render layers subscribe (or read the shared entity), rule layers stay on the sparse signals","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"vx","type":"number","required":true},{"name":"vy","type":"number","required":true},{"name":"grounded","type":"boolean","required":true},{"name":"skating","type":"boolean","required":true},{"name":"speed","type":"number","required":true}]},{"event":"BODY_SKATE_START","eventId":"evt_PAWHGPPPEAB758CQZE2AYX2BNR","description":"Body engaged curve skating this tick (grounded, landing, or falling within skateSnap above the skateCurve surface); slope is the local dy/dx — boards layer fx and equation readouts","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"slope","type":"number","required":true}]},{"event":"BODY_SKATE_END","eventId":"evt_RPPVFS60MX0AEM56ES6Z8GWP74","description":"Body left the curve surface (jumped, walked past an end, or drifted beyond skateSnap); boards tear down skate fx","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"event":"BODY_JUMPED","eventId":"evt_VJRT208AVB5DNGBM3J1R457RK5","description":"Jump accepted (grounded at intent time) and vertical velocity kicked against gravity; boards layer squash/sound fx","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"event":"BODY_LANDED","eventId":"evt_ZCJ5PWZSM7WT3NVFXNQ6BJMZ7N","description":"Body transitioned airborne → standing on a ground/platform tile this tick; impact is the pre-landing fall speed in units/s so boards can scale dust or damage","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"impact","type":"number","required":true}]},{"event":"BODY_HAZARD","eventId":"evt_ZJW67CKM7WT3Y4HXM1Z24FRYRY","description":"Body entered overlap with a hazard tile; fires once per entry and re-arms only after the body leaves, so damage rules stay sparse","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"event":"BODY_GOAL","eventId":"evt_RGZ62G9546JJ305W6TDY541PJ3","description":"Body entered overlap with a goal tile; fires once per entry and re-arms only after the body leaves — the board's win-rule trigger","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"event":"BODY_FELL","eventId":"evt_ST1PCXK3S7HWKVMSBBMW27TKGD","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","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"event":"CURVE_MOD_CLEAR","eventId":"evt_36FSC21301HG0J36JH17NNYM72","description":"Curve mods were cleared; the skate surface is back to the base skateCurve until a new mod is added.","tier":"domain","scope":"external"}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_HSH6JP60B305HGTJ7M9NWYZPZS","name":"Initialize"},{"key":"STEER","id":"evt_ZVFCCENK9YSMZE5VY9T23HNFKS","name":"Steer","payloadSchema":[{"name":"dir","type":"number","required":true}],"listened":true},{"key":"JUMP","id":"evt_J41SC9XB9TNMX3SYPA1ZEDW0ST","name":"Jump","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"PLACE","id":"evt_84A26KRJ7193GK69ZFSP81GYZP","name":"Place","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}],"listened":true},{"key":"CURVE_MOD_ADD","id":"evt_54GKJEJ23E11Q73QA0J8GPQJZB","name":"Curve Mod Add","payloadSchema":[{"name":"x0","type":"number","required":true},{"name":"x1","type":"number","required":true},{"name":"a","type":"number","required":true},{"name":"b","type":"number"},{"name":"h","type":"number","required":true},{"name":"k","type":"number","required":true}],"listened":true},{"key":"CURVE_MOD_CLEAR","id":"evt_36FSC21301HG0J36JH17NNYM72","name":"Curve Mod Clear","description":"Curve mods were cleared; the skate surface is back to the base skateCurve until a new mod is added.","tier":"domain","listened":true},{"key":"CURVE_MOD_CLEAR_RANGE","id":"evt_9E2WJ7YM6FA37RQXM4S6S5S60B","name":"Curve Mod Clear Range","payloadSchema":[{"name":"x0","type":"number","required":true},{"name":"x1","type":"number","required":true}],"listened":true},{"key":"SET_TUNING","id":"evt_1FEFAVHAWGNE83EN68ZXB1CF14","name":"Set Tuning","payloadSchema":[{"name":"jumpStrength","type":"number"},{"name":"moveSpeed","type":"number"},{"name":"gravity","type":"number"}],"listened":true},{"key":"SET_PLATFORMS","id":"evt_Y23D0EK681K40SRDMSJ7JFWFN1","name":"Set Platforms","payloadSchema":[{"name":"platforms","type":"[object]","required":true,"properties":[{"name":"id","type":"string"},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"width","type":"number","required":true},{"name":"height","type":"number","required":true},{"name":"type","type":"string","values":["ground","platform","hazard","goal"]}]}],"listened":true},{"key":"SET_SKATE_CURVE","id":"evt_GC76TX4HNJ8TS86KQTS8YFKCGN","name":"Set Skate Curve","payloadSchema":[{"name":"curve","type":"[object]","required":true,"properties":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]}],"listened":true},{"key":"SET_DRIFT_REGIONS","id":"evt_C8DD46GHSW8WY93Z4JR4BPQF3B","name":"Set Drift Regions","payloadSchema":[{"name":"regions","type":"[object]","required":true,"properties":[{"name":"id","type":"string","required":true},{"name":"x0","type":"number","required":true},{"name":"x1","type":"number","required":true},{"name":"y0","type":"number","required":true},{"name":"y1","type":"number","required":true},{"name":"ax","type":"number","required":true},{"name":"ay","type":"number","required":true}]}],"listened":true},{"key":"RESTART","id":"evt_NZRFJ13645K22YVZ4PV0MN57AN","name":"Restart","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"BODY_MOVED","id":"evt_WY87E1EKCM9PAFP30EZWRZKZFF","name":"Body Moved","description":"The body after this physics tick: position, velocity, grounded and skating flags, and scalar speed; render layers subscribe (or read the shared entity), rule layers stay on the sparse signals","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"vx","type":"number","required":true},{"name":"vy","type":"number","required":true},{"name":"grounded","type":"boolean","required":true},{"name":"skating","type":"boolean","required":true},{"name":"speed","type":"number","required":true}]},{"key":"BODY_SKATE_START","id":"evt_PAWHGPPPEAB758CQZE2AYX2BNR","name":"Body Skate Start","description":"Body engaged curve skating this tick (grounded, landing, or falling within skateSnap above the skateCurve surface); slope is the local dy/dx — boards layer fx and equation readouts","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"slope","type":"number","required":true}]},{"key":"BODY_SKATE_END","id":"evt_RPPVFS60MX0AEM56ES6Z8GWP74","name":"Body Skate End","description":"Body left the curve surface (jumped, walked past an end, or drifted beyond skateSnap); boards tear down skate fx","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"key":"BODY_JUMPED","id":"evt_VJRT208AVB5DNGBM3J1R457RK5","name":"Body Jumped","description":"Jump accepted (grounded at intent time) and vertical velocity kicked against gravity; boards layer squash/sound fx","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"key":"BODY_LANDED","id":"evt_ZCJ5PWZSM7WT3NVFXNQ6BJMZ7N","name":"Body Landed","description":"Body transitioned airborne → standing on a ground/platform tile this tick; impact is the pre-landing fall speed in units/s so boards can scale dust or damage","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"impact","type":"number","required":true}]},{"key":"BODY_HAZARD","id":"evt_ZJW67CKM7WT3Y4HXM1Z24FRYRY","name":"Body Hazard","description":"Body entered overlap with a hazard tile; fires once per entry and re-arms only after the body leaves, so damage rules stay sparse","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"key":"BODY_GOAL","id":"evt_RGZ62G9546JJ305W6TDY541PJ3","name":"Body Goal","description":"Body entered overlap with a goal tile; fires once per entry and re-arms only after the body leaves — the board's win-rule trigger","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"key":"BODY_FELL","id":"evt_ST1PCXK3S7HWKVMSBBMW27TKGD","name":"Body Fell","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","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_HSH6JP60B305HGTJ7M9NWYZPZS","effects":[["set","@entity.body","@config.spawn"],["set","@entity.fell",false],["set","@entity.hazardId",""],["set","@entity.goalId",""],["set","@entity.skating",false],["set","@entity.platforms","@config.platforms"],["set","@entity.skateCurve","@config.skateCurve"],["set","@entity.driftRegions","@config.driftRegions"]]},{"from":"active","to":"active","event":"STEER","eventId":"evt_ZVFCCENK9YSMZE5VY9T23HNFKS","guard":"@config.running","effects":[["set","@entity.body",["object/merge","@entity.body",{"vx":["*","@payload.dir",["if",["==",["object/get","@entity.tuning","moveSpeed",null],null],"@config.moveSpeed",["object/get","@entity.tuning","moveSpeed",null]]],"facingRight":["if",["!=","@payload.dir",0],[">","@payload.dir",0],"@entity.body.facingRight"]}]]]},{"from":"active","to":"active","event":"JUMP","eventId":"evt_J41SC9XB9TNMX3SYPA1ZEDW0ST","guard":["and","@config.running",["==","@entity.body.grounded",true]],"effects":[["set","@entity.body",["object/merge","@entity.body",{"vy":["if",[">",["if",["==",["object/get","@entity.tuning","gravity",null],null],"@config.gravity",["object/get","@entity.tuning","gravity",null]],0],["-",0,["if",["==",["object/get","@entity.tuning","jumpStrength",null],null],"@config.jumpStrength",["object/get","@entity.tuning","jumpStrength",null]]],["if",["==",["object/get","@entity.tuning","jumpStrength",null],null],"@config.jumpStrength",["object/get","@entity.tuning","jumpStrength",null]]],"grounded":false}]],["emit","BODY_JUMPED",{"x":"@entity.body.x","y":"@entity.body.y"}]]},{"from":"active","to":"active","event":"PLACE","eventId":"evt_84A26KRJ7193GK69ZFSP81GYZP","effects":[["set","@entity.body",["object/merge","@entity.body",{"x":"@payload.x","y":"@payload.y","vx":0,"vy":0,"grounded":false}]],["set","@entity.fell",false],["set","@entity.hazardId",""],["set","@entity.skating",false]]},{"from":"active","to":"active","event":"CURVE_MOD_ADD","eventId":"evt_54GKJEJ23E11Q73QA0J8GPQJZB","guard":"@config.curveModsEnabled","effects":[["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"}]]]},{"from":"active","to":"active","event":"CURVE_MOD_CLEAR","eventId":"evt_36FSC21301HG0J36JH17NNYM72","guard":"@config.curveModsEnabled","effects":[["set","@entity.curveMods",[]]]},{"from":"active","to":"active","event":"CURVE_MOD_CLEAR_RANGE","eventId":"evt_9E2WJ7YM6FA37RQXM4S6S5S60B","guard":"@config.curveModsEnabled","effects":[["set","@entity.curveMods",["array/filter","@entity.curveMods",["fn","m",["or",["<",["object/get","@m","x1"],"@payload.x0"],[">",["object/get","@m","x0"],"@payload.x1"]]]]]]},{"from":"active","to":"active","event":"SET_TUNING","eventId":"evt_1FEFAVHAWGNE83EN68ZXB1CF14","effects":[["set","@entity.tuning",["object/merge","@entity.tuning",["if",["==","@payload.jumpStrength",null],{},{"jumpStrength":"@payload.jumpStrength"}]]],["set","@entity.tuning",["object/merge","@entity.tuning",["if",["==","@payload.moveSpeed",null],{},{"moveSpeed":"@payload.moveSpeed"}]]],["set","@entity.tuning",["object/merge","@entity.tuning",["if",["==","@payload.gravity",null],{},{"gravity":"@payload.gravity"}]]]]},{"from":"active","to":"active","event":"SET_PLATFORMS","eventId":"evt_Y23D0EK681K40SRDMSJ7JFWFN1","effects":[["set","@entity.platforms","@payload.platforms"]]},{"from":"active","to":"active","event":"SET_SKATE_CURVE","eventId":"evt_GC76TX4HNJ8TS86KQTS8YFKCGN","effects":[["set","@entity.skateCurve","@payload.curve"]]},{"from":"active","to":"active","event":"SET_DRIFT_REGIONS","eventId":"evt_C8DD46GHSW8WY93Z4JR4BPQF3B","effects":[["set","@entity.driftRegions","@payload.regions"]]},{"from":"active","to":"active","event":"RESTART","eventId":"evt_NZRFJ13645K22YVZ4PV0MN57AN","effects":[["set","@entity.body","@config.spawn"],["set","@entity.curveMods",[]],["set","@entity.fell",false],["set","@entity.hazardId",""],["set","@entity.goalId",""],["set","@entity.skating",false],["set","@entity.tuning",{}]]}]},"ticks":[{"name":"physicsTick","interval":33,"guard":["and","@config.running",[">","@entity.body.width",0]],"effects":[["let",[["eg",["if",["==",["object/get","@entity.tuning","gravity",null],null],"@config.gravity",["object/get","@entity.tuning","gravity",null]]]],["let",[["gdir",["if",[">","@eg",0],1,-1]]],["let",[["bcx",["+",["object/get","@entity.body","x"],["/",["object/get","@entity.body","width"],2]]],["bcy",["+",["object/get","@entity.body","y"],["/",["object/get","@entity.body","height"],2]]]],["let",[["drift",["array/find","@entity.driftRegions",["fn","r",["and",[">=","@bcx",["object/get","@r","x0"]],["and",["<=","@bcx",["object/get","@r","x1"]],["and",[">=","@bcy",["object/get","@r","y0"]],["<=","@bcy",["object/get","@r","y1"]]]]]]]]],["let",[["dax",["if",["==","@drift",null],0,["object/get","@drift","ax"]]],["day",["if",["==","@drift",null],0,["object/get","@drift","ay"]]]],["let",[["vy1",["math/clamp",["+","@entity.body.vy",["*",["+","@eg","@day"],0.033]],["-",0,"@config.maxFallSpeed"],"@config.maxFallSpeed"]]],["let",[["bw",["object/get","@entity.body","width"]],["bh",["object/get","@entity.body","height"]]],["let",[["nx",["math/clamp",["+","@entity.body.x",["*","@entity.body.vx",0.033]],"@config.xMin","@config.xMax"]]],["let",[["ny",["+","@entity.body.y",["*","@vy1",0.033]]]],["let",[["rect",{"x":"@nx","y":"@ny","w":"@bw","h":"@bh"}]],["let",[["hit",["array/find","@entity.platforms",["fn","p",["and",["or",["==",["object/get","@p","type"],"ground"],["==",["object/get","@p","type"],"platform"]],["geo/aabb-overlap","@rect",{"x":"@p.x","y":"@p.y","w":"@p.width","h":"@p.height"}]]]]]],["let",[["landed",["and",["!=","@hit",null],[">",["*","@vy1","@gdir"],0]]]],["let",[["ny2",["if","@landed",["if",[">","@gdir",0],["-",["object/get","@hit","y"],"@bh"],["+",["object/get","@hit","y"],["object/get","@hit","height"]]],"@ny"]],["vy2",["if","@landed",0,"@vy1"]]],["let",[["cx",["+","@nx",["/","@bw",2]]]],["let",[["inRange",["and","@config.skate",["and",[">",["array/len","@entity.skateCurve"],1],["and",[">=","@cx",["object/get",["array/first","@entity.skateCurve"],"x"]],["<","@cx",["object/get",["array/last","@entity.skateCurve"],"x"]]]]]]],["let",[["leftSamp",["if","@inRange",["array/last",["array/filter","@entity.skateCurve",["fn","s",["<=",["object/get","@s","x"],"@cx"]]]],{"x":0,"y":0}]]],["let",[["rightSamp",["if","@inRange",["array/first",["array/filter","@entity.skateCurve",["fn","s",[">",["object/get","@s","x"],"@cx"]]]],{"x":1,"y":0}]]],["let",[["slope",["if","@inRange",["/",["-",["object/get","@rightSamp","y"],["object/get","@leftSamp","y"]],["-",["object/get","@rightSamp","x"],["object/get","@leftSamp","x"]]],0]]],["let",[["curveY",["if","@inRange",["+",["object/get","@leftSamp","y"],["*","@slope",["-","@cx",["object/get","@leftSamp","x"]]]],0]]],["let",[["gapBreak",["and",[">","@config.skateMaxGap",0],[">",["-",["object/get","@rightSamp","x"],["object/get","@leftSamp","x"]],"@config.skateMaxGap"]]]],["let",[["mods",["if",["and","@config.curveModsEnabled","@inRange"],["array/filter","@entity.curveMods",["fn","m",["and",[">=","@cx",["object/get","@m","x0"]],["<=","@cx",["object/get","@m","x1"]]]]],[]]]],["let",[["modded",["array/reduce","@mods",{"y":"@curveY","s":"@slope"},["fn",["acc","m"],["let",[["modX",["*",["object/get","@m","b"],["-","@cx",["object/get","@m","h"]]]]],["let",[["modInRange",["and",[">=","@modX",["object/get",["array/first","@entity.skateCurve"],"x"]],["<","@modX",["object/get",["array/last","@entity.skateCurve"],"x"]]]]],["let",[["modLeft",["if","@modInRange",["array/last",["array/filter","@entity.skateCurve",["fn","s",["<=",["object/get","@s","x"],"@modX"]]]],null]]],["let",[["modRight",["if","@modInRange",["array/first",["array/filter","@entity.skateCurve",["fn","s",[">",["object/get","@s","x"],"@modX"]]]],null]]],["let",[["modOK",["and","@modInRange",["and",["!=","@modLeft",null],["!=","@modRight",null]]]]],["let",[["modSlope",["if","@modOK",["/",["-",["object/get","@modRight","y"],["object/get","@modLeft","y"]],["-",["object/get","@modRight","x"],["object/get","@modLeft","x"]]],0]]],["let",[["modCurveY",["if","@modOK",["+",["object/get","@modLeft","y"],["*","@modSlope",["-","@modX",["object/get","@modLeft","x"]]]],0]]],["if","@modOK",{"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"]]},"@acc"]]]]]]]]]]]],["let",[["slope",["object/get","@modded","s"]]],["let",[["curveY",["object/get","@modded","y"]]],["let",[["aboveCurve",["<",["*",["-","@ny2","@curveY"],"@gdir"],0]]],["let",[["movingUp",["<",["*","@vy1","@gdir"],-0.01]]],["let",[["skateNow",["and","@inRange",["and",["not","@gapBreak"],["and",["<=",["math/abs",["-","@ny2","@curveY"]],"@config.skateSnap"],["and",["or","@landed",["or","@entity.skating",["and",["not","@movingUp"],"@aboveCurve"]]],["or","@entity.body.grounded",["not","@movingUp"]]]]]]]],["let",[["vx2",["if","@skateNow",["math/clamp",["+","@entity.body.vx",["*",["/",["*","@eg","@slope"],["+",1,["*","@slope","@slope"]]],0.033]],["-",0,"@config.maxFallSpeed"],"@config.maxFallSpeed"],"@entity.body.vx"]]],["let",[["vx3",["if",["==","@drift",null],"@vx2",["math/clamp",["+","@vx2",["*","@dax",0.033]],["-",0,"@config.maxFallSpeed"],"@config.maxFallSpeed"]]]],["let",[["fy",["if","@skateNow","@curveY","@ny2"]],["fvy",["if","@skateNow",["*",["*","@vx2",["math/cos",["math/atan","@slope"]]],["math/sin",["math/atan","@slope"]]],"@vy2"]],["fgrounded",["or","@landed","@skateNow"]]],["let",[["hazardHit",["array/find","@entity.platforms",["fn","p",["and",["==",["object/get","@p","type"],"hazard"],["geo/aabb-overlap","@rect",{"x":"@p.x","y":"@p.y","w":"@p.width","h":"@p.height"}]]]]]],["let",[["goalHit",["array/find","@entity.platforms",["fn","p",["and",["==",["object/get","@p","type"],"goal"],["geo/aabb-overlap","@rect",{"x":"@p.x","y":"@p.y","w":"@p.width","h":"@p.height"}]]]]]],["let",[["fellNow",["if",[">","@gdir",0],[">","@fy","@config.killY"],["<","@fy","@config.killY"]]]],["do",["set","@entity.body",["object/merge","@entity.body",{"x":"@nx","y":"@fy","vx":["if",["or",["==","@nx","@config.xMin"],["==","@nx","@config.xMax"]],0,"@vx3"],"vy":"@fvy","grounded":"@fgrounded"}]],["set","@entity.skating","@skateNow"],["if",["and","@skateNow",["==","@entity.skating",false]],["emit","BODY_SKATE_START",{"x":"@nx","y":"@fy","slope":"@slope"}],null],["if",["and",["==","@skateNow",false],["==","@entity.skating",true]],["emit","BODY_SKATE_END",{"x":"@nx","y":"@fy"}],null],["if",["and","@landed",["==","@entity.body.grounded",false]],["emit","BODY_LANDED",{"x":"@nx","y":"@fy","impact":["*","@vy1","@gdir"]}],null],["if",["!=","@hazardHit",null],["if",["!=","@entity.hazardId",["object/get","@hazardHit","id",""]],["do",["set","@entity.hazardId",["object/get","@hazardHit","id",""]],["emit","BODY_HAZARD",{"id":["object/get","@hazardHit","id",""],"x":"@nx","y":"@fy"}]],null],["set","@entity.hazardId",""]],["if",["!=","@goalHit",null],["if",["!=","@entity.goalId",["object/get","@goalHit","id",""]],["do",["set","@entity.goalId",["object/get","@goalHit","id",""]],["emit","BODY_GOAL",{"id":["object/get","@goalHit","id",""],"x":"@nx","y":"@fy"}]],null],["set","@entity.goalId",""]],["if",["and","@fellNow",["==","@entity.fell",false]],["do",["set","@entity.fell",true],["emit","BODY_FELL",{"x":"@nx","y":"@fy"}]],null],["emit","BODY_MOVED",{"x":"@nx","y":"@fy","vx":"@entity.body.vx","vy":"@fvy","grounded":"@fgrounded","skating":"@skateNow","speed":["math/hypot","@entity.body.vx","@fvy"]}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]}],"config":{"jumpStrength":{"type":"number","default":11,"label":"Jump Strength","description":"Vertical speed in units/s imparted by JUMP, directed against gravity; apex height ≈ jumpStrength² / (2·|gravity|)","tier":"domain"},"skateCurve":{"type":"[PlatformerCurveSample]","default":[],"label":"Skate Curve","description":"Surface samples (x strictly increasing) the body skates when skate is on; y is the surface height for the body's MIN corner, linearly interpolated between bracketing samples — mirror the render-side curve so what you see is what you ride. Seeded onto the entity on INIT; the live curve is entity.skateCurve — SET_SKATE_CURVE replaces it at runtime (stitched mega-curves) and RESTART does not reseed it.","tier":"domain","items":{"type":"object","properties":{"y":{"name":"y","type":"number","required":true},"x":{"name":"x","type":"number","required":true}}}},"maxFallSpeed":{"type":"number","default":14,"label":"Max Fall Speed","description":"Terminal velocity cap in units/s applied to vertical speed each tick","tier":"presentation"},"xMin":{"type":"number","default":-1000000,"label":"Left Wall","description":"Smallest x the body's min corner may hold (world bounds, not level geometry)","tier":"presentation"},"curveModsEnabled":{"type":"boolean","default":false,"label":"Curve Mods Enabled","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.","tier":"domain"},"xMax":{"type":"number","default":1000000,"label":"Right Wall","description":"Largest x the body's min corner may hold (world bounds, not level geometry)","tier":"presentation"},"skate":{"type":"boolean","default":false,"label":"Curve Skating","description":"When true, a grounded body within skateSnap of the skateCurve surface rides the curve: y snaps to the interpolated surface and tangential gravity (g·slope/(1+slope²)) accelerates vx, so the body slides downhill along the graph and launches off its ends; JUMP kicks free. Engages when grounded, when landing on a tile, or when a falling (not rising) body passes within skateSnap above the surface.","tier":"domain"},"driftRegions":{"type":"[BodyDriftRegion]","default":[],"label":"Drift Regions","description":"Axis-aligned rects (x0..x1, y0..y1 in world units) each carrying a constant acceleration (ax, ay in units/s²) applied with the physics dt whenever the body's center is inside — winds, currents, gradient pushes. Empty list = zero behavior change. Seeded onto the entity on INIT; the live set is entity.driftRegions — SET_DRIFT_REGIONS replaces it at runtime and RESTART does not reseed it.","tier":"domain","items":{"type":"object","properties":{"id":{"name":"id","type":"string","required":true},"ay":{"name":"ay","type":"number","required":true},"x0":{"name":"x0","type":"number","required":true},"ax":{"name":"ax","type":"number","required":true},"y0":{"name":"y0","type":"number","required":true},"x1":{"name":"x1","type":"number","required":true},"y1":{"name":"y1","type":"number","required":true}}}},"moveSpeed":{"type":"number","default":5,"label":"Move Speed","description":"Horizontal run speed in units/s applied by STEER dir ±1","tier":"domain"},"platforms":{"type":"[PlatformerPlatform]","default":[],"label":"Platforms","description":"Level geometry as min-corner rects: ground/platform tiles are solid one-way landing surfaces, hazard tiles emit BODY_HAZARD on touch, goal tiles emit BODY_GOAL. Seeded onto the entity on INIT; the live set is entity.platforms — SET_PLATFORMS replaces it at runtime (boards that import geometry, e.g. stitched open worlds) and RESTART deliberately does NOT reseed it, so injected geometry survives respawns.","tier":"domain","items":{"type":"object","properties":{"x":{"name":"x","type":"number","required":true},"height":{"name":"height","type":"number","required":true},"y":{"name":"y","type":"number","required":true},"type":{"name":"type","type":"string","required":false,"values":["ground","platform","hazard","goal"]},"id":{"name":"id","type":"string","required":false},"width":{"name":"width","type":"number","required":true}}}},"running":{"type":"boolean","default":true,"label":"Running","description":"When true the 33ms physics tick integrates and collides; toggle to freeze the body","tier":"domain"},"killY":{"type":"number","default":1000000,"label":"Kill Y","description":"Fall line: crossing it in the gravity direction fires BODY_FELL once (past it downward on y-down boards, below it on y-up canvases); y-up consumers must set a value below their world floor","tier":"domain"},"skateMaxGap":{"type":"number","default":0,"label":"Skate Max Gap","description":"Largest x-gap between consecutive skateCurve samples that still counts as surface. 0 = unlimited (sparse two-sample lines skate fine). Dense resampled curves with real gaps between segments (stitched worlds) MUST set this — otherwise the sampler invents a skatable chord across every gap (an invisible line above the bridge/terrain that the body snaps to and glides along).","tier":"domain"},"skateSnap":{"type":"number","default":0.75,"label":"Skate Snap","description":"Max vertical gap (world units) between the body's min corner and the curve surface for skating to engage or stay engaged; larger values grab earlier on landing, smaller values release sooner on bumps","tier":"domain"},"spawn":{"type":"PlatformerBody","default":{"x":2,"y":8,"width":0.6,"height":0.6,"vx":0,"vy":0,"grounded":false,"facingRight":true},"label":"Spawn Body","description":"Initial body rect (min-corner x/y plus width/height) seeded on INIT/RESTART; width/height also define the collision box","tier":"domain","properties":{"facingRight":{"name":"facingRight","type":"boolean","required":false},"height":{"name":"height","type":"number","required":true},"y":{"name":"y","type":"number","required":true},"width":{"name":"width","type":"number","required":true},"grounded":{"name":"grounded","type":"boolean","required":false},"vx":{"name":"vx","type":"number","required":false},"x":{"name":"x","type":"number","required":true},"vy":{"name":"vy","type":"number","required":false}}},"gravity":{"type":"number","default":24,"label":"Gravity","description":"Units/s² added to vertical velocity; the SIGN is the vertical convention — positive pulls toward +y (screen boards, y down), negative toward −y (math canvases, y up) — and jumps always fire against it","tier":"domain"}},"scope":"instance"}],"pages":[{"name":"PlatformerBodyPage","id":"pag_NQ4NFDQBP3NV1ZMT5J4SDDFF5T","path":"/platformer-body","traits":[{"ref":"PlatformerBody","refId":"trt_VA39R1HDYAPZ589GFPQ0MKP546"}]}],"types":{"BodyDriftRegion":[{"name":"id","type":"string","required":true},{"name":"x0","type":"number","required":true},{"name":"x1","type":"number","required":true},{"name":"y0","type":"number","required":true},{"name":"y1","type":"number","required":true},{"name":"ax","type":"number","required":true},{"name":"ay","type":"number","required":true}],"CurveMod":[{"name":"x0","type":"number","required":true},{"name":"x1","type":"number","required":true},{"name":"a","type":"number","required":true},{"name":"b","type":"number","required":true},{"name":"h","type":"number","required":true},{"name":"k","type":"number","required":true}],"PlatformerBody":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"width","type":"number","required":true},{"name":"height","type":"number","required":true},{"name":"vx","type":"number"},{"name":"vy","type":"number"},{"name":"grounded","type":"boolean"},{"name":"facingRight","type":"boolean"}],"PlatformerCurveSample":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}],"PlatformerPlatform":[{"name":"id","type":"string"},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"width","type":"number","required":true},{"name":"height","type":"number","required":true},{"name":"type","type":"string","values":["ground","platform","hazard","goal"]}],"PlatformerTuning":[{"name":"jumpStrength","type":"number"},{"name":"moveSpeed","type":"number"},{"name":"gravity","type":"number"}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_A7ZJPNY5DJ2PS13VH2GY789CSY":{"id":"ent_A7ZJPNY5DJ2PS13VH2GY789CSY","kind":"entity","bakedName":"PlatformerBodyData","curName":"PlatformerBodyData","renames":[],"owner":"workspace"},"evt_1FEFAVHAWGNE83EN68ZXB1CF14":{"id":"evt_1FEFAVHAWGNE83EN68ZXB1CF14","kind":"event","bakedName":"SET_TUNING","curName":"SET_TUNING","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_36FSC21301HG0J36JH17NNYM72":{"id":"evt_36FSC21301HG0J36JH17NNYM72","kind":"event","bakedName":"CURVE_MOD_CLEAR","curName":"CURVE_MOD_CLEAR","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_54GKJEJ23E11Q73QA0J8GPQJZB":{"id":"evt_54GKJEJ23E11Q73QA0J8GPQJZB","kind":"event","bakedName":"CURVE_MOD_ADD","curName":"CURVE_MOD_ADD","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_84A26KRJ7193GK69ZFSP81GYZP":{"id":"evt_84A26KRJ7193GK69ZFSP81GYZP","kind":"event","bakedName":"PLACE","curName":"PLACE","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_9E2WJ7YM6FA37RQXM4S6S5S60B":{"id":"evt_9E2WJ7YM6FA37RQXM4S6S5S60B","kind":"event","bakedName":"CURVE_MOD_CLEAR_RANGE","curName":"CURVE_MOD_CLEAR_RANGE","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_C8DD46GHSW8WY93Z4JR4BPQF3B":{"id":"evt_C8DD46GHSW8WY93Z4JR4BPQF3B","kind":"event","bakedName":"SET_DRIFT_REGIONS","curName":"SET_DRIFT_REGIONS","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_GC76TX4HNJ8TS86KQTS8YFKCGN":{"id":"evt_GC76TX4HNJ8TS86KQTS8YFKCGN","kind":"event","bakedName":"SET_SKATE_CURVE","curName":"SET_SKATE_CURVE","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_HSH6JP60B305HGTJ7M9NWYZPZS":{"id":"evt_HSH6JP60B305HGTJ7M9NWYZPZS","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_J41SC9XB9TNMX3SYPA1ZEDW0ST":{"id":"evt_J41SC9XB9TNMX3SYPA1ZEDW0ST","kind":"event","bakedName":"JUMP","curName":"JUMP","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_NZRFJ13645K22YVZ4PV0MN57AN":{"id":"evt_NZRFJ13645K22YVZ4PV0MN57AN","kind":"event","bakedName":"RESTART","curName":"RESTART","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_PAWHGPPPEAB758CQZE2AYX2BNR":{"id":"evt_PAWHGPPPEAB758CQZE2AYX2BNR","kind":"event","bakedName":"BODY_SKATE_START","curName":"BODY_SKATE_START","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_RGZ62G9546JJ305W6TDY541PJ3":{"id":"evt_RGZ62G9546JJ305W6TDY541PJ3","kind":"event","bakedName":"BODY_GOAL","curName":"BODY_GOAL","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_RPPVFS60MX0AEM56ES6Z8GWP74":{"id":"evt_RPPVFS60MX0AEM56ES6Z8GWP74","kind":"event","bakedName":"BODY_SKATE_END","curName":"BODY_SKATE_END","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_ST1PCXK3S7HWKVMSBBMW27TKGD":{"id":"evt_ST1PCXK3S7HWKVMSBBMW27TKGD","kind":"event","bakedName":"BODY_FELL","curName":"BODY_FELL","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_VJRT208AVB5DNGBM3J1R457RK5":{"id":"evt_VJRT208AVB5DNGBM3J1R457RK5","kind":"event","bakedName":"BODY_JUMPED","curName":"BODY_JUMPED","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_WY87E1EKCM9PAFP30EZWRZKZFF":{"id":"evt_WY87E1EKCM9PAFP30EZWRZKZFF","kind":"event","bakedName":"BODY_MOVED","curName":"BODY_MOVED","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_Y23D0EK681K40SRDMSJ7JFWFN1":{"id":"evt_Y23D0EK681K40SRDMSJ7JFWFN1","kind":"event","bakedName":"SET_PLATFORMS","curName":"SET_PLATFORMS","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_ZCJ5PWZSM7WT3NVFXNQ6BJMZ7N":{"id":"evt_ZCJ5PWZSM7WT3NVFXNQ6BJMZ7N","kind":"event","bakedName":"BODY_LANDED","curName":"BODY_LANDED","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_ZJW67CKM7WT3Y4HXM1Z24FRYRY":{"id":"evt_ZJW67CKM7WT3Y4HXM1Z24FRYRY","kind":"event","bakedName":"BODY_HAZARD","curName":"BODY_HAZARD","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_ZVFCCENK9YSMZE5VY9T23HNFKS":{"id":"evt_ZVFCCENK9YSMZE5VY9T23HNFKS","kind":"event","bakedName":"STEER","curName":"STEER","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"orb_54HMS7B1FXGQYPPHAY703PPVKA":{"id":"orb_54HMS7B1FXGQYPPHAY703PPVKA","kind":"orbital","bakedName":"PlatformerBodyOrbital","curName":"PlatformerBodyOrbital","renames":[],"owner":"workspace"},"pag_NQ4NFDQBP3NV1ZMT5J4SDDFF5T":{"id":"pag_NQ4NFDQBP3NV1ZMT5J4SDDFF5T","kind":"page","bakedName":"PlatformerBodyPage","curName":"PlatformerBodyPage","renames":[],"owner":"workspace"},"trt_VA39R1HDYAPZ589GFPQ0MKP546":{"id":"trt_VA39R1HDYAPZ589GFPQ0MKP546","kind":"trait","bakedName":"PlatformerBody","curName":"PlatformerBody","renames":[],"owner":"workspace"}}}}
1
+ {"name":"std-platformer-body","version":"1.0.0","description":"Headless run/jump platformer-physics authority: the SOLE writer of body + fell + hazardId + goalId on side-view boards. Where std-motion-body owns free 2D drift (no collision), this atom owns the platformer contract: every 33ms physics tick it integrates gravity into the body's vertical velocity, steps position in per-second units, and collides the body rect against the platform set with one-way semantics — a body moving in the gravity direction that overlaps a ground/platform tile lands on its anti-gravity face (vy zeroed, grounded set), while a body moving against gravity passes through, so jumping up through a platform and walking up a staircase both just work. The sign of gravity IS the vertical convention: positive pulls toward +y (screen boards, y down — sprite canvases), negative toward −y (math canvases, y up); jumps always fire against it. Geometry lives on the shared entity: config platforms/skateCurve/driftRegions seed entity.platforms/skateCurve/driftRegions on INIT, and SET_PLATFORMS / SET_SKATE_CURVE / SET_DRIFT_REGIONS replace them at runtime (RESTART keeps the live set, so boards that import geometry never lose it on a respawn). Intents: STEER sets horizontal velocity (dir −1/0/1 × moveSpeed, hold-to-run: keydown steers, keyup steers 0), JUMP kicks vertical velocity when grounded, PLACE teleports (spawns, hazard respawns), RESTART reseeds. Emits BODY_MOVED every tick for the render layer (boards that don't subscribe pay nothing), plus the sparse rule signals a board needs to score: BODY_JUMPED, BODY_LANDED (with impact speed), BODY_HAZARD (once per hazard entry, re-arms on exit), BODY_GOAL (same arming), BODY_FELL (once per fall past killY, re-armed by PLACE/RESTART). Drift regions: the driftRegions set lists axis-aligned rects each carrying a constant acceleration (ax, ay) applied with the same 0.033s dt whenever the body's center is inside (empty list = zero behavior change). Curve skating: when config.skate is on and the grounded body comes within skateSnap of the skateCurve surface, the body rides the curve — y snaps to the interpolated surface and tangential gravity (g·slope/(1+slope²)) accelerates vx, and the vertical velocity is the tangential projection (s = vx·cos θ, vy = s·sin θ — no discontinuous jumps at sample boundaries), so the body slides downhill along the graph itself and launches ballistically off its ends; jumping kicks free. Sparse BODY_SKATE_START/BODY_SKATE_END signals fire on engage/disengage so boards can layer fx. Lives, score, and win/lose stay downstream — this atom simulates, it never judges. Renders nothing. Corresponds to the design-sheet field(s): mechanics, dynamics.","orbitals":[{"name":"PlatformerBodyOrbital","id":"orb_54HMS7B1FXGQYPPHAY703PPVKA","entity":{"name":"PlatformerBodyData","id":"ent_A7ZJPNY5DJ2PS13VH2GY789CSY","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"body","type":"object","default":{"x":0,"y":0,"width":1,"height":1,"vx":0,"vy":0,"grounded":false,"facingRight":true},"properties":{"vy":{"name":"vy","type":"number","required":false},"x":{"name":"x","type":"number","required":true},"vx":{"name":"vx","type":"number","required":false},"y":{"name":"y","type":"number","required":true},"grounded":{"name":"grounded","type":"boolean","required":false},"width":{"name":"width","type":"number","required":true},"facingRight":{"name":"facingRight","type":"boolean","required":false},"height":{"name":"height","type":"number","required":true}}},{"name":"fell","type":"boolean","default":false},{"name":"hazardId","type":"string","default":""},{"name":"curveMods","type":"array","default":[],"items":{"type":"object","properties":{"k":{"name":"k","type":"number","required":true},"a":{"name":"a","type":"number","required":true},"b":{"name":"b","type":"number","required":true},"x0":{"name":"x0","type":"number","required":true},"h":{"name":"h","type":"number","required":true},"x1":{"name":"x1","type":"number","required":true}}}},{"name":"goalId","type":"string","default":""},{"name":"skating","type":"boolean","default":false},{"name":"tuning","type":"object","default":{},"properties":{"moveSpeed":{"name":"moveSpeed","type":"number","required":false},"jumpStrength":{"name":"jumpStrength","type":"number","required":false},"gravity":{"name":"gravity","type":"number","required":false}}},{"name":"platforms","type":"array","default":[],"items":{"type":"object","properties":{"x":{"name":"x","type":"number","required":true},"width":{"name":"width","type":"number","required":true},"id":{"name":"id","type":"string","required":false},"type":{"name":"type","type":"string","required":false,"values":["ground","platform","hazard","goal"]},"height":{"name":"height","type":"number","required":true},"y":{"name":"y","type":"number","required":true}}}},{"name":"skateCurve","type":"array","default":[],"items":{"type":"object","properties":{"y":{"name":"y","type":"number","required":true},"x":{"name":"x","type":"number","required":true}}}},{"name":"driftRegions","type":"array","default":[],"items":{"type":"object","properties":{"ax":{"name":"ax","type":"number","required":true},"y0":{"name":"y0","type":"number","required":true},"ay":{"name":"ay","type":"number","required":true},"y1":{"name":"y1","type":"number","required":true},"x0":{"name":"x0","type":"number","required":true},"x1":{"name":"x1","type":"number","required":true},"id":{"name":"id","type":"string","required":true}}}}],"shared":true},"traits":[{"name":"PlatformerBody","id":"trt_VA39R1HDYAPZ589GFPQ0MKP546","entityRebindable":true,"entityContract":{"requires":[],"provides":["body","curveMods","driftRegions","fell","goalId","hazardId","platforms","skateCurve","skating","tuning"]},"effectRow":[{"kind":"emit","resource":"BODY_FELL","site":"tick"},{"kind":"emit","resource":"BODY_GOAL","site":"tick"},{"kind":"emit","resource":"BODY_HAZARD","site":"tick"},{"kind":"emit","resource":"BODY_JUMPED"},{"kind":"emit","resource":"BODY_LANDED","site":"tick"},{"kind":"emit","resource":"BODY_MOVED","site":"tick"},{"kind":"emit","resource":"BODY_SKATE_END","site":"tick"},{"kind":"emit","resource":"BODY_SKATE_START","site":"tick"},{"kind":"set","resource":"@entity.body"},{"kind":"set","resource":"@entity.body","site":"tick"},{"kind":"set","resource":"@entity.curveMods"},{"kind":"set","resource":"@entity.driftRegions"},{"kind":"set","resource":"@entity.fell"},{"kind":"set","resource":"@entity.fell","site":"tick"},{"kind":"set","resource":"@entity.goalId"},{"kind":"set","resource":"@entity.goalId","site":"tick"},{"kind":"set","resource":"@entity.hazardId"},{"kind":"set","resource":"@entity.hazardId","site":"tick"},{"kind":"set","resource":"@entity.platforms"},{"kind":"set","resource":"@entity.skateCurve"},{"kind":"set","resource":"@entity.skating"},{"kind":"set","resource":"@entity.skating","site":"tick"},{"kind":"set","resource":"@entity.tuning"},{"kind":"ticks","site":"tick"}],"category":"lifecycle","linkedEntity":"PlatformerBodyData","linkedEntityId":"ent_A7ZJPNY5DJ2PS13VH2GY789CSY","entityRefIds":{"PlatformerBodyData":"ent_A7ZJPNY5DJ2PS13VH2GY789CSY"},"emits":[{"event":"BODY_MOVED","eventId":"evt_WY87E1EKCM9PAFP30EZWRZKZFF","description":"The body after this physics tick: position, velocity, grounded and skating flags, and scalar speed; render layers subscribe (or read the shared entity), rule layers stay on the sparse signals","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"vx","type":"number","required":true},{"name":"vy","type":"number","required":true},{"name":"grounded","type":"boolean","required":true},{"name":"skating","type":"boolean","required":true},{"name":"speed","type":"number","required":true}]},{"event":"BODY_SKATE_START","eventId":"evt_PAWHGPPPEAB758CQZE2AYX2BNR","description":"Body engaged curve skating this tick (grounded, landing, or falling within skateSnap above the skateCurve surface); slope is the local dy/dx — boards layer fx and equation readouts","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"slope","type":"number","required":true}]},{"event":"BODY_SKATE_END","eventId":"evt_RPPVFS60MX0AEM56ES6Z8GWP74","description":"Body left the curve surface (jumped, walked past an end, or drifted beyond skateSnap); boards tear down skate fx","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"event":"BODY_JUMPED","eventId":"evt_VJRT208AVB5DNGBM3J1R457RK5","description":"Jump accepted (grounded at intent time) and vertical velocity kicked against gravity; boards layer squash/sound fx","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"event":"BODY_LANDED","eventId":"evt_ZCJ5PWZSM7WT3NVFXNQ6BJMZ7N","description":"Body transitioned airborne → standing on a ground/platform tile this tick; impact is the pre-landing fall speed in units/s so boards can scale dust or damage","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"impact","type":"number","required":true}]},{"event":"BODY_HAZARD","eventId":"evt_ZJW67CKM7WT3Y4HXM1Z24FRYRY","description":"Body entered overlap with a hazard tile; fires once per entry and re-arms only after the body leaves, so damage rules stay sparse","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"event":"BODY_GOAL","eventId":"evt_RGZ62G9546JJ305W6TDY541PJ3","description":"Body entered overlap with a goal tile; fires once per entry and re-arms only after the body leaves — the board's win-rule trigger","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"event":"BODY_FELL","eventId":"evt_ST1PCXK3S7HWKVMSBBMW27TKGD","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","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"event":"CURVE_MOD_CLEAR","eventId":"evt_36FSC21301HG0J36JH17NNYM72","description":"Curve mods were cleared; the skate surface is back to the base skateCurve until a new mod is added.","tier":"domain","scope":"external"}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_HSH6JP60B305HGTJ7M9NWYZPZS","name":"Initialize"},{"key":"STEER","id":"evt_ZVFCCENK9YSMZE5VY9T23HNFKS","name":"Steer","payloadSchema":[{"name":"dir","type":"number","required":true}],"listened":true},{"key":"JUMP","id":"evt_J41SC9XB9TNMX3SYPA1ZEDW0ST","name":"Jump","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"PLACE","id":"evt_84A26KRJ7193GK69ZFSP81GYZP","name":"Place","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}],"listened":true},{"key":"CURVE_MOD_ADD","id":"evt_54GKJEJ23E11Q73QA0J8GPQJZB","name":"Curve Mod Add","payloadSchema":[{"name":"x0","type":"number","required":true},{"name":"x1","type":"number","required":true},{"name":"a","type":"number","required":true},{"name":"b","type":"number"},{"name":"h","type":"number","required":true},{"name":"k","type":"number","required":true}],"listened":true},{"key":"CURVE_MOD_CLEAR","id":"evt_36FSC21301HG0J36JH17NNYM72","name":"Curve Mod Clear","description":"Curve mods were cleared; the skate surface is back to the base skateCurve until a new mod is added.","tier":"domain","listened":true},{"key":"CURVE_MOD_CLEAR_RANGE","id":"evt_9E2WJ7YM6FA37RQXM4S6S5S60B","name":"Curve Mod Clear Range","payloadSchema":[{"name":"x0","type":"number","required":true},{"name":"x1","type":"number","required":true}],"listened":true},{"key":"SET_TUNING","id":"evt_1FEFAVHAWGNE83EN68ZXB1CF14","name":"Set Tuning","payloadSchema":[{"name":"jumpStrength","type":"number"},{"name":"moveSpeed","type":"number"},{"name":"gravity","type":"number"}],"listened":true},{"key":"SET_PLATFORMS","id":"evt_Y23D0EK681K40SRDMSJ7JFWFN1","name":"Set Platforms","payloadSchema":[{"name":"platforms","type":"[object]","required":true,"properties":[{"name":"id","type":"string"},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"width","type":"number","required":true},{"name":"height","type":"number","required":true},{"name":"type","type":"string","values":["ground","platform","hazard","goal"]}]}],"listened":true},{"key":"SET_SKATE_CURVE","id":"evt_GC76TX4HNJ8TS86KQTS8YFKCGN","name":"Set Skate Curve","payloadSchema":[{"name":"curve","type":"[object]","required":true,"properties":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]}],"listened":true},{"key":"SET_DRIFT_REGIONS","id":"evt_C8DD46GHSW8WY93Z4JR4BPQF3B","name":"Set Drift Regions","payloadSchema":[{"name":"regions","type":"[object]","required":true,"properties":[{"name":"id","type":"string","required":true},{"name":"x0","type":"number","required":true},{"name":"x1","type":"number","required":true},{"name":"y0","type":"number","required":true},{"name":"y1","type":"number","required":true},{"name":"ax","type":"number","required":true},{"name":"ay","type":"number","required":true}]}],"listened":true},{"key":"RESTART","id":"evt_NZRFJ13645K22YVZ4PV0MN57AN","name":"Restart","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"BODY_MOVED","id":"evt_WY87E1EKCM9PAFP30EZWRZKZFF","name":"Body Moved","description":"The body after this physics tick: position, velocity, grounded and skating flags, and scalar speed; render layers subscribe (or read the shared entity), rule layers stay on the sparse signals","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"vx","type":"number","required":true},{"name":"vy","type":"number","required":true},{"name":"grounded","type":"boolean","required":true},{"name":"skating","type":"boolean","required":true},{"name":"speed","type":"number","required":true}]},{"key":"BODY_SKATE_START","id":"evt_PAWHGPPPEAB758CQZE2AYX2BNR","name":"Body Skate Start","description":"Body engaged curve skating this tick (grounded, landing, or falling within skateSnap above the skateCurve surface); slope is the local dy/dx — boards layer fx and equation readouts","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"slope","type":"number","required":true}]},{"key":"BODY_SKATE_END","id":"evt_RPPVFS60MX0AEM56ES6Z8GWP74","name":"Body Skate End","description":"Body left the curve surface (jumped, walked past an end, or drifted beyond skateSnap); boards tear down skate fx","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"key":"BODY_JUMPED","id":"evt_VJRT208AVB5DNGBM3J1R457RK5","name":"Body Jumped","description":"Jump accepted (grounded at intent time) and vertical velocity kicked against gravity; boards layer squash/sound fx","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"key":"BODY_LANDED","id":"evt_ZCJ5PWZSM7WT3NVFXNQ6BJMZ7N","name":"Body Landed","description":"Body transitioned airborne → standing on a ground/platform tile this tick; impact is the pre-landing fall speed in units/s so boards can scale dust or damage","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"impact","type":"number","required":true}]},{"key":"BODY_HAZARD","id":"evt_ZJW67CKM7WT3Y4HXM1Z24FRYRY","name":"Body Hazard","description":"Body entered overlap with a hazard tile; fires once per entry and re-arms only after the body leaves, so damage rules stay sparse","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"key":"BODY_GOAL","id":"evt_RGZ62G9546JJ305W6TDY541PJ3","name":"Body Goal","description":"Body entered overlap with a goal tile; fires once per entry and re-arms only after the body leaves — the board's win-rule trigger","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"key":"BODY_FELL","id":"evt_ST1PCXK3S7HWKVMSBBMW27TKGD","name":"Body Fell","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","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_HSH6JP60B305HGTJ7M9NWYZPZS","effects":[["set","@entity.body","@config.spawn"],["set","@entity.fell",false],["set","@entity.hazardId",""],["set","@entity.goalId",""],["set","@entity.skating",false],["set","@entity.platforms","@config.platforms"],["set","@entity.skateCurve","@config.skateCurve"],["set","@entity.driftRegions","@config.driftRegions"]]},{"from":"active","to":"active","event":"STEER","eventId":"evt_ZVFCCENK9YSMZE5VY9T23HNFKS","guard":"@config.running","effects":[["set","@entity.body",["object/merge","@entity.body",{"vx":["*","@payload.dir",["if",["==",["object/get","@entity.tuning","moveSpeed",null],null],"@config.moveSpeed",["object/get","@entity.tuning","moveSpeed",null]]],"facingRight":["if",["!=","@payload.dir",0],[">","@payload.dir",0],"@entity.body.facingRight"]}]]]},{"from":"active","to":"active","event":"JUMP","eventId":"evt_J41SC9XB9TNMX3SYPA1ZEDW0ST","guard":["and","@config.running",["==","@entity.body.grounded",true]],"effects":[["set","@entity.body",["object/merge","@entity.body",{"vy":["if",[">",["if",["==",["object/get","@entity.tuning","gravity",null],null],"@config.gravity",["object/get","@entity.tuning","gravity",null]],0],["-",0,["if",["==",["object/get","@entity.tuning","jumpStrength",null],null],"@config.jumpStrength",["object/get","@entity.tuning","jumpStrength",null]]],["if",["==",["object/get","@entity.tuning","jumpStrength",null],null],"@config.jumpStrength",["object/get","@entity.tuning","jumpStrength",null]]],"grounded":false}]],["emit","BODY_JUMPED",{"x":"@entity.body.x","y":"@entity.body.y"}]]},{"from":"active","to":"active","event":"PLACE","eventId":"evt_84A26KRJ7193GK69ZFSP81GYZP","effects":[["set","@entity.body",["object/merge","@entity.body",{"x":"@payload.x","y":"@payload.y","vx":0,"vy":0,"grounded":false}]],["set","@entity.fell",false],["set","@entity.hazardId",""],["set","@entity.skating",false]]},{"from":"active","to":"active","event":"CURVE_MOD_ADD","eventId":"evt_54GKJEJ23E11Q73QA0J8GPQJZB","guard":"@config.curveModsEnabled","effects":[["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"}]]]},{"from":"active","to":"active","event":"CURVE_MOD_CLEAR","eventId":"evt_36FSC21301HG0J36JH17NNYM72","guard":"@config.curveModsEnabled","effects":[["set","@entity.curveMods",[]]]},{"from":"active","to":"active","event":"CURVE_MOD_CLEAR_RANGE","eventId":"evt_9E2WJ7YM6FA37RQXM4S6S5S60B","guard":"@config.curveModsEnabled","effects":[["set","@entity.curveMods",["array/filter","@entity.curveMods",["fn","m",["or",["<",["object/get","@m","x1"],"@payload.x0"],[">",["object/get","@m","x0"],"@payload.x1"]]]]]]},{"from":"active","to":"active","event":"SET_TUNING","eventId":"evt_1FEFAVHAWGNE83EN68ZXB1CF14","effects":[["set","@entity.tuning",["object/merge","@entity.tuning",["if",["==","@payload.jumpStrength",null],{},{"jumpStrength":"@payload.jumpStrength"}]]],["set","@entity.tuning",["object/merge","@entity.tuning",["if",["==","@payload.moveSpeed",null],{},{"moveSpeed":"@payload.moveSpeed"}]]],["set","@entity.tuning",["object/merge","@entity.tuning",["if",["==","@payload.gravity",null],{},{"gravity":"@payload.gravity"}]]]]},{"from":"active","to":"active","event":"SET_PLATFORMS","eventId":"evt_Y23D0EK681K40SRDMSJ7JFWFN1","effects":[["set","@entity.platforms","@payload.platforms"]]},{"from":"active","to":"active","event":"SET_SKATE_CURVE","eventId":"evt_GC76TX4HNJ8TS86KQTS8YFKCGN","effects":[["set","@entity.skateCurve","@payload.curve"]]},{"from":"active","to":"active","event":"SET_DRIFT_REGIONS","eventId":"evt_C8DD46GHSW8WY93Z4JR4BPQF3B","effects":[["set","@entity.driftRegions","@payload.regions"]]},{"from":"active","to":"active","event":"RESTART","eventId":"evt_NZRFJ13645K22YVZ4PV0MN57AN","effects":[["set","@entity.body","@config.spawn"],["set","@entity.curveMods",[]],["set","@entity.fell",false],["set","@entity.hazardId",""],["set","@entity.goalId",""],["set","@entity.skating",false],["set","@entity.tuning",{}]]}]},"ticks":[{"name":"physicsTick","interval":33,"guard":["and","@config.running",[">","@entity.body.width",0]],"effects":[["let",[["eg",["if",["==",["object/get","@entity.tuning","gravity",null],null],"@config.gravity",["object/get","@entity.tuning","gravity",null]]]],["let",[["gdir",["if",[">","@eg",0],1,-1]]],["let",[["bcx",["+",["object/get","@entity.body","x"],["/",["object/get","@entity.body","width"],2]]],["bcy",["+",["object/get","@entity.body","y"],["/",["object/get","@entity.body","height"],2]]]],["let",[["drift",["array/find","@entity.driftRegions",["fn","r",["and",[">=","@bcx",["object/get","@r","x0"]],["and",["<=","@bcx",["object/get","@r","x1"]],["and",[">=","@bcy",["object/get","@r","y0"]],["<=","@bcy",["object/get","@r","y1"]]]]]]]]],["let",[["dax",["if",["==","@drift",null],0,["object/get","@drift","ax"]]],["day",["if",["==","@drift",null],0,["object/get","@drift","ay"]]]],["let",[["vy1",["math/clamp",["+","@entity.body.vy",["*",["+","@eg","@day"],0.033]],["-",0,"@config.maxFallSpeed"],"@config.maxFallSpeed"]]],["let",[["bw",["object/get","@entity.body","width"]],["bh",["object/get","@entity.body","height"]]],["let",[["nx",["math/clamp",["+","@entity.body.x",["*","@entity.body.vx",0.033]],"@config.xMin","@config.xMax"]]],["let",[["ny",["+","@entity.body.y",["*","@vy1",0.033]]]],["let",[["rect",{"x":"@nx","y":"@ny","w":"@bw","h":"@bh"}]],["let",[["hit",["array/find","@entity.platforms",["fn","p",["and",["or",["==",["object/get","@p","type"],"ground"],["==",["object/get","@p","type"],"platform"]],["geo/aabb-overlap","@rect",{"x":"@p.x","y":"@p.y","w":"@p.width","h":"@p.height"}]]]]]],["let",[["landed",["and",["!=","@hit",null],[">",["*","@vy1","@gdir"],0]]]],["let",[["ny2",["if","@landed",["if",[">","@gdir",0],["-",["object/get","@hit","y"],"@bh"],["+",["object/get","@hit","y"],["object/get","@hit","height"]]],"@ny"]],["vy2",["if","@landed",0,"@vy1"]]],["let",[["cx",["+","@nx",["/","@bw",2]]]],["let",[["inRange",["and","@config.skate",["and",[">",["array/len","@entity.skateCurve"],1],["and",[">=","@cx",["object/get",["array/first","@entity.skateCurve"],"x"]],["<","@cx",["object/get",["array/last","@entity.skateCurve"],"x"]]]]]]],["let",[["leftSamp",["if","@inRange",["array/last",["array/filter","@entity.skateCurve",["fn","s",["<=",["object/get","@s","x"],"@cx"]]]],{"x":0,"y":0}]]],["let",[["rightSamp",["if","@inRange",["array/first",["array/filter","@entity.skateCurve",["fn","s",[">",["object/get","@s","x"],"@cx"]]]],{"x":1,"y":0}]]],["let",[["slope",["if","@inRange",["/",["-",["object/get","@rightSamp","y"],["object/get","@leftSamp","y"]],["-",["object/get","@rightSamp","x"],["object/get","@leftSamp","x"]]],0]]],["let",[["curveY",["if","@inRange",["+",["object/get","@leftSamp","y"],["*","@slope",["-","@cx",["object/get","@leftSamp","x"]]]],0]]],["let",[["gapBreak",["and",[">","@config.skateMaxGap",0],[">",["-",["object/get","@rightSamp","x"],["object/get","@leftSamp","x"]],"@config.skateMaxGap"]]]],["let",[["mods",["if",["and","@config.curveModsEnabled","@inRange"],["array/filter","@entity.curveMods",["fn","m",["and",[">=","@cx",["object/get","@m","x0"]],["<=","@cx",["object/get","@m","x1"]]]]],[]]]],["let",[["modded",["array/reduce","@mods",{"y":"@curveY","s":"@slope"},["fn",["acc","m"],["let",[["modX",["*",["object/get","@m","b"],["-","@cx",["object/get","@m","h"]]]]],["let",[["modInRange",["and",[">=","@modX",["object/get",["array/first","@entity.skateCurve"],"x"]],["<","@modX",["object/get",["array/last","@entity.skateCurve"],"x"]]]]],["let",[["modLeft",["if","@modInRange",["array/last",["array/filter","@entity.skateCurve",["fn","s",["<=",["object/get","@s","x"],"@modX"]]]],null]]],["let",[["modRight",["if","@modInRange",["array/first",["array/filter","@entity.skateCurve",["fn","s",[">",["object/get","@s","x"],"@modX"]]]],null]]],["let",[["modOK",["and","@modInRange",["and",["!=","@modLeft",null],["!=","@modRight",null]]]]],["let",[["modSlope",["if","@modOK",["/",["-",["object/get","@modRight","y"],["object/get","@modLeft","y"]],["-",["object/get","@modRight","x"],["object/get","@modLeft","x"]]],0]]],["let",[["modCurveY",["if","@modOK",["+",["object/get","@modLeft","y"],["*","@modSlope",["-","@modX",["object/get","@modLeft","x"]]]],0]]],["if","@modOK",{"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"]]},"@acc"]]]]]]]]]]]],["let",[["slope",["object/get","@modded","s"]]],["let",[["curveY",["object/get","@modded","y"]]],["let",[["aboveCurve",["<",["*",["-","@ny2","@curveY"],"@gdir"],0]]],["let",[["movingUp",["<",["*","@vy1","@gdir"],-0.01]]],["let",[["skateNow",["and","@inRange",["and",["not","@gapBreak"],["and",["<=",["math/abs",["-","@ny2","@curveY"]],"@config.skateSnap"],["and",["or","@landed",["or","@entity.skating",["and",["not","@movingUp"],"@aboveCurve"]]],["or","@entity.body.grounded",["not","@movingUp"]]]]]]]],["let",[["vx2",["if","@skateNow",["math/clamp",["+","@entity.body.vx",["*",["/",["*","@eg","@slope"],["+",1,["*","@slope","@slope"]]],0.033]],["-",0,"@config.maxFallSpeed"],"@config.maxFallSpeed"],"@entity.body.vx"]]],["let",[["vx3",["if",["==","@drift",null],"@vx2",["math/clamp",["+","@vx2",["*","@dax",0.033]],["-",0,"@config.maxFallSpeed"],"@config.maxFallSpeed"]]]],["let",[["fy",["if","@skateNow","@curveY","@ny2"]],["fvy",["if","@skateNow",["*",["*","@vx2",["math/cos",["math/atan","@slope"]]],["math/sin",["math/atan","@slope"]]],"@vy2"]],["fgrounded",["or","@landed","@skateNow"]]],["let",[["hazardHit",["array/find","@entity.platforms",["fn","p",["and",["==",["object/get","@p","type"],"hazard"],["geo/aabb-overlap","@rect",{"x":"@p.x","y":"@p.y","w":"@p.width","h":"@p.height"}]]]]]],["let",[["goalHit",["array/find","@entity.platforms",["fn","p",["and",["==",["object/get","@p","type"],"goal"],["geo/aabb-overlap","@rect",{"x":"@p.x","y":"@p.y","w":"@p.width","h":"@p.height"}]]]]]],["let",[["fellNow",["if",[">","@gdir",0],[">","@fy","@config.killY"],["<","@fy","@config.killY"]]]],["do",["set","@entity.body",["object/merge","@entity.body",{"x":"@nx","y":"@fy","vx":["if",["or",["==","@nx","@config.xMin"],["==","@nx","@config.xMax"]],0,"@vx3"],"vy":"@fvy","grounded":"@fgrounded"}]],["set","@entity.skating","@skateNow"],["if",["and","@skateNow",["==","@entity.skating",false]],["emit","BODY_SKATE_START",{"x":"@nx","y":"@fy","slope":"@slope"}],null],["if",["and",["==","@skateNow",false],["==","@entity.skating",true]],["emit","BODY_SKATE_END",{"x":"@nx","y":"@fy"}],null],["if",["and","@landed",["==","@entity.body.grounded",false]],["emit","BODY_LANDED",{"x":"@nx","y":"@fy","impact":["*","@vy1","@gdir"]}],null],["if",["!=","@hazardHit",null],["if",["!=","@entity.hazardId",["object/get","@hazardHit","id",""]],["do",["set","@entity.hazardId",["object/get","@hazardHit","id",""]],["emit","BODY_HAZARD",{"id":["object/get","@hazardHit","id",""],"x":"@nx","y":"@fy"}]],null],["set","@entity.hazardId",""]],["if",["!=","@goalHit",null],["if",["!=","@entity.goalId",["object/get","@goalHit","id",""]],["do",["set","@entity.goalId",["object/get","@goalHit","id",""]],["emit","BODY_GOAL",{"id":["object/get","@goalHit","id",""],"x":"@nx","y":"@fy"}]],null],["set","@entity.goalId",""]],["if",["and","@fellNow",["==","@entity.fell",false]],["do",["set","@entity.fell",true],["emit","BODY_FELL",{"x":"@nx","y":"@fy"}]],null],["emit","BODY_MOVED",{"x":"@nx","y":"@fy","vx":"@entity.body.vx","vy":"@fvy","grounded":"@fgrounded","skating":"@skateNow","speed":["math/hypot","@entity.body.vx","@fvy"]}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]}],"config":{"curveModsEnabled":{"type":"boolean","default":false,"label":"Curve Mods Enabled","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.","tier":"domain"},"skateSnap":{"type":"number","default":0.75,"label":"Skate Snap","description":"Max vertical gap (world units) between the body's min corner and the curve surface for skating to engage or stay engaged; larger values grab earlier on landing, smaller values release sooner on bumps","tier":"domain"},"maxFallSpeed":{"type":"number","default":14,"label":"Max Fall Speed","description":"Terminal velocity cap in units/s applied to vertical speed each tick","tier":"presentation"},"spawn":{"type":"PlatformerBody","default":{"x":2,"y":8,"width":0.6,"height":0.6,"vx":0,"vy":0,"grounded":false,"facingRight":true},"label":"Spawn Body","description":"Initial body rect (min-corner x/y plus width/height) seeded on INIT/RESTART; width/height also define the collision box","tier":"domain","properties":{"vx":{"name":"vx","type":"number","required":false},"x":{"name":"x","type":"number","required":true},"facingRight":{"name":"facingRight","type":"boolean","required":false},"vy":{"name":"vy","type":"number","required":false},"grounded":{"name":"grounded","type":"boolean","required":false},"y":{"name":"y","type":"number","required":true},"width":{"name":"width","type":"number","required":true},"height":{"name":"height","type":"number","required":true}}},"gravity":{"type":"number","default":24,"label":"Gravity","description":"Units/s² added to vertical velocity; the SIGN is the vertical convention — positive pulls toward +y (screen boards, y down), negative toward −y (math canvases, y up) — and jumps always fire against it","tier":"domain"},"jumpStrength":{"type":"number","default":11,"label":"Jump Strength","description":"Vertical speed in units/s imparted by JUMP, directed against gravity; apex height ≈ jumpStrength² / (2·|gravity|)","tier":"domain"},"running":{"type":"boolean","default":true,"label":"Running","description":"When true the 33ms physics tick integrates and collides; toggle to freeze the body","tier":"domain"},"skate":{"type":"boolean","default":false,"label":"Curve Skating","description":"When true, a grounded body within skateSnap of the skateCurve surface rides the curve: y snaps to the interpolated surface and tangential gravity (g·slope/(1+slope²)) accelerates vx, so the body slides downhill along the graph and launches off its ends; JUMP kicks free. Engages when grounded, when landing on a tile, or when a falling (not rising) body passes within skateSnap above the surface.","tier":"domain"},"killY":{"type":"number","default":1000000,"label":"Kill Y","description":"Fall line: crossing it in the gravity direction fires BODY_FELL once (past it downward on y-down boards, below it on y-up canvases); y-up consumers must set a value below their world floor","tier":"domain"},"moveSpeed":{"type":"number","default":5,"label":"Move Speed","description":"Horizontal run speed in units/s applied by STEER dir ±1","tier":"domain"},"skateMaxGap":{"type":"number","default":0,"label":"Skate Max Gap","description":"Largest x-gap between consecutive skateCurve samples that still counts as surface. 0 = unlimited (sparse two-sample lines skate fine). Dense resampled curves with real gaps between segments (stitched worlds) MUST set this — otherwise the sampler invents a skatable chord across every gap (an invisible line above the bridge/terrain that the body snaps to and glides along).","tier":"domain"},"platforms":{"type":"[PlatformerPlatform]","default":[],"label":"Platforms","description":"Level geometry as min-corner rects: ground/platform tiles are solid one-way landing surfaces, hazard tiles emit BODY_HAZARD on touch, goal tiles emit BODY_GOAL. Seeded onto the entity on INIT; the live set is entity.platforms — SET_PLATFORMS replaces it at runtime (boards that import geometry, e.g. stitched open worlds) and RESTART deliberately does NOT reseed it, so injected geometry survives respawns.","tier":"domain","items":{"type":"object","properties":{"type":{"name":"type","type":"string","required":false,"values":["ground","platform","hazard","goal"]},"id":{"name":"id","type":"string","required":false},"y":{"name":"y","type":"number","required":true},"x":{"name":"x","type":"number","required":true},"width":{"name":"width","type":"number","required":true},"height":{"name":"height","type":"number","required":true}}}},"xMin":{"type":"number","default":-1000000,"label":"Left Wall","description":"Smallest x the body's min corner may hold (world bounds, not level geometry)","tier":"presentation"},"driftRegions":{"type":"[BodyDriftRegion]","default":[],"label":"Drift Regions","description":"Axis-aligned rects (x0..x1, y0..y1 in world units) each carrying a constant acceleration (ax, ay in units/s²) applied with the physics dt whenever the body's center is inside — winds, currents, gradient pushes. Empty list = zero behavior change. Seeded onto the entity on INIT; the live set is entity.driftRegions — SET_DRIFT_REGIONS replaces it at runtime and RESTART does not reseed it.","tier":"domain","items":{"type":"object","properties":{"ay":{"name":"ay","type":"number","required":true},"ax":{"name":"ax","type":"number","required":true},"y1":{"name":"y1","type":"number","required":true},"x1":{"name":"x1","type":"number","required":true},"id":{"name":"id","type":"string","required":true},"x0":{"name":"x0","type":"number","required":true},"y0":{"name":"y0","type":"number","required":true}}}},"xMax":{"type":"number","default":1000000,"label":"Right Wall","description":"Largest x the body's min corner may hold (world bounds, not level geometry)","tier":"presentation"},"skateCurve":{"type":"[PlatformerCurveSample]","default":[],"label":"Skate Curve","description":"Surface samples (x strictly increasing) the body skates when skate is on; y is the surface height for the body's MIN corner, linearly interpolated between bracketing samples — mirror the render-side curve so what you see is what you ride. Seeded onto the entity on INIT; the live curve is entity.skateCurve — SET_SKATE_CURVE replaces it at runtime (stitched mega-curves) and RESTART does not reseed it.","tier":"domain","items":{"type":"object","properties":{"x":{"name":"x","type":"number","required":true},"y":{"name":"y","type":"number","required":true}}}}},"scope":"instance"}],"pages":[{"name":"PlatformerBodyPage","id":"pag_NQ4NFDQBP3NV1ZMT5J4SDDFF5T","path":"/platformer-body","traits":[{"ref":"PlatformerBody","refId":"trt_VA39R1HDYAPZ589GFPQ0MKP546"}]}],"types":{"BodyDriftRegion":[{"name":"id","type":"string","required":true},{"name":"x0","type":"number","required":true},{"name":"x1","type":"number","required":true},{"name":"y0","type":"number","required":true},{"name":"y1","type":"number","required":true},{"name":"ax","type":"number","required":true},{"name":"ay","type":"number","required":true}],"CurveMod":[{"name":"x0","type":"number","required":true},{"name":"x1","type":"number","required":true},{"name":"a","type":"number","required":true},{"name":"b","type":"number","required":true},{"name":"h","type":"number","required":true},{"name":"k","type":"number","required":true}],"PlatformerBody":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"width","type":"number","required":true},{"name":"height","type":"number","required":true},{"name":"vx","type":"number"},{"name":"vy","type":"number"},{"name":"grounded","type":"boolean"},{"name":"facingRight","type":"boolean"}],"PlatformerCurveSample":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}],"PlatformerPlatform":[{"name":"id","type":"string"},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"width","type":"number","required":true},{"name":"height","type":"number","required":true},{"name":"type","type":"string","values":["ground","platform","hazard","goal"]}],"PlatformerTuning":[{"name":"jumpStrength","type":"number"},{"name":"moveSpeed","type":"number"},{"name":"gravity","type":"number"}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_A7ZJPNY5DJ2PS13VH2GY789CSY":{"id":"ent_A7ZJPNY5DJ2PS13VH2GY789CSY","kind":"entity","bakedName":"PlatformerBodyData","curName":"PlatformerBodyData","renames":[],"owner":"workspace"},"evt_1FEFAVHAWGNE83EN68ZXB1CF14":{"id":"evt_1FEFAVHAWGNE83EN68ZXB1CF14","kind":"event","bakedName":"SET_TUNING","curName":"SET_TUNING","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_36FSC21301HG0J36JH17NNYM72":{"id":"evt_36FSC21301HG0J36JH17NNYM72","kind":"event","bakedName":"CURVE_MOD_CLEAR","curName":"CURVE_MOD_CLEAR","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_54GKJEJ23E11Q73QA0J8GPQJZB":{"id":"evt_54GKJEJ23E11Q73QA0J8GPQJZB","kind":"event","bakedName":"CURVE_MOD_ADD","curName":"CURVE_MOD_ADD","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_84A26KRJ7193GK69ZFSP81GYZP":{"id":"evt_84A26KRJ7193GK69ZFSP81GYZP","kind":"event","bakedName":"PLACE","curName":"PLACE","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_9E2WJ7YM6FA37RQXM4S6S5S60B":{"id":"evt_9E2WJ7YM6FA37RQXM4S6S5S60B","kind":"event","bakedName":"CURVE_MOD_CLEAR_RANGE","curName":"CURVE_MOD_CLEAR_RANGE","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_C8DD46GHSW8WY93Z4JR4BPQF3B":{"id":"evt_C8DD46GHSW8WY93Z4JR4BPQF3B","kind":"event","bakedName":"SET_DRIFT_REGIONS","curName":"SET_DRIFT_REGIONS","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_GC76TX4HNJ8TS86KQTS8YFKCGN":{"id":"evt_GC76TX4HNJ8TS86KQTS8YFKCGN","kind":"event","bakedName":"SET_SKATE_CURVE","curName":"SET_SKATE_CURVE","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_HSH6JP60B305HGTJ7M9NWYZPZS":{"id":"evt_HSH6JP60B305HGTJ7M9NWYZPZS","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_J41SC9XB9TNMX3SYPA1ZEDW0ST":{"id":"evt_J41SC9XB9TNMX3SYPA1ZEDW0ST","kind":"event","bakedName":"JUMP","curName":"JUMP","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_NZRFJ13645K22YVZ4PV0MN57AN":{"id":"evt_NZRFJ13645K22YVZ4PV0MN57AN","kind":"event","bakedName":"RESTART","curName":"RESTART","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_PAWHGPPPEAB758CQZE2AYX2BNR":{"id":"evt_PAWHGPPPEAB758CQZE2AYX2BNR","kind":"event","bakedName":"BODY_SKATE_START","curName":"BODY_SKATE_START","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_RGZ62G9546JJ305W6TDY541PJ3":{"id":"evt_RGZ62G9546JJ305W6TDY541PJ3","kind":"event","bakedName":"BODY_GOAL","curName":"BODY_GOAL","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_RPPVFS60MX0AEM56ES6Z8GWP74":{"id":"evt_RPPVFS60MX0AEM56ES6Z8GWP74","kind":"event","bakedName":"BODY_SKATE_END","curName":"BODY_SKATE_END","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_ST1PCXK3S7HWKVMSBBMW27TKGD":{"id":"evt_ST1PCXK3S7HWKVMSBBMW27TKGD","kind":"event","bakedName":"BODY_FELL","curName":"BODY_FELL","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_VJRT208AVB5DNGBM3J1R457RK5":{"id":"evt_VJRT208AVB5DNGBM3J1R457RK5","kind":"event","bakedName":"BODY_JUMPED","curName":"BODY_JUMPED","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_WY87E1EKCM9PAFP30EZWRZKZFF":{"id":"evt_WY87E1EKCM9PAFP30EZWRZKZFF","kind":"event","bakedName":"BODY_MOVED","curName":"BODY_MOVED","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_Y23D0EK681K40SRDMSJ7JFWFN1":{"id":"evt_Y23D0EK681K40SRDMSJ7JFWFN1","kind":"event","bakedName":"SET_PLATFORMS","curName":"SET_PLATFORMS","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_ZCJ5PWZSM7WT3NVFXNQ6BJMZ7N":{"id":"evt_ZCJ5PWZSM7WT3NVFXNQ6BJMZ7N","kind":"event","bakedName":"BODY_LANDED","curName":"BODY_LANDED","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_ZJW67CKM7WT3Y4HXM1Z24FRYRY":{"id":"evt_ZJW67CKM7WT3Y4HXM1Z24FRYRY","kind":"event","bakedName":"BODY_HAZARD","curName":"BODY_HAZARD","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"evt_ZVFCCENK9YSMZE5VY9T23HNFKS":{"id":"evt_ZVFCCENK9YSMZE5VY9T23HNFKS","kind":"event","bakedName":"STEER","curName":"STEER","renames":[],"owner":"workspace","parent":"trt_VA39R1HDYAPZ589GFPQ0MKP546"},"orb_54HMS7B1FXGQYPPHAY703PPVKA":{"id":"orb_54HMS7B1FXGQYPPHAY703PPVKA","kind":"orbital","bakedName":"PlatformerBodyOrbital","curName":"PlatformerBodyOrbital","renames":[],"owner":"workspace"},"pag_NQ4NFDQBP3NV1ZMT5J4SDDFF5T":{"id":"pag_NQ4NFDQBP3NV1ZMT5J4SDDFF5T","kind":"page","bakedName":"PlatformerBodyPage","curName":"PlatformerBodyPage","renames":[],"owner":"workspace"},"trt_VA39R1HDYAPZ589GFPQ0MKP546":{"id":"trt_VA39R1HDYAPZ589GFPQ0MKP546","kind":"trait","bakedName":"PlatformerBody","curName":"PlatformerBody","renames":[],"owner":"workspace"}}}}
@@ -1 +1 @@
1
- {"name":"std-production","version":"1.0.0","description":"Headless unit-production mechanic: accrues productionPoints each turn (AI_TURN) and, on an affordable PRODUCE, emits a SPAWN intent for the grid-tactics authority to place a new unit. Owns only productionPoints (+ its spawn counter); never writes units directly.","orbitals":[{"name":"ProductionOrbital","id":"orb_09KRZD0GYD8F6XN688SJJ0Q7ER","entity":{"name":"ProductionState","id":"ent_AZB0K71KXASYN6C86Y8NP31682","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"productionPoints","type":"number","default":0},{"name":"spawnCount","type":"number","default":0}],"shared":true},"traits":[{"name":"Producer","id":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE","entityRebindable":true,"entityContract":{"requires":[],"provides":["productionPoints","spawnCount"]},"effectRow":[{"kind":"emit","resource":"SPAWN"},{"kind":"set","resource":"@entity.productionPoints"},{"kind":"set","resource":"@entity.spawnCount"}],"category":"lifecycle","linkedEntity":"ProductionState","linkedEntityId":"ent_AZB0K71KXASYN6C86Y8NP31682","entityRefIds":{"ProductionState":"ent_AZB0K71KXASYN6C86Y8NP31682"},"emits":[{"event":"SPAWN","eventId":"evt_CW5EFV8F4Y7JF3B54MNZDSGG76","description":"New-unit intent applied by the grid-tactics authority (the sole units writer)","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"team","type":"string","required":true},{"name":"health","type":"number","required":true},{"name":"maxHealth","type":"number","required":true},{"name":"unitType","type":"string","required":true}]}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_TNJW4RHX1AYGN5R8VY4JNPY9GJ","name":"Initialize"},{"key":"AI_TURN","id":"evt_4Y89G24N9SAMWQWGHJDNPQ0JJ2","name":"Ai Turn","payloadSchema":[{"name":"turn","type":"number"}],"listened":true},{"key":"PRODUCE","id":"evt_1CB47521NV0TXG263TKFJ0EGE7","name":"Produce","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"SPAWN","id":"evt_CW5EFV8F4Y7JF3B54MNZDSGG76","name":"Spawn","description":"New-unit intent applied by the grid-tactics authority (the sole units writer)","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"team","type":"string","required":true},{"name":"health","type":"number","required":true},{"name":"maxHealth","type":"number","required":true},{"name":"unitType","type":"string","required":true}]}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_TNJW4RHX1AYGN5R8VY4JNPY9GJ","effects":[["set","@entity.productionPoints","@config.startPoints"],["set","@entity.spawnCount",0]]},{"from":"active","to":"active","event":"AI_TURN","eventId":"evt_4Y89G24N9SAMWQWGHJDNPQ0JJ2","guard":"@config.running","effects":[["set","@entity.productionPoints",["+","@entity.productionPoints","@config.pointsPerTurn"]]]},{"from":"active","to":"active","event":"PRODUCE","eventId":"evt_1CB47521NV0TXG263TKFJ0EGE7","guard":["and","@config.running",[">=","@entity.productionPoints","@config.spawnCost"]],"effects":[["emit","SPAWN",{"id":["str/concat","prod-u-","@entity.spawnCount"],"x":"@config.spawnX","y":"@config.spawnY","team":"@config.spawnTeam","health":"@config.spawnHealth","maxHealth":"@config.spawnHealth","unitType":"@config.spawnUnitType"}],["set","@entity.spawnCount",["+","@entity.spawnCount",1]],["set","@entity.productionPoints",["-","@entity.productionPoints","@config.spawnCost"]]]}]},"config":{"spawnHealth":{"type":"number","default":3,"label":"Spawn Health","description":"Health/maxHealth of produced units.","tier":"domain"},"spawnY":{"type":"number","default":0,"label":"Spawn Y","description":"Grid row where produced units appear (rally point).","tier":"domain"},"spawnX":{"type":"number","default":0,"label":"Spawn X","description":"Grid column where produced units appear (rally point).","tier":"domain"},"spawnCost":{"type":"number","default":3,"label":"Spawn Cost","description":"Points spent per produced unit; PRODUCE only fires when affordable.","tier":"domain"},"spawnTeam":{"type":"string","default":"player","label":"Spawn Team","description":"Team of produced units.","tier":"domain"},"pointsPerTurn":{"type":"number","default":2,"label":"Points Per Turn","description":"Points accrued each AI_TURN (turn advance).","tier":"domain"},"spawnUnitType":{"type":"string","default":"unit","label":"Spawn Unit Type","description":"unitType of produced units (drives the asset-manifest sprite).","tier":"domain"},"startPoints":{"type":"number","default":0,"label":"Start Points","description":"Production points set on INIT.","tier":"domain"},"running":{"type":"boolean","default":true,"label":"Running","description":"When true, turns accrue points and PRODUCE spends them; toggle to freeze production.","tier":"domain"}},"scope":"instance"}],"pages":[{"name":"ProductionPage","id":"pag_ZCNHTJFFD9QPMXP11KP679583S","path":"/production","traits":[{"ref":"Producer","refId":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE"}]}]}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_AZB0K71KXASYN6C86Y8NP31682":{"id":"ent_AZB0K71KXASYN6C86Y8NP31682","kind":"entity","bakedName":"ProductionState","curName":"ProductionState","renames":[],"owner":"workspace"},"evt_1CB47521NV0TXG263TKFJ0EGE7":{"id":"evt_1CB47521NV0TXG263TKFJ0EGE7","kind":"event","bakedName":"PRODUCE","curName":"PRODUCE","renames":[],"owner":"workspace","parent":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE"},"evt_4Y89G24N9SAMWQWGHJDNPQ0JJ2":{"id":"evt_4Y89G24N9SAMWQWGHJDNPQ0JJ2","kind":"event","bakedName":"AI_TURN","curName":"AI_TURN","renames":[],"owner":"workspace","parent":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE"},"evt_CW5EFV8F4Y7JF3B54MNZDSGG76":{"id":"evt_CW5EFV8F4Y7JF3B54MNZDSGG76","kind":"event","bakedName":"SPAWN","curName":"SPAWN","renames":[],"owner":"workspace","parent":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE"},"evt_TNJW4RHX1AYGN5R8VY4JNPY9GJ":{"id":"evt_TNJW4RHX1AYGN5R8VY4JNPY9GJ","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE"},"orb_09KRZD0GYD8F6XN688SJJ0Q7ER":{"id":"orb_09KRZD0GYD8F6XN688SJJ0Q7ER","kind":"orbital","bakedName":"ProductionOrbital","curName":"ProductionOrbital","renames":[],"owner":"workspace"},"pag_ZCNHTJFFD9QPMXP11KP679583S":{"id":"pag_ZCNHTJFFD9QPMXP11KP679583S","kind":"page","bakedName":"ProductionPage","curName":"ProductionPage","renames":[],"owner":"workspace"},"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE":{"id":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE","kind":"trait","bakedName":"Producer","curName":"Producer","renames":[],"owner":"workspace"}}}}
1
+ {"name":"std-production","version":"1.0.0","description":"Headless unit-production mechanic: accrues productionPoints each turn (AI_TURN) and, on an affordable PRODUCE, emits a SPAWN intent for the grid-tactics authority to place a new unit. Owns only productionPoints (+ its spawn counter); never writes units directly.","orbitals":[{"name":"ProductionOrbital","id":"orb_09KRZD0GYD8F6XN688SJJ0Q7ER","entity":{"name":"ProductionState","id":"ent_AZB0K71KXASYN6C86Y8NP31682","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"productionPoints","type":"number","default":0},{"name":"spawnCount","type":"number","default":0}],"shared":true},"traits":[{"name":"Producer","id":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE","entityRebindable":true,"entityContract":{"requires":[],"provides":["productionPoints","spawnCount"]},"effectRow":[{"kind":"emit","resource":"SPAWN"},{"kind":"set","resource":"@entity.productionPoints"},{"kind":"set","resource":"@entity.spawnCount"}],"category":"lifecycle","linkedEntity":"ProductionState","linkedEntityId":"ent_AZB0K71KXASYN6C86Y8NP31682","entityRefIds":{"ProductionState":"ent_AZB0K71KXASYN6C86Y8NP31682"},"emits":[{"event":"SPAWN","eventId":"evt_CW5EFV8F4Y7JF3B54MNZDSGG76","description":"New-unit intent applied by the grid-tactics authority (the sole units writer)","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"team","type":"string","required":true},{"name":"health","type":"number","required":true},{"name":"maxHealth","type":"number","required":true},{"name":"unitType","type":"string","required":true}]}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_TNJW4RHX1AYGN5R8VY4JNPY9GJ","name":"Initialize"},{"key":"AI_TURN","id":"evt_4Y89G24N9SAMWQWGHJDNPQ0JJ2","name":"Ai Turn","payloadSchema":[{"name":"turn","type":"number"}],"listened":true},{"key":"PRODUCE","id":"evt_1CB47521NV0TXG263TKFJ0EGE7","name":"Produce","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"SPAWN","id":"evt_CW5EFV8F4Y7JF3B54MNZDSGG76","name":"Spawn","description":"New-unit intent applied by the grid-tactics authority (the sole units writer)","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"team","type":"string","required":true},{"name":"health","type":"number","required":true},{"name":"maxHealth","type":"number","required":true},{"name":"unitType","type":"string","required":true}]}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_TNJW4RHX1AYGN5R8VY4JNPY9GJ","effects":[["set","@entity.productionPoints","@config.startPoints"],["set","@entity.spawnCount",0]]},{"from":"active","to":"active","event":"AI_TURN","eventId":"evt_4Y89G24N9SAMWQWGHJDNPQ0JJ2","guard":"@config.running","effects":[["set","@entity.productionPoints",["+","@entity.productionPoints","@config.pointsPerTurn"]]]},{"from":"active","to":"active","event":"PRODUCE","eventId":"evt_1CB47521NV0TXG263TKFJ0EGE7","guard":["and","@config.running",[">=","@entity.productionPoints","@config.spawnCost"]],"effects":[["emit","SPAWN",{"id":["str/concat","prod-u-","@entity.spawnCount"],"x":"@config.spawnX","y":"@config.spawnY","team":"@config.spawnTeam","health":"@config.spawnHealth","maxHealth":"@config.spawnHealth","unitType":"@config.spawnUnitType"}],["set","@entity.spawnCount",["+","@entity.spawnCount",1]],["set","@entity.productionPoints",["-","@entity.productionPoints","@config.spawnCost"]]]}]},"config":{"spawnHealth":{"type":"number","default":3,"label":"Spawn Health","description":"Health/maxHealth of produced units.","tier":"domain"},"spawnUnitType":{"type":"string","default":"unit","label":"Spawn Unit Type","description":"unitType of produced units (drives the asset-manifest sprite).","tier":"domain"},"spawnCost":{"type":"number","default":3,"label":"Spawn Cost","description":"Points spent per produced unit; PRODUCE only fires when affordable.","tier":"domain"},"spawnY":{"type":"number","default":0,"label":"Spawn Y","description":"Grid row where produced units appear (rally point).","tier":"domain"},"running":{"type":"boolean","default":true,"label":"Running","description":"When true, turns accrue points and PRODUCE spends them; toggle to freeze production.","tier":"domain"},"startPoints":{"type":"number","default":0,"label":"Start Points","description":"Production points set on INIT.","tier":"domain"},"pointsPerTurn":{"type":"number","default":2,"label":"Points Per Turn","description":"Points accrued each AI_TURN (turn advance).","tier":"domain"},"spawnTeam":{"type":"string","default":"player","label":"Spawn Team","description":"Team of produced units.","tier":"domain"},"spawnX":{"type":"number","default":0,"label":"Spawn X","description":"Grid column where produced units appear (rally point).","tier":"domain"}},"scope":"instance"}],"pages":[{"name":"ProductionPage","id":"pag_ZCNHTJFFD9QPMXP11KP679583S","path":"/production","traits":[{"ref":"Producer","refId":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE"}]}]}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_AZB0K71KXASYN6C86Y8NP31682":{"id":"ent_AZB0K71KXASYN6C86Y8NP31682","kind":"entity","bakedName":"ProductionState","curName":"ProductionState","renames":[],"owner":"workspace"},"evt_1CB47521NV0TXG263TKFJ0EGE7":{"id":"evt_1CB47521NV0TXG263TKFJ0EGE7","kind":"event","bakedName":"PRODUCE","curName":"PRODUCE","renames":[],"owner":"workspace","parent":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE"},"evt_4Y89G24N9SAMWQWGHJDNPQ0JJ2":{"id":"evt_4Y89G24N9SAMWQWGHJDNPQ0JJ2","kind":"event","bakedName":"AI_TURN","curName":"AI_TURN","renames":[],"owner":"workspace","parent":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE"},"evt_CW5EFV8F4Y7JF3B54MNZDSGG76":{"id":"evt_CW5EFV8F4Y7JF3B54MNZDSGG76","kind":"event","bakedName":"SPAWN","curName":"SPAWN","renames":[],"owner":"workspace","parent":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE"},"evt_TNJW4RHX1AYGN5R8VY4JNPY9GJ":{"id":"evt_TNJW4RHX1AYGN5R8VY4JNPY9GJ","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE"},"orb_09KRZD0GYD8F6XN688SJJ0Q7ER":{"id":"orb_09KRZD0GYD8F6XN688SJJ0Q7ER","kind":"orbital","bakedName":"ProductionOrbital","curName":"ProductionOrbital","renames":[],"owner":"workspace"},"pag_ZCNHTJFFD9QPMXP11KP679583S":{"id":"pag_ZCNHTJFFD9QPMXP11KP679583S","kind":"page","bakedName":"ProductionPage","curName":"ProductionPage","renames":[],"owner":"workspace"},"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE":{"id":"trt_4VAHHRQ0F4G7J3YV9M9WV7WFXE","kind":"trait","bakedName":"Producer","curName":"Producer","renames":[],"owner":"workspace"}}}}
@@ -1 +1 @@
1
- {"name":"std-score","version":"1.0.0","description":"Headless scoring mechanic: awards points when the enemy survivor count drops on a UNITS_CHANGED signal. Owns only score (+ its kill baseline); renders nothing.","orbitals":[{"name":"ScoreOrbital","id":"orb_ZCRWVSJQZWBZYE3A7YG5NCS6BQ","entity":{"name":"ScoreState","id":"ent_DSB29GX63CK1PFHYPBEM260CV8","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"score","type":"number","default":0},{"name":"scoreBaseline","type":"number","default":0}],"shared":true},"traits":[{"name":"ScoreKeeper","id":"trt_4WA6KA3VT5XX2H3D2SVM4VC5R0","entityRebindable":true,"entityContract":{"requires":[],"provides":["score","scoreBaseline"]},"effectRow":[{"kind":"set","resource":"@entity.score"},{"kind":"set","resource":"@entity.scoreBaseline"}],"category":"lifecycle","linkedEntity":"ScoreState","linkedEntityId":"ent_DSB29GX63CK1PFHYPBEM260CV8","entityRefIds":{"ScoreState":"ent_DSB29GX63CK1PFHYPBEM260CV8"},"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_D2EDFVEGS08CG48206PDK2RZKC","name":"Initialize"},{"key":"UNITS_CHANGED","id":"evt_T5RG9CM6EH378RFYSM09A0BHFV","name":"Units Changed","payloadSchema":[{"name":"playersAlive","type":"number"},{"name":"enemiesAlive","type":"number"}],"listened":true}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_D2EDFVEGS08CG48206PDK2RZKC","effects":[["set","@entity.score","@config.startScore"],["set","@entity.scoreBaseline","@config.initialEnemies"]]},{"from":"active","to":"active","event":"UNITS_CHANGED","eventId":"evt_T5RG9CM6EH378RFYSM09A0BHFV","guard":"@config.running","effects":[["set","@entity.score",["if",["<","@payload.enemiesAlive","@entity.scoreBaseline"],["+","@entity.score",["*",["-","@entity.scoreBaseline","@payload.enemiesAlive"],"@config.pointsPerKill"]],"@entity.score"]],["set","@entity.scoreBaseline","@payload.enemiesAlive"]]}]},"config":{"running":{"type":"boolean","default":true,"label":"Running","description":"When true, enemy-count drops award points; toggle to freeze scoring.","tier":"domain"},"initialEnemies":{"type":"number","default":0,"label":"Initial Enemies","description":"Enemy count at start; the kill baseline so the first kill scores correctly.","tier":"domain"},"pointsPerKill":{"type":"number","default":10,"label":"Points Per Kill","description":"Points awarded for each enemy removed since the last signal.","tier":"domain"},"startScore":{"type":"number","default":0,"label":"Start Score","description":"Initial score set on INIT.","tier":"domain"}},"scope":"instance"}],"pages":[{"name":"ScorePage","id":"pag_6WMWPP31DRGPW0BKNMX6DNG19C","path":"/score","traits":[{"ref":"ScoreKeeper","refId":"trt_4WA6KA3VT5XX2H3D2SVM4VC5R0"}]}]}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_DSB29GX63CK1PFHYPBEM260CV8":{"id":"ent_DSB29GX63CK1PFHYPBEM260CV8","kind":"entity","bakedName":"ScoreState","curName":"ScoreState","renames":[],"owner":"workspace"},"evt_D2EDFVEGS08CG48206PDK2RZKC":{"id":"evt_D2EDFVEGS08CG48206PDK2RZKC","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_4WA6KA3VT5XX2H3D2SVM4VC5R0"},"evt_T5RG9CM6EH378RFYSM09A0BHFV":{"id":"evt_T5RG9CM6EH378RFYSM09A0BHFV","kind":"event","bakedName":"UNITS_CHANGED","curName":"UNITS_CHANGED","renames":[],"owner":"workspace","parent":"trt_4WA6KA3VT5XX2H3D2SVM4VC5R0"},"orb_ZCRWVSJQZWBZYE3A7YG5NCS6BQ":{"id":"orb_ZCRWVSJQZWBZYE3A7YG5NCS6BQ","kind":"orbital","bakedName":"ScoreOrbital","curName":"ScoreOrbital","renames":[],"owner":"workspace"},"pag_6WMWPP31DRGPW0BKNMX6DNG19C":{"id":"pag_6WMWPP31DRGPW0BKNMX6DNG19C","kind":"page","bakedName":"ScorePage","curName":"ScorePage","renames":[],"owner":"workspace"},"trt_4WA6KA3VT5XX2H3D2SVM4VC5R0":{"id":"trt_4WA6KA3VT5XX2H3D2SVM4VC5R0","kind":"trait","bakedName":"ScoreKeeper","curName":"ScoreKeeper","renames":[],"owner":"workspace"}}}}
1
+ {"name":"std-score","version":"1.0.0","description":"Headless scoring mechanic: awards points when the enemy survivor count drops on a UNITS_CHANGED signal. Owns only score (+ its kill baseline); renders nothing.","orbitals":[{"name":"ScoreOrbital","id":"orb_ZCRWVSJQZWBZYE3A7YG5NCS6BQ","entity":{"name":"ScoreState","id":"ent_DSB29GX63CK1PFHYPBEM260CV8","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"score","type":"number","default":0},{"name":"scoreBaseline","type":"number","default":0}],"shared":true},"traits":[{"name":"ScoreKeeper","id":"trt_4WA6KA3VT5XX2H3D2SVM4VC5R0","entityRebindable":true,"entityContract":{"requires":[],"provides":["score","scoreBaseline"]},"effectRow":[{"kind":"set","resource":"@entity.score"},{"kind":"set","resource":"@entity.scoreBaseline"}],"category":"lifecycle","linkedEntity":"ScoreState","linkedEntityId":"ent_DSB29GX63CK1PFHYPBEM260CV8","entityRefIds":{"ScoreState":"ent_DSB29GX63CK1PFHYPBEM260CV8"},"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_D2EDFVEGS08CG48206PDK2RZKC","name":"Initialize"},{"key":"UNITS_CHANGED","id":"evt_T5RG9CM6EH378RFYSM09A0BHFV","name":"Units Changed","payloadSchema":[{"name":"playersAlive","type":"number"},{"name":"enemiesAlive","type":"number"}],"listened":true}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_D2EDFVEGS08CG48206PDK2RZKC","effects":[["set","@entity.score","@config.startScore"],["set","@entity.scoreBaseline","@config.initialEnemies"]]},{"from":"active","to":"active","event":"UNITS_CHANGED","eventId":"evt_T5RG9CM6EH378RFYSM09A0BHFV","guard":"@config.running","effects":[["set","@entity.score",["if",["<","@payload.enemiesAlive","@entity.scoreBaseline"],["+","@entity.score",["*",["-","@entity.scoreBaseline","@payload.enemiesAlive"],"@config.pointsPerKill"]],"@entity.score"]],["set","@entity.scoreBaseline","@payload.enemiesAlive"]]}]},"config":{"pointsPerKill":{"type":"number","default":10,"label":"Points Per Kill","description":"Points awarded for each enemy removed since the last signal.","tier":"domain"},"running":{"type":"boolean","default":true,"label":"Running","description":"When true, enemy-count drops award points; toggle to freeze scoring.","tier":"domain"},"startScore":{"type":"number","default":0,"label":"Start Score","description":"Initial score set on INIT.","tier":"domain"},"initialEnemies":{"type":"number","default":0,"label":"Initial Enemies","description":"Enemy count at start; the kill baseline so the first kill scores correctly.","tier":"domain"}},"scope":"instance"}],"pages":[{"name":"ScorePage","id":"pag_6WMWPP31DRGPW0BKNMX6DNG19C","path":"/score","traits":[{"ref":"ScoreKeeper","refId":"trt_4WA6KA3VT5XX2H3D2SVM4VC5R0"}]}]}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_DSB29GX63CK1PFHYPBEM260CV8":{"id":"ent_DSB29GX63CK1PFHYPBEM260CV8","kind":"entity","bakedName":"ScoreState","curName":"ScoreState","renames":[],"owner":"workspace"},"evt_D2EDFVEGS08CG48206PDK2RZKC":{"id":"evt_D2EDFVEGS08CG48206PDK2RZKC","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_4WA6KA3VT5XX2H3D2SVM4VC5R0"},"evt_T5RG9CM6EH378RFYSM09A0BHFV":{"id":"evt_T5RG9CM6EH378RFYSM09A0BHFV","kind":"event","bakedName":"UNITS_CHANGED","curName":"UNITS_CHANGED","renames":[],"owner":"workspace","parent":"trt_4WA6KA3VT5XX2H3D2SVM4VC5R0"},"orb_ZCRWVSJQZWBZYE3A7YG5NCS6BQ":{"id":"orb_ZCRWVSJQZWBZYE3A7YG5NCS6BQ","kind":"orbital","bakedName":"ScoreOrbital","curName":"ScoreOrbital","renames":[],"owner":"workspace"},"pag_6WMWPP31DRGPW0BKNMX6DNG19C":{"id":"pag_6WMWPP31DRGPW0BKNMX6DNG19C","kind":"page","bakedName":"ScorePage","curName":"ScorePage","renames":[],"owner":"workspace"},"trt_4WA6KA3VT5XX2H3D2SVM4VC5R0":{"id":"trt_4WA6KA3VT5XX2H3D2SVM4VC5R0","kind":"trait","bakedName":"ScoreKeeper","curName":"ScoreKeeper","renames":[],"owner":"workspace"}}}}
@@ -1 +1 @@
1
- {"name":"std-tutorial-autodemo","version":"1.0.0","description":"Generic scripted input-replay atom: the demo half of a tutorial. Holds one or more named cue scripts (each an ordered list of { at, event, arg } rows where at is a millisecond offset and event is LEFT/RIGHT/JUMP/STOP); listens for TUTORIAL_DEMO_START { demoId } (from std-tutorial-overlay's demoId step) and plays the matching script on a 32ms clock, emitting the semantic DEMO_LEFT / DEMO_RIGHT / DEMO_JUMP / DEMO_STOP events the host board maps onto its own movement. TUTORIAL_DEMO_STOP, DEMO_CANCEL (real user input), or exhausting the cue list end the demo and emit DEMO_STOP so the character stops moving. Renders a small Demo badge while playing. Domain-agnostic: the demo never emits board events (OW_*, etc.) — the organism maps DEMO_* to its own steering, so a demo cannot self-cancel through the board's input path.","orbitals":[{"name":"TutorialAutoDemoOrbital","id":"orb_7YBJTP6S5RCJW64Y4Q178FFYK6","entity":{"name":"AutoDemoData","id":"ent_EQWAEV89ZJ4ZS6SBQFMKVYVB6A","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"playing","type":"boolean","default":false},{"name":"scriptId","type":"string","default":""},{"name":"elapsed","type":"number","default":0},{"name":"cueIndex","type":"number","default":0}]},"traits":[{"name":"AutoDemo","id":"trt_SST59D1PTBVD5RA8TD6KE3CWD4","entityRebindable":true,"entityContract":{"requires":[],"provides":["cueIndex","elapsed","playing","scriptId"]},"effectRow":[{"kind":"emit","resource":"DEMO_JUMP","site":"tick"},{"kind":"emit","resource":"DEMO_LEFT","site":"tick"},{"kind":"emit","resource":"DEMO_RIGHT","site":"tick"},{"kind":"emit","resource":"DEMO_STOP"},{"kind":"emit","resource":"DEMO_STOP","site":"tick"},{"kind":"render-ui","resource":"hud-top"},{"kind":"render-ui","resource":"hud-top","site":"tick"},{"kind":"set","resource":"@entity.cueIndex"},{"kind":"set","resource":"@entity.cueIndex","site":"tick"},{"kind":"set","resource":"@entity.elapsed"},{"kind":"set","resource":"@entity.elapsed","site":"tick"},{"kind":"set","resource":"@entity.playing"},{"kind":"set","resource":"@entity.playing","site":"tick"},{"kind":"set","resource":"@entity.scriptId"},{"kind":"ticks","site":"tick"}],"category":"interaction","linkedEntity":"AutoDemoData","linkedEntityId":"ent_EQWAEV89ZJ4ZS6SBQFMKVYVB6A","entityRefIds":{"AutoDemoData":"ent_EQWAEV89ZJ4ZS6SBQFMKVYVB6A"},"emits":[{"event":"DEMO_LEFT","eventId":"evt_37J9CKBS4PWJBCWE312BMMA3GR","description":"Scripted run-left cue; the host board maps this to its own steer-left.","tier":"domain","scope":"external"},{"event":"DEMO_RIGHT","eventId":"evt_WBP8ND3V56XJK0BXACJ20JFPZC","description":"Scripted run-right cue; the host board maps this to its own steer-right.","tier":"domain","scope":"external"},{"event":"DEMO_JUMP","eventId":"evt_FDAZ83789RM4W3AGZE7ZNM39BX","description":"Scripted jump cue; the host board maps this to its own jump.","tier":"domain","scope":"external"},{"event":"DEMO_STOP","eventId":"evt_X0NFT949WW4YEB8XCW2BWZFCY8","description":"Scripted stop cue (or demo end/cancel); the host board maps this to stop movement.","tier":"domain","scope":"external"}],"stateMachine":{"states":[{"name":"idle","isInitial":true},{"name":"playing"}],"events":[{"key":"INIT","id":"evt_AP1SJSAY07F03G09SP5X9P79RR","name":"Initialize"},{"key":"TUTORIAL_DEMO_START","id":"evt_NWN09S984TM2D3AKABMEZTTQAQ","name":"Tutorial Demo Start","description":"A tutorial step carrying a demoId was shown (std-tutorial-overlay); begin playing the cue script whose id matches demoId.","tier":"domain","payloadSchema":[{"name":"demoId","type":"string","required":true}],"listened":true},{"key":"TUTORIAL_DEMO_STOP","id":"evt_A0ETKH2QE6BQ3E8HD26H6Z68CF","name":"Tutorial Demo Stop","description":"The tutorial left a demo step or was dismissed; stop the demo and release control.","tier":"domain","listened":true},{"key":"DEMO_CANCEL","id":"evt_YDK0X6Z2BJH5SEZAFK9PMYDW8R","name":"Demo Cancel","description":"Real user input was received by the host board; stop the demo immediately and hand control back to the player.","tier":"domain","listened":true},{"key":"DEMO_LEFT","id":"evt_37J9CKBS4PWJBCWE312BMMA3GR","name":"Demo Left","description":"Scripted run-left cue; the host board maps this to its own steer-left.","tier":"domain"},{"key":"DEMO_RIGHT","id":"evt_WBP8ND3V56XJK0BXACJ20JFPZC","name":"Demo Right","description":"Scripted run-right cue; the host board maps this to its own steer-right.","tier":"domain"},{"key":"DEMO_JUMP","id":"evt_FDAZ83789RM4W3AGZE7ZNM39BX","name":"Demo Jump","description":"Scripted jump cue; the host board maps this to its own jump.","tier":"domain"},{"key":"DEMO_STOP","id":"evt_X0NFT949WW4YEB8XCW2BWZFCY8","name":"Demo Stop","description":"Scripted stop cue (or demo end/cancel); the host board maps this to stop movement.","tier":"domain"}],"transitions":[{"from":"idle","to":"idle","event":"INIT","eventId":"evt_AP1SJSAY07F03G09SP5X9P79RR","effects":[["render-ui","hud-top",null]]},{"from":"idle","to":"playing","event":"TUTORIAL_DEMO_START","eventId":"evt_NWN09S984TM2D3AKABMEZTTQAQ","effects":[["set","@entity.scriptId","@payload.demoId"],["set","@entity.elapsed",0],["set","@entity.cueIndex",0],["set","@entity.playing",true],["render-ui","hud-top",{"type":"badge","label":"Demo","variant":"info"}]]},{"from":"idle","to":"idle","event":"TUTORIAL_DEMO_STOP","eventId":"evt_A0ETKH2QE6BQ3E8HD26H6Z68CF","effects":[["render-ui","hud-top",null]]},{"from":"idle","to":"idle","event":"DEMO_CANCEL","eventId":"evt_YDK0X6Z2BJH5SEZAFK9PMYDW8R","effects":[["render-ui","hud-top",null]]},{"from":"playing","to":"idle","event":"INIT","eventId":"evt_AP1SJSAY07F03G09SP5X9P79RR","effects":[["render-ui","hud-top",null]]},{"from":"playing","to":"playing","event":"TUTORIAL_DEMO_START","eventId":"evt_NWN09S984TM2D3AKABMEZTTQAQ","effects":[["set","@entity.scriptId","@payload.demoId"],["set","@entity.elapsed",0],["set","@entity.cueIndex",0],["render-ui","hud-top",{"type":"badge","label":"Demo","variant":"info"}]]},{"from":"playing","to":"idle","event":"TUTORIAL_DEMO_STOP","eventId":"evt_A0ETKH2QE6BQ3E8HD26H6Z68CF","effects":[["set","@entity.playing",false],["render-ui","hud-top",null],["emit","DEMO_STOP",{}]]},{"from":"playing","to":"idle","event":"DEMO_CANCEL","eventId":"evt_YDK0X6Z2BJH5SEZAFK9PMYDW8R","effects":[["set","@entity.playing",false],["render-ui","hud-top",null],["emit","DEMO_STOP",{}]]}]},"ticks":[{"name":"demoTick","interval":32,"guard":["==","@entity.playing",true],"effects":[["set","@entity.elapsed",["+","@entity.elapsed",32]],["let",[["scriptMatch",["array/filter","@config.scripts",["fn","s",["==",["object/get","@s","id"],"@entity.scriptId"]]]]],["let",[["cueList",["if",[">",["array/len","@scriptMatch"],0],["object/get",["array/first","@scriptMatch"],"cues",[]],[]]]],["let",[["cue",["if",["<","@entity.cueIndex",["array/len","@cueList"]],["array/nth","@cueList","@entity.cueIndex"],{"at":999999,"event":""}]]],["do",["if",["<=",["object/get","@cue","at",0],"@entity.elapsed"],["do",["set","@entity.cueIndex",["+","@entity.cueIndex",1]],["if",["==",["object/get","@cue","event",""],"LEFT"],["emit","DEMO_LEFT",{}],null],["if",["==",["object/get","@cue","event",""],"RIGHT"],["emit","DEMO_RIGHT",{}],null],["if",["==",["object/get","@cue","event",""],"JUMP"],["emit","DEMO_JUMP",{}],null],["if",["==",["object/get","@cue","event",""],"STOP"],["emit","DEMO_STOP",{}],null]],null],["if",[">=","@entity.cueIndex",["array/len","@cueList"]],["do",["set","@entity.playing",false],["render-ui","hud-top",null],["emit","DEMO_STOP",{}]],null]]]]]]}],"config":{"scripts":{"type":"[DemoScript]","default":[],"label":"Scripts","description":"Named cue scripts keyed by the tutorial step's demoId; each cue fires its event after `at` milliseconds of the demo clock.","tier":"domain","items":{"type":"object","properties":{"id":{"name":"id","type":"string","required":true},"cues":{"name":"cues","type":"array","required":true,"items":{"type":"object","properties":{"event":{"name":"event","type":"string","required":true},"arg":{"name":"arg","type":"number","required":false},"at":{"name":"at","type":"number","required":true}}}}}}}},"scope":"instance"}],"pages":[{"name":"TutorialAutoDemoPage","id":"pag_TAPW1GQBHQNRVQKS46AZ29VCBF","path":"/tutorial-autodemo","traits":[{"ref":"AutoDemo","refId":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"}]}],"types":{"DemoCue":[{"name":"at","type":"number","required":true},{"name":"event","type":"string","required":true},{"name":"arg","type":"number"}],"DemoScript":[{"name":"id","type":"string","required":true},{"name":"cues","type":"[object]","required":true,"properties":[{"name":"at","type":"number","required":true},{"name":"event","type":"string","required":true},{"name":"arg","type":"number"}]}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_EQWAEV89ZJ4ZS6SBQFMKVYVB6A":{"id":"ent_EQWAEV89ZJ4ZS6SBQFMKVYVB6A","kind":"entity","bakedName":"AutoDemoData","curName":"AutoDemoData","renames":[],"owner":"workspace"},"evt_37J9CKBS4PWJBCWE312BMMA3GR":{"id":"evt_37J9CKBS4PWJBCWE312BMMA3GR","kind":"event","bakedName":"DEMO_LEFT","curName":"DEMO_LEFT","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_A0ETKH2QE6BQ3E8HD26H6Z68CF":{"id":"evt_A0ETKH2QE6BQ3E8HD26H6Z68CF","kind":"event","bakedName":"TUTORIAL_DEMO_STOP","curName":"TUTORIAL_DEMO_STOP","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_AP1SJSAY07F03G09SP5X9P79RR":{"id":"evt_AP1SJSAY07F03G09SP5X9P79RR","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_FDAZ83789RM4W3AGZE7ZNM39BX":{"id":"evt_FDAZ83789RM4W3AGZE7ZNM39BX","kind":"event","bakedName":"DEMO_JUMP","curName":"DEMO_JUMP","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_NWN09S984TM2D3AKABMEZTTQAQ":{"id":"evt_NWN09S984TM2D3AKABMEZTTQAQ","kind":"event","bakedName":"TUTORIAL_DEMO_START","curName":"TUTORIAL_DEMO_START","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_WBP8ND3V56XJK0BXACJ20JFPZC":{"id":"evt_WBP8ND3V56XJK0BXACJ20JFPZC","kind":"event","bakedName":"DEMO_RIGHT","curName":"DEMO_RIGHT","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_X0NFT949WW4YEB8XCW2BWZFCY8":{"id":"evt_X0NFT949WW4YEB8XCW2BWZFCY8","kind":"event","bakedName":"DEMO_STOP","curName":"DEMO_STOP","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_YDK0X6Z2BJH5SEZAFK9PMYDW8R":{"id":"evt_YDK0X6Z2BJH5SEZAFK9PMYDW8R","kind":"event","bakedName":"DEMO_CANCEL","curName":"DEMO_CANCEL","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"orb_7YBJTP6S5RCJW64Y4Q178FFYK6":{"id":"orb_7YBJTP6S5RCJW64Y4Q178FFYK6","kind":"orbital","bakedName":"TutorialAutoDemoOrbital","curName":"TutorialAutoDemoOrbital","renames":[],"owner":"workspace"},"pag_TAPW1GQBHQNRVQKS46AZ29VCBF":{"id":"pag_TAPW1GQBHQNRVQKS46AZ29VCBF","kind":"page","bakedName":"TutorialAutoDemoPage","curName":"TutorialAutoDemoPage","renames":[],"owner":"workspace"},"trt_SST59D1PTBVD5RA8TD6KE3CWD4":{"id":"trt_SST59D1PTBVD5RA8TD6KE3CWD4","kind":"trait","bakedName":"AutoDemo","curName":"AutoDemo","renames":[],"owner":"workspace"}}}}
1
+ {"name":"std-tutorial-autodemo","version":"1.0.0","description":"Generic scripted input-replay atom: the demo half of a tutorial. Holds one or more named cue scripts (each an ordered list of { at, event, arg } rows where at is a millisecond offset and event is LEFT/RIGHT/JUMP/STOP); listens for TUTORIAL_DEMO_START { demoId } (from std-tutorial-overlay's demoId step) and plays the matching script on a 32ms clock, emitting the semantic DEMO_LEFT / DEMO_RIGHT / DEMO_JUMP / DEMO_STOP events the host board maps onto its own movement. TUTORIAL_DEMO_STOP, DEMO_CANCEL (real user input), or exhausting the cue list end the demo and emit DEMO_STOP so the character stops moving. Renders a small Demo badge while playing. Domain-agnostic: the demo never emits board events (OW_*, etc.) — the organism maps DEMO_* to its own steering, so a demo cannot self-cancel through the board's input path.","orbitals":[{"name":"TutorialAutoDemoOrbital","id":"orb_7YBJTP6S5RCJW64Y4Q178FFYK6","entity":{"name":"AutoDemoData","id":"ent_EQWAEV89ZJ4ZS6SBQFMKVYVB6A","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"playing","type":"boolean","default":false},{"name":"scriptId","type":"string","default":""},{"name":"elapsed","type":"number","default":0},{"name":"cueIndex","type":"number","default":0}]},"traits":[{"name":"AutoDemo","id":"trt_SST59D1PTBVD5RA8TD6KE3CWD4","entityRebindable":true,"entityContract":{"requires":[],"provides":["cueIndex","elapsed","playing","scriptId"]},"effectRow":[{"kind":"emit","resource":"DEMO_JUMP","site":"tick"},{"kind":"emit","resource":"DEMO_LEFT","site":"tick"},{"kind":"emit","resource":"DEMO_RIGHT","site":"tick"},{"kind":"emit","resource":"DEMO_STOP"},{"kind":"emit","resource":"DEMO_STOP","site":"tick"},{"kind":"render-ui","resource":"hud-top"},{"kind":"render-ui","resource":"hud-top","site":"tick"},{"kind":"set","resource":"@entity.cueIndex"},{"kind":"set","resource":"@entity.cueIndex","site":"tick"},{"kind":"set","resource":"@entity.elapsed"},{"kind":"set","resource":"@entity.elapsed","site":"tick"},{"kind":"set","resource":"@entity.playing"},{"kind":"set","resource":"@entity.playing","site":"tick"},{"kind":"set","resource":"@entity.scriptId"},{"kind":"ticks","site":"tick"}],"category":"interaction","linkedEntity":"AutoDemoData","linkedEntityId":"ent_EQWAEV89ZJ4ZS6SBQFMKVYVB6A","entityRefIds":{"AutoDemoData":"ent_EQWAEV89ZJ4ZS6SBQFMKVYVB6A"},"emits":[{"event":"DEMO_LEFT","eventId":"evt_37J9CKBS4PWJBCWE312BMMA3GR","description":"Scripted run-left cue; the host board maps this to its own steer-left.","tier":"domain","scope":"external"},{"event":"DEMO_RIGHT","eventId":"evt_WBP8ND3V56XJK0BXACJ20JFPZC","description":"Scripted run-right cue; the host board maps this to its own steer-right.","tier":"domain","scope":"external"},{"event":"DEMO_JUMP","eventId":"evt_FDAZ83789RM4W3AGZE7ZNM39BX","description":"Scripted jump cue; the host board maps this to its own jump.","tier":"domain","scope":"external"},{"event":"DEMO_STOP","eventId":"evt_X0NFT949WW4YEB8XCW2BWZFCY8","description":"Scripted stop cue (or demo end/cancel); the host board maps this to stop movement.","tier":"domain","scope":"external"}],"stateMachine":{"states":[{"name":"idle","isInitial":true},{"name":"playing"}],"events":[{"key":"INIT","id":"evt_AP1SJSAY07F03G09SP5X9P79RR","name":"Initialize"},{"key":"TUTORIAL_DEMO_START","id":"evt_NWN09S984TM2D3AKABMEZTTQAQ","name":"Tutorial Demo Start","description":"A tutorial step carrying a demoId was shown (std-tutorial-overlay); begin playing the cue script whose id matches demoId.","tier":"domain","payloadSchema":[{"name":"demoId","type":"string","required":true}],"listened":true},{"key":"TUTORIAL_DEMO_STOP","id":"evt_A0ETKH2QE6BQ3E8HD26H6Z68CF","name":"Tutorial Demo Stop","description":"The tutorial left a demo step or was dismissed; stop the demo and release control.","tier":"domain","listened":true},{"key":"DEMO_CANCEL","id":"evt_YDK0X6Z2BJH5SEZAFK9PMYDW8R","name":"Demo Cancel","description":"Real user input was received by the host board; stop the demo immediately and hand control back to the player.","tier":"domain","listened":true},{"key":"DEMO_LEFT","id":"evt_37J9CKBS4PWJBCWE312BMMA3GR","name":"Demo Left","description":"Scripted run-left cue; the host board maps this to its own steer-left.","tier":"domain"},{"key":"DEMO_RIGHT","id":"evt_WBP8ND3V56XJK0BXACJ20JFPZC","name":"Demo Right","description":"Scripted run-right cue; the host board maps this to its own steer-right.","tier":"domain"},{"key":"DEMO_JUMP","id":"evt_FDAZ83789RM4W3AGZE7ZNM39BX","name":"Demo Jump","description":"Scripted jump cue; the host board maps this to its own jump.","tier":"domain"},{"key":"DEMO_STOP","id":"evt_X0NFT949WW4YEB8XCW2BWZFCY8","name":"Demo Stop","description":"Scripted stop cue (or demo end/cancel); the host board maps this to stop movement.","tier":"domain"}],"transitions":[{"from":"idle","to":"idle","event":"INIT","eventId":"evt_AP1SJSAY07F03G09SP5X9P79RR","effects":[["render-ui","hud-top",null]]},{"from":"idle","to":"playing","event":"TUTORIAL_DEMO_START","eventId":"evt_NWN09S984TM2D3AKABMEZTTQAQ","effects":[["set","@entity.scriptId","@payload.demoId"],["set","@entity.elapsed",0],["set","@entity.cueIndex",0],["set","@entity.playing",true],["render-ui","hud-top",{"type":"badge","label":"Demo","variant":"info"}]]},{"from":"idle","to":"idle","event":"TUTORIAL_DEMO_STOP","eventId":"evt_A0ETKH2QE6BQ3E8HD26H6Z68CF","effects":[["render-ui","hud-top",null]]},{"from":"idle","to":"idle","event":"DEMO_CANCEL","eventId":"evt_YDK0X6Z2BJH5SEZAFK9PMYDW8R","effects":[["render-ui","hud-top",null]]},{"from":"playing","to":"idle","event":"INIT","eventId":"evt_AP1SJSAY07F03G09SP5X9P79RR","effects":[["render-ui","hud-top",null]]},{"from":"playing","to":"playing","event":"TUTORIAL_DEMO_START","eventId":"evt_NWN09S984TM2D3AKABMEZTTQAQ","effects":[["set","@entity.scriptId","@payload.demoId"],["set","@entity.elapsed",0],["set","@entity.cueIndex",0],["render-ui","hud-top",{"type":"badge","label":"Demo","variant":"info"}]]},{"from":"playing","to":"idle","event":"TUTORIAL_DEMO_STOP","eventId":"evt_A0ETKH2QE6BQ3E8HD26H6Z68CF","effects":[["set","@entity.playing",false],["render-ui","hud-top",null],["emit","DEMO_STOP",{}]]},{"from":"playing","to":"idle","event":"DEMO_CANCEL","eventId":"evt_YDK0X6Z2BJH5SEZAFK9PMYDW8R","effects":[["set","@entity.playing",false],["render-ui","hud-top",null],["emit","DEMO_STOP",{}]]}]},"ticks":[{"name":"demoTick","interval":32,"guard":["==","@entity.playing",true],"effects":[["set","@entity.elapsed",["+","@entity.elapsed",32]],["let",[["scriptMatch",["array/filter","@config.scripts",["fn","s",["==",["object/get","@s","id"],"@entity.scriptId"]]]]],["let",[["cueList",["if",[">",["array/len","@scriptMatch"],0],["object/get",["array/first","@scriptMatch"],"cues",[]],[]]]],["let",[["cue",["if",["<","@entity.cueIndex",["array/len","@cueList"]],["array/nth","@cueList","@entity.cueIndex"],{"at":999999,"event":""}]]],["do",["if",["<=",["object/get","@cue","at",0],"@entity.elapsed"],["do",["set","@entity.cueIndex",["+","@entity.cueIndex",1]],["if",["==",["object/get","@cue","event",""],"LEFT"],["emit","DEMO_LEFT",{}],null],["if",["==",["object/get","@cue","event",""],"RIGHT"],["emit","DEMO_RIGHT",{}],null],["if",["==",["object/get","@cue","event",""],"JUMP"],["emit","DEMO_JUMP",{}],null],["if",["==",["object/get","@cue","event",""],"STOP"],["emit","DEMO_STOP",{}],null]],null],["if",[">=","@entity.cueIndex",["array/len","@cueList"]],["do",["set","@entity.playing",false],["render-ui","hud-top",null],["emit","DEMO_STOP",{}]],null]]]]]]}],"config":{"scripts":{"type":"[DemoScript]","default":[],"label":"Scripts","description":"Named cue scripts keyed by the tutorial step's demoId; each cue fires its event after `at` milliseconds of the demo clock.","tier":"domain","items":{"type":"object","properties":{"cues":{"name":"cues","type":"array","required":true,"items":{"type":"object","properties":{"arg":{"name":"arg","type":"number","required":false},"event":{"name":"event","type":"string","required":true},"at":{"name":"at","type":"number","required":true}}}},"id":{"name":"id","type":"string","required":true}}}}},"scope":"instance"}],"pages":[{"name":"TutorialAutoDemoPage","id":"pag_TAPW1GQBHQNRVQKS46AZ29VCBF","path":"/tutorial-autodemo","traits":[{"ref":"AutoDemo","refId":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"}]}],"types":{"DemoCue":[{"name":"at","type":"number","required":true},{"name":"event","type":"string","required":true},{"name":"arg","type":"number"}],"DemoScript":[{"name":"id","type":"string","required":true},{"name":"cues","type":"[object]","required":true,"properties":[{"name":"at","type":"number","required":true},{"name":"event","type":"string","required":true},{"name":"arg","type":"number"}]}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_EQWAEV89ZJ4ZS6SBQFMKVYVB6A":{"id":"ent_EQWAEV89ZJ4ZS6SBQFMKVYVB6A","kind":"entity","bakedName":"AutoDemoData","curName":"AutoDemoData","renames":[],"owner":"workspace"},"evt_37J9CKBS4PWJBCWE312BMMA3GR":{"id":"evt_37J9CKBS4PWJBCWE312BMMA3GR","kind":"event","bakedName":"DEMO_LEFT","curName":"DEMO_LEFT","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_A0ETKH2QE6BQ3E8HD26H6Z68CF":{"id":"evt_A0ETKH2QE6BQ3E8HD26H6Z68CF","kind":"event","bakedName":"TUTORIAL_DEMO_STOP","curName":"TUTORIAL_DEMO_STOP","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_AP1SJSAY07F03G09SP5X9P79RR":{"id":"evt_AP1SJSAY07F03G09SP5X9P79RR","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_FDAZ83789RM4W3AGZE7ZNM39BX":{"id":"evt_FDAZ83789RM4W3AGZE7ZNM39BX","kind":"event","bakedName":"DEMO_JUMP","curName":"DEMO_JUMP","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_NWN09S984TM2D3AKABMEZTTQAQ":{"id":"evt_NWN09S984TM2D3AKABMEZTTQAQ","kind":"event","bakedName":"TUTORIAL_DEMO_START","curName":"TUTORIAL_DEMO_START","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_WBP8ND3V56XJK0BXACJ20JFPZC":{"id":"evt_WBP8ND3V56XJK0BXACJ20JFPZC","kind":"event","bakedName":"DEMO_RIGHT","curName":"DEMO_RIGHT","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_X0NFT949WW4YEB8XCW2BWZFCY8":{"id":"evt_X0NFT949WW4YEB8XCW2BWZFCY8","kind":"event","bakedName":"DEMO_STOP","curName":"DEMO_STOP","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"evt_YDK0X6Z2BJH5SEZAFK9PMYDW8R":{"id":"evt_YDK0X6Z2BJH5SEZAFK9PMYDW8R","kind":"event","bakedName":"DEMO_CANCEL","curName":"DEMO_CANCEL","renames":[],"owner":"workspace","parent":"trt_SST59D1PTBVD5RA8TD6KE3CWD4"},"orb_7YBJTP6S5RCJW64Y4Q178FFYK6":{"id":"orb_7YBJTP6S5RCJW64Y4Q178FFYK6","kind":"orbital","bakedName":"TutorialAutoDemoOrbital","curName":"TutorialAutoDemoOrbital","renames":[],"owner":"workspace"},"pag_TAPW1GQBHQNRVQKS46AZ29VCBF":{"id":"pag_TAPW1GQBHQNRVQKS46AZ29VCBF","kind":"page","bakedName":"TutorialAutoDemoPage","curName":"TutorialAutoDemoPage","renames":[],"owner":"workspace"},"trt_SST59D1PTBVD5RA8TD6KE3CWD4":{"id":"trt_SST59D1PTBVD5RA8TD6KE3CWD4","kind":"trait","bakedName":"AutoDemo","curName":"AutoDemo","renames":[],"owner":"workspace"}}}}