@almadar/std 16.253.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.
- package/behaviors/lolo/agent/atoms/std-agent-pool.lolo +355 -0
- package/behaviors/lolo/agent/evals/eval-agent-builder.lolo +159 -0
- package/behaviors/lolo/agent/organisms/std-agent-builder.lolo +321 -26
- package/behaviors/lolo-behavior-contracts.json +1 -1
- package/behaviors/registry/agent/atoms/std-agent-context.orb +1 -1
- package/behaviors/registry/agent/atoms/std-agent-memory.orb +1 -1
- package/behaviors/registry/agent/atoms/std-agent-planner.orb +1 -1
- package/behaviors/registry/agent/atoms/std-agent-pool.orb +1 -0
- package/behaviors/registry/agent/atoms/std-agent-proposal.orb +1 -1
- package/behaviors/registry/agent/atoms/std-agent-session.orb +1 -1
- package/behaviors/registry/agent/atoms/std-agent-suggestions.orb +1 -1
- package/behaviors/registry/agent/atoms/std-agent-tool-call.orb +1 -1
- package/behaviors/registry/agent/atoms/std-agent-tool-loop.orb +1 -1
- package/behaviors/registry/agent/atoms/std-agent-trace.orb +1 -1
- package/behaviors/registry/agent/evals/eval-agent-builder.orb +1 -0
- package/behaviors/registry/agent/organisms/std-agent-assistant.orb +1 -1
- package/behaviors/registry/agent/organisms/std-agent-builder.orb +1 -1
- package/behaviors/registry/infra/atoms/std-analytics.orb +1 -1
- package/behaviors/registry/infra/atoms/std-approval-gate.orb +1 -1
- package/behaviors/registry/infra/atoms/std-audit-capture.orb +1 -1
- package/behaviors/registry/infra/atoms/std-cache-aside.orb +1 -1
- package/behaviors/registry/infra/atoms/std-calendar-sync.orb +1 -1
- package/behaviors/registry/infra/atoms/std-cascade-on-delete.orb +1 -1
- package/behaviors/registry/infra/atoms/std-circuit-breaker.orb +1 -1
- package/behaviors/registry/infra/atoms/std-cross-reference.orb +1 -1
- package/behaviors/registry/infra/atoms/std-data-erasure.orb +1 -1
- package/behaviors/registry/infra/atoms/std-data-import.orb +1 -1
- package/behaviors/registry/infra/atoms/std-global-search.orb +1 -1
- package/behaviors/registry/infra/atoms/std-knowledge-loop.orb +1 -1
- package/behaviors/registry/infra/atoms/std-lifecycle.orb +1 -1
- package/behaviors/registry/infra/atoms/std-migration-job.orb +1 -1
- package/behaviors/registry/infra/atoms/std-mod-queue.orb +1 -1
- package/behaviors/registry/infra/atoms/std-notification-center.orb +1 -1
- package/behaviors/registry/infra/atoms/std-notification-preferences.orb +1 -1
- package/behaviors/registry/infra/atoms/std-notify-on-event.orb +1 -1
- package/behaviors/registry/infra/atoms/std-page-search.orb +1 -1
- package/behaviors/registry/infra/atoms/std-page-watch.orb +1 -1
- package/behaviors/registry/infra/atoms/std-permission-matrix.orb +1 -1
- package/behaviors/registry/infra/atoms/std-rate-limiter.orb +1 -1
- package/behaviors/registry/infra/atoms/std-reminder-scheduler.orb +1 -1
- package/behaviors/registry/infra/atoms/std-review-cycle.orb +1 -1
- package/behaviors/registry/infra/atoms/std-row-access-control.orb +1 -1
- package/behaviors/registry/infra/atoms/std-status-lifecycle.orb +1 -1
- package/behaviors/registry/infra/organisms/std-status-lifecycle-control.orb +1 -1
- package/behaviors/registry/ml/atoms/std-data-collector.orb +1 -1
- package/behaviors/registry/ml/atoms/std-graph-builder.orb +1 -1
- package/behaviors/registry/ml/atoms/std-ml-classify.orb +1 -1
- package/behaviors/registry/ml/atoms/std-ml-exact-check.orb +1 -1
- package/behaviors/registry/ml/atoms/std-ml-infer.orb +1 -1
- package/behaviors/registry/ml/atoms/std-ml-label-capture.orb +1 -1
- package/behaviors/registry/ml/atoms/std-ml-lookup.orb +1 -1
- package/behaviors/registry/ml/atoms/std-ml-posterior.orb +1 -1
- package/behaviors/registry/ml/atoms/std-ml-similarity.orb +1 -1
- package/behaviors/registry/ml/atoms/std-tokenizer.orb +1 -1
- package/behaviors/registry/ml/atoms/std-weight-validator.orb +1 -1
- package/behaviors/registry/ml/organisms/std-escalating-decision.orb +1 -1
- package/behaviors/registry/ml/organisms/std-knowledge-tracing.orb +1 -1
- package/behaviors/registry/ui/avl/atoms/std-avl-cosmic-zoom.orb +1 -1
- package/behaviors/registry/ui/avl/atoms/ui-avl-glyph.orb +1 -1
- package/behaviors/registry/ui/avl/atoms/ui-avl-state-machine.orb +1 -1
- package/behaviors/registry/ui/avl/atoms/ui-avl-transition-detail.orb +1 -1
- package/behaviors/registry/ui/avl/atoms/ui-avl-transition-explainer.orb +1 -1
- package/behaviors/registry/ui/avl/atoms/ui-behavior-view.orb +1 -1
- package/behaviors/registry/ui/avl/atoms/ui-module-card.orb +1 -1
- package/behaviors/registry/ui/avl/organisms/ui-flow-canvas.orb +1 -1
- package/behaviors/registry/ui/avl/organisms/ui-layers-panel.orb +1 -1
- package/behaviors/registry/ui/avl/organisms/ui-orb-inspector.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-app-layout.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-app-search.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-behavior-catalog.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-behavior-tour.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-billable-hour.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-board.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-book-reader.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-browse.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-calendar.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-card-grid.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-confirmation.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-dashboard-grid-embedded.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-date-range.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-doc-page.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-esign-flow.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-esign-request.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-event-log.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-export.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-file-store.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-filter.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-form-advanced.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-gallery.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-gantt-schedule.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-geosearch.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-graphs.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-hero.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-home.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-image-upload-multi.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-import.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-language-picker.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-media-section.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-modal-editor.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-modal.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-multi-party-flow.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-notification-panel.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-panel-launcher.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-pricing.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-proof.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-prose.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-rating-review.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-record-detail.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-recurrence.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-related.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-role-gate.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-saved-search.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-scatter.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-scoped-list.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-search.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-selection.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-site-footer.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-site-header.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-slide-deck.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-stat-band.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-stats.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-step-flow.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-steps.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-tabs.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-tag-strip.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-tag-taxonomy.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-thread.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-tree.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-version-history.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-wizard.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-workspace-layout.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-animated-graphic.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-animated-reveal.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-aside.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-atlas-image.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-atlas-panel.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-avatar.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-badge.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-box.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-button.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-card.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-center.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-checkbox.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-conditional-wrapper.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-confetti-effect.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-day-cell.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-dialog.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-divider.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-filter-pill.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-flip-container.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-game-icon.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-hstack.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-icon.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-image.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-infinite-scroll-sentinel.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-input.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-label.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-law-reference-tooltip.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-overlay.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-pattern-tile.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-presence.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-progress-bar.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-radio.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-range-slider.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-section-header.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-select.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-spacer.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-sparkline.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-spinner.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-stack.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-status-dot.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-svg-branch.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-svg-connection.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-svg-flow.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-svg-grid.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-svg-lobe.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-svg-mesh.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-svg-morph.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-svg-node.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-svg-pulse.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-svg-ring.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-svg-shield.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-svg-stack.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-switch.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-text-highlight.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-textarea.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-theme-toggle.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-time-slot-cell.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-trend-indicator.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-typewriter-text.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-typography.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-video-embed.orb +1 -1
- package/behaviors/registry/ui/core/atoms/ui-vstack.orb +1 -1
- package/behaviors/registry/ui/core/molecules/std-stat-rows.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-accordion.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-activation-block.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-activity-rail.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-agent-activity-feed.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-agent-activity-row.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-agent-chat-feed.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-alert.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-animated-counter.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-bloom-quiz-block.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-branching-logic-builder.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-breadcrumb.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-calendar-grid.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-carousel.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-change-list.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-chart-legend.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-chart.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-code-block.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-command-palette.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-commit-row.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-confirm-dialog.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-connection-block.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-container.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-content-renderer.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-data-grid.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-data-list.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-date-range-picker.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-date-range-selector.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-doc-breadcrumb.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-doc-pagination.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-doc-search.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-doc-sidebar.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-doc-toc.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-document-details.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-document-panel.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-document-viewer.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-drawer.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-edge-decoration.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-emoji-picker.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-empty-state.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-error-boundary.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-error-state.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-feature-card.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-feature-grid.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-file-tree.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-filter-group.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-flex.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-flip-card.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-floating-action-button.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-floating-toolbar.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-form-actions.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-form-field.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-form-layout.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-form-section-header.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-fx-overlay.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-gantt.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-geometric-pattern.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-gradient-divider.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-graph-canvas.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-graph-view.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-grid.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-header.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-icon-button.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-import-preview-tree.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-import-progress.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-import-source-picker.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-input-group.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-jazari-state-machine.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-lightbox.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-likert-scale.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-line-chart.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-loading-state.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-map-view.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-markdown-content.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-matrix-question.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-menu.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-meter.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-modal.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-navigation.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-notification.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-number-stepper.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-option-constraint-group.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-orbital-visualization.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-page-header.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-page-transition.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-pagination.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-popover.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-positioned-canvas.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-progress-dots.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-pull-to-refresh.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-qr-scanner.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-quiz-block.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-reflection-block.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-relation-select.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-repeatable-form-section.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-reply-tree.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-rich-text-editor.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-scaled-diagram.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-search-input.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-section.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-side-panel.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-sidebar.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-signature-pad.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-simple-grid.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-skeleton.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-social-proof.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-sortable-list.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-split.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-star-rating.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-stat-display.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-swipeable-row.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-table-view.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-tabs.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-tag-input.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-tooltip.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-top-nav-item.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-upload-drop-zone.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-version-diff.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-violation-alert.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-vote-stack.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-wizard-container.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-wizard-navigation.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-wizard-progress.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-chat-bar.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-code-runner-panel.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-dashboard-grid.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-detail-panel.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-dock-layout.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-drawer-slot.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-form-section.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-form.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-master-detail-layout.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-media-gallery.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-modal-slot.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-runtime-debugger.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-segment-renderer.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-split-pane.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-stat-card.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-state-machine-view.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-subagent-trace-panel.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-tabbed-container.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-timeline.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-toast-slot.orb +1 -1
- package/behaviors/registry/ui/core/templates/ui-auth-layout.orb +1 -1
- package/behaviors/registry/ui/core/templates/ui-counter-template.orb +1 -1
- package/behaviors/registry/ui/core/templates/ui-dashboard-layout.orb +1 -1
- package/behaviors/registry/ui/core/templates/ui-generic-app-template.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-arcade-play.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-area-fill.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-audio-cue.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-camera-rig.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-chase-ai.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-choice-gate.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-coef-pad.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-curve-fog.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-dungeon-combat.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-fx-narrative.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-fx-particles.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-fx-trail.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-gate-lock.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-gather.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-gold.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-grid-tactics.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-hero-nav.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-lives.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-loop-lock.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-motion-body.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-objective-reach.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-pad-lock.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-patience.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-patrol-hazard.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-pickup.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-platformer-body.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-production.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-score.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-tutorial-autodemo.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-tutorial-overlay.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-velocity-gate.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-xp.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-zone-card.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-action-palette.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-action-tile.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-canvas-2d.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-canvas.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-choice-button.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-control-button.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-control-grid.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-dialogue-bubble.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-draw-fx-layer.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-draw-group.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-draw-mesh.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-draw-shape-layer.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-draw-shape.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-draw-skinned-mesh.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-draw-sprite-layer.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-draw-sprite.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-draw-text-layer.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-draw-text.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-game-audio-cue.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-game-audio-toggle.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-game-hud.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-game-menu.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-health-bar.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-score-display.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-sequence-bar.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-stat-badge.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-state-graph.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-state-json-view.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-timer-display.orb +1 -1
- package/behaviors/registry/ui/game/atoms/ui-trait-slot.orb +1 -1
- package/behaviors/registry/ui/game/organisms/std-arcade-board-3d.orb +1 -1
- package/behaviors/registry/ui/game/organisms/std-crew-board-2d.orb +1 -1
- package/behaviors/registry/ui/game/organisms/std-dungeon-board-2d.orb +1 -1
- package/behaviors/registry/ui/game/organisms/std-market-board-3d.orb +1 -1
- package/behaviors/registry/ui/game/organisms/std-objective-board-3d.orb +1 -1
- package/behaviors/registry/ui/game/organisms/std-platformer-board-2d.orb +1 -1
- package/behaviors/registry/ui/game/organisms/std-platformer-puzzle.orb +1 -1
- package/behaviors/registry/ui/game/organisms/std-survival-board-3d.orb +1 -1
- package/behaviors/registry/ui/game/organisms/std-tactics-board-2d.orb +1 -1
- package/behaviors/registry/ui/game/organisms/std-tactics-board-3d.orb +1 -1
- package/behaviors/registry/ui/game/organisms/std-worldmap-board-2d.orb +1 -1
- package/behaviors/registry/ui/game/templates/ui-game-shell.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-arrangement.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-compare.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-coupled-sim.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-derivation.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-diagram.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-doser.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-estimate.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-fx-cues.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-generate.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-goal-seek.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-grid-sim.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-hotspot.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-live-sim.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-measure.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-param-explorer.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-perturb.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-predict.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-sample-accumulator.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-sandbox.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-scatter-fit.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-scenario.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-sim-3d.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-slope-probe.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-speed-drill.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-stepper.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-trace-player.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-transport.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-tree.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/ui-algo-graph-canvas.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/ui-algorithm-canvas.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/ui-biology-canvas.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/ui-chemistry-canvas.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/ui-learning-canvas.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/ui-math-canvas.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/ui-physics-canvas.orb +1 -1
- package/dist/behaviors-embeddings.hash.json +2 -2
- package/dist/behaviors-embeddings.json +1 -1
- package/dist/knob-embeddings.hash.json +2 -2
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"std-lives","version":"1.0.0","description":"Headless lives + checkpoint authority for boards with stakes: owns lives, the current respawn point, and nothing else. DAMAGE (call sites rename their hazard sources — BODY_HAZARD, BODY_FELL, PATROL_HIT — onto it) costs one life, respecting an invulnerability window so overlapping hazards can't chain-drain; losing a life emits LIFE_LOST plus RESPAWN with the current checkpoint (boards route RESPAWN to the body authority's PLACE), and losing the last emits GAME_OVER instead. Checkpoints advance automatically: BODY_MOVED crossing a configured checkpoint's atX moves the respawn point forward and emits CHECKPOINT_REACHED once per checkpoint (tracked by furthest atX reached, so checkpoints are ordered along the run). RESTART reseeds lives and respawn to the spawn. Renders nothing — HUDs read lives off the shared entity. Corresponds to the design-sheet field(s): challenge, feedback.","orbitals":[{"name":"LivesOrbital","id":"orb_HQKNNVDEMNQAAXDGM96W2M92SP","entity":{"name":"LivesData","id":"ent_S5EFWWET0SD0CH3R0AWVHH523G","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"lives","type":"number","default":3},{"name":"respawnX","type":"number","default":0},{"name":"respawnY","type":"number","default":0},{"name":"cpX","type":"number","default":-1000000},{"name":"lastHitAt","type":"number","default":0}],"shared":true},"traits":[{"name":"Lives","id":"trt_QQMSETSNDTTPX3PDMZ76YPN58N","entityRebindable":true,"entityContract":{"requires":[],"provides":["cpX","lastHitAt","lives","respawnX","respawnY"]},"effectRow":[{"kind":"emit","resource":"CHECKPOINT_REACHED"},{"kind":"emit","resource":"GAME_OVER"},{"kind":"emit","resource":"LIFE_LOST"},{"kind":"emit","resource":"RESPAWN"},{"kind":"set","resource":"@entity.cpX"},{"kind":"set","resource":"@entity.lastHitAt"},{"kind":"set","resource":"@entity.lives"},{"kind":"set","resource":"@entity.respawnX"},{"kind":"set","resource":"@entity.respawnY"}],"category":"lifecycle","linkedEntity":"LivesData","linkedEntityId":"ent_S5EFWWET0SD0CH3R0AWVHH523G","entityRefIds":{"LivesData":"ent_S5EFWWET0SD0CH3R0AWVHH523G"},"emits":[{"event":"LIFE_LOST","eventId":"evt_G9MF5ABEAQQ5BGPYCWQ81A9STG","description":"A life was spent (post-invulnerability check); carries the lives remaining. Boards layer damage fx / HUD heartbeat.","tier":"domain","scope":"external","payloadSchema":[{"name":"lives","type":"number","required":true}]},{"event":"RESPAWN","eventId":"evt_TR9EFJM05D02PWJG15YTPH1E50","description":"The checkpoint the body should restart from after this life loss; boards forward it to the body authority's PLACE.","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"event":"GAME_OVER","eventId":"evt_XCVFYT43B91NMZDYTNS7C92QER","description":"The last life was spent; boards show the game-over overlay and wait for RESTART.","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true}]},{"event":"CHECKPOINT_REACHED","eventId":"evt_BDR82ZKMWDTE6ZCAF7MM322K96","description":"The player crossed a checkpoint's atX for the first time this run; the respawn point moved to it. Boards layer flag/save fx.","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true}]}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_P9VEHG72ZSHFWHXMFAVWF1ZKWH","name":"Initialize"},{"key":"DAMAGE","id":"evt_GQQJW88BWZ5YFSTB70FZ9622SK","name":"Damage","payloadSchema":[{"name":"source","type":"string"}],"listened":true},{"key":"BODY_MOVED","id":"evt_VSEQS1S5H8JRM7BG3HTNTR3GMB","name":"Body Moved","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}],"listened":true},{"key":"RESTART","id":"evt_6F19CFEE9G74REYPYYCJTAGDB4","name":"Restart","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"LIFE_LOST","id":"evt_G9MF5ABEAQQ5BGPYCWQ81A9STG","name":"Life Lost","description":"A life was spent (post-invulnerability check); carries the lives remaining. Boards layer damage fx / HUD heartbeat.","tier":"domain","payloadSchema":[{"name":"lives","type":"number","required":true}]},{"key":"RESPAWN","id":"evt_TR9EFJM05D02PWJG15YTPH1E50","name":"Respawn","description":"The checkpoint the body should restart from after this life loss; boards forward it to the body authority's PLACE.","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"key":"GAME_OVER","id":"evt_XCVFYT43B91NMZDYTNS7C92QER","name":"Game Over","description":"The last life was spent; boards show the game-over overlay and wait for RESTART.","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true}]},{"key":"CHECKPOINT_REACHED","id":"evt_BDR82ZKMWDTE6ZCAF7MM322K96","name":"Checkpoint Reached","description":"The player crossed a checkpoint's atX for the first time this run; the respawn point moved to it. Boards layer flag/save fx.","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true}]}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_P9VEHG72ZSHFWHXMFAVWF1ZKWH","effects":[["set","@entity.lives","@config.maxLives"],["set","@entity.respawnX","@config.spawnX"],["set","@entity.respawnY","@config.spawnY"],["set","@entity.cpX",["-",0,1000000]],["set","@entity.lastHitAt",0]]},{"from":"active","to":"active","event":"DAMAGE","eventId":"evt_GQQJW88BWZ5YFSTB70FZ9622SK","guard":["and","@config.running",[">","@entity.lives",0]],"effects":[["if",[">=",["-",["time/now"],"@entity.lastHitAt"],"@config.invulnMs"],["do",["set","@entity.lastHitAt",["time/now"]],["set","@entity.lives",["-","@entity.lives",1]],["if",[">","@entity.lives",0],["do",["emit","LIFE_LOST",{"lives":"@entity.lives"}],["emit","RESPAWN",{"x":"@entity.respawnX","y":"@entity.respawnY"}]],["emit","GAME_OVER",{"id":"lives"}]]],null]]},{"from":"active","to":"active","event":"BODY_MOVED","eventId":"evt_VSEQS1S5H8JRM7BG3HTNTR3GMB","guard":"@config.running","effects":[["let",[["reached",["array/filter","@config.checkpoints",["fn","c",["and",["<=",["object/get","@c","atX"],"@payload.x"],[">",["object/get","@c","atX"],"@entity.cpX"]]]]]],["if",[">",["array/len","@reached"],0],["let",[["cp",["array/last","@reached"]]],["do",["set","@entity.respawnX",["object/get","@cp","x"]],["set","@entity.respawnY",["object/get","@cp","y"]],["set","@entity.cpX",["object/get","@cp","atX"]],["emit","CHECKPOINT_REACHED",{"id":["object/get","@cp","id"]}]]],null]]]},{"from":"active","to":"active","event":"RESTART","eventId":"evt_6F19CFEE9G74REYPYYCJTAGDB4","effects":[["set","@entity.lives","@config.maxLives"],["set","@entity.respawnX","@config.spawnX"],["set","@entity.respawnY","@config.spawnY"],["set","@entity.cpX",["-",0,1000000]],["set","@entity.lastHitAt",0]]}]},"config":{"spawnX":{"type":"number","default":0,"label":"Spawn X","description":"Respawn x before any checkpoint is reached (match the body authority's spawn).","tier":"domain"},"spawnY":{"type":"number","default":0,"label":"Spawn Y","description":"Respawn y before any checkpoint is reached.","tier":"domain"},"checkpoints":{"type":"[Checkpoint]","default":[],"label":"Checkpoints","description":"Ordered along the run: when the player's x crosses atX the respawn point moves to (x, y). Must be sorted by atX ascending.","tier":"domain","items":{"type":"object","properties":{"x":{"name":"x","type":"number","required":true},"id":{"name":"id","type":"string","required":true},"atX":{"name":"atX","type":"number","required":true},"y":{"name":"y","type":"number","required":true}}}},"running":{"type":"boolean","default":true,"label":"Running","description":"When true, DAMAGE and checkpoint crossings are processed; toggle to make the run harmless (practice mode).","tier":"domain"},"invulnMs":{"type":"number","default":1500,"label":"Invulnerability Window (ms)","description":"Milliseconds after a accepted hit during which further DAMAGE is ignored, so a hazard overlapping the respawn can't chain-drain.","tier":"domain"},"maxLives":{"type":"number","default":3,"label":"Max Lives","description":"Lives seeded on INIT/RESTART; reaching zero fires GAME_OVER.","tier":"domain"}},"scope":"instance"}],"pages":[{"name":"LivesPage","id":"pag_QQRP1A2B565JKE48NAZYVCM8R7","path":"/lives","traits":[{"ref":"Lives","refId":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"}]}],"types":{"Checkpoint":[{"name":"id","type":"string","required":true},{"name":"atX","type":"number","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_S5EFWWET0SD0CH3R0AWVHH523G":{"id":"ent_S5EFWWET0SD0CH3R0AWVHH523G","kind":"entity","bakedName":"LivesData","curName":"LivesData","renames":[],"owner":"workspace"},"evt_6F19CFEE9G74REYPYYCJTAGDB4":{"id":"evt_6F19CFEE9G74REYPYYCJTAGDB4","kind":"event","bakedName":"RESTART","curName":"RESTART","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_BDR82ZKMWDTE6ZCAF7MM322K96":{"id":"evt_BDR82ZKMWDTE6ZCAF7MM322K96","kind":"event","bakedName":"CHECKPOINT_REACHED","curName":"CHECKPOINT_REACHED","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_G9MF5ABEAQQ5BGPYCWQ81A9STG":{"id":"evt_G9MF5ABEAQQ5BGPYCWQ81A9STG","kind":"event","bakedName":"LIFE_LOST","curName":"LIFE_LOST","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_GQQJW88BWZ5YFSTB70FZ9622SK":{"id":"evt_GQQJW88BWZ5YFSTB70FZ9622SK","kind":"event","bakedName":"DAMAGE","curName":"DAMAGE","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_P9VEHG72ZSHFWHXMFAVWF1ZKWH":{"id":"evt_P9VEHG72ZSHFWHXMFAVWF1ZKWH","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_TR9EFJM05D02PWJG15YTPH1E50":{"id":"evt_TR9EFJM05D02PWJG15YTPH1E50","kind":"event","bakedName":"RESPAWN","curName":"RESPAWN","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_VSEQS1S5H8JRM7BG3HTNTR3GMB":{"id":"evt_VSEQS1S5H8JRM7BG3HTNTR3GMB","kind":"event","bakedName":"BODY_MOVED","curName":"BODY_MOVED","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_XCVFYT43B91NMZDYTNS7C92QER":{"id":"evt_XCVFYT43B91NMZDYTNS7C92QER","kind":"event","bakedName":"GAME_OVER","curName":"GAME_OVER","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"orb_HQKNNVDEMNQAAXDGM96W2M92SP":{"id":"orb_HQKNNVDEMNQAAXDGM96W2M92SP","kind":"orbital","bakedName":"LivesOrbital","curName":"LivesOrbital","renames":[],"owner":"workspace"},"pag_QQRP1A2B565JKE48NAZYVCM8R7":{"id":"pag_QQRP1A2B565JKE48NAZYVCM8R7","kind":"page","bakedName":"LivesPage","curName":"LivesPage","renames":[],"owner":"workspace"},"trt_QQMSETSNDTTPX3PDMZ76YPN58N":{"id":"trt_QQMSETSNDTTPX3PDMZ76YPN58N","kind":"trait","bakedName":"Lives","curName":"Lives","renames":[],"owner":"workspace"}}}}
|
|
1
|
+
{"name":"std-lives","version":"1.0.0","description":"Headless lives + checkpoint authority for boards with stakes: owns lives, the current respawn point, and nothing else. DAMAGE (call sites rename their hazard sources — BODY_HAZARD, BODY_FELL, PATROL_HIT — onto it) costs one life, respecting an invulnerability window so overlapping hazards can't chain-drain; losing a life emits LIFE_LOST plus RESPAWN with the current checkpoint (boards route RESPAWN to the body authority's PLACE), and losing the last emits GAME_OVER instead. Checkpoints advance automatically: BODY_MOVED crossing a configured checkpoint's atX moves the respawn point forward and emits CHECKPOINT_REACHED once per checkpoint (tracked by furthest atX reached, so checkpoints are ordered along the run). RESTART reseeds lives and respawn to the spawn. Renders nothing — HUDs read lives off the shared entity. Corresponds to the design-sheet field(s): challenge, feedback.","orbitals":[{"name":"LivesOrbital","id":"orb_HQKNNVDEMNQAAXDGM96W2M92SP","entity":{"name":"LivesData","id":"ent_S5EFWWET0SD0CH3R0AWVHH523G","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"lives","type":"number","default":3},{"name":"respawnX","type":"number","default":0},{"name":"respawnY","type":"number","default":0},{"name":"cpX","type":"number","default":-1000000},{"name":"lastHitAt","type":"number","default":0}],"shared":true},"traits":[{"name":"Lives","id":"trt_QQMSETSNDTTPX3PDMZ76YPN58N","entityRebindable":true,"entityContract":{"requires":[],"provides":["cpX","lastHitAt","lives","respawnX","respawnY"]},"effectRow":[{"kind":"emit","resource":"CHECKPOINT_REACHED"},{"kind":"emit","resource":"GAME_OVER"},{"kind":"emit","resource":"LIFE_LOST"},{"kind":"emit","resource":"RESPAWN"},{"kind":"set","resource":"@entity.cpX"},{"kind":"set","resource":"@entity.lastHitAt"},{"kind":"set","resource":"@entity.lives"},{"kind":"set","resource":"@entity.respawnX"},{"kind":"set","resource":"@entity.respawnY"}],"category":"lifecycle","linkedEntity":"LivesData","linkedEntityId":"ent_S5EFWWET0SD0CH3R0AWVHH523G","entityRefIds":{"LivesData":"ent_S5EFWWET0SD0CH3R0AWVHH523G"},"emits":[{"event":"LIFE_LOST","eventId":"evt_G9MF5ABEAQQ5BGPYCWQ81A9STG","description":"A life was spent (post-invulnerability check); carries the lives remaining. Boards layer damage fx / HUD heartbeat.","tier":"domain","scope":"external","payloadSchema":[{"name":"lives","type":"number","required":true}]},{"event":"RESPAWN","eventId":"evt_TR9EFJM05D02PWJG15YTPH1E50","description":"The checkpoint the body should restart from after this life loss; boards forward it to the body authority's PLACE.","tier":"domain","scope":"external","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"event":"GAME_OVER","eventId":"evt_XCVFYT43B91NMZDYTNS7C92QER","description":"The last life was spent; boards show the game-over overlay and wait for RESTART.","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true}]},{"event":"CHECKPOINT_REACHED","eventId":"evt_BDR82ZKMWDTE6ZCAF7MM322K96","description":"The player crossed a checkpoint's atX for the first time this run; the respawn point moved to it. Boards layer flag/save fx.","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true}]}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_P9VEHG72ZSHFWHXMFAVWF1ZKWH","name":"Initialize"},{"key":"DAMAGE","id":"evt_GQQJW88BWZ5YFSTB70FZ9622SK","name":"Damage","payloadSchema":[{"name":"source","type":"string"}],"listened":true},{"key":"BODY_MOVED","id":"evt_VSEQS1S5H8JRM7BG3HTNTR3GMB","name":"Body Moved","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}],"listened":true},{"key":"RESTART","id":"evt_6F19CFEE9G74REYPYYCJTAGDB4","name":"Restart","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"LIFE_LOST","id":"evt_G9MF5ABEAQQ5BGPYCWQ81A9STG","name":"Life Lost","description":"A life was spent (post-invulnerability check); carries the lives remaining. Boards layer damage fx / HUD heartbeat.","tier":"domain","payloadSchema":[{"name":"lives","type":"number","required":true}]},{"key":"RESPAWN","id":"evt_TR9EFJM05D02PWJG15YTPH1E50","name":"Respawn","description":"The checkpoint the body should restart from after this life loss; boards forward it to the body authority's PLACE.","tier":"domain","payloadSchema":[{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]},{"key":"GAME_OVER","id":"evt_XCVFYT43B91NMZDYTNS7C92QER","name":"Game Over","description":"The last life was spent; boards show the game-over overlay and wait for RESTART.","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true}]},{"key":"CHECKPOINT_REACHED","id":"evt_BDR82ZKMWDTE6ZCAF7MM322K96","name":"Checkpoint Reached","description":"The player crossed a checkpoint's atX for the first time this run; the respawn point moved to it. Boards layer flag/save fx.","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true}]}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_P9VEHG72ZSHFWHXMFAVWF1ZKWH","effects":[["set","@entity.lives","@config.maxLives"],["set","@entity.respawnX","@config.spawnX"],["set","@entity.respawnY","@config.spawnY"],["set","@entity.cpX",["-",0,1000000]],["set","@entity.lastHitAt",0]]},{"from":"active","to":"active","event":"DAMAGE","eventId":"evt_GQQJW88BWZ5YFSTB70FZ9622SK","guard":["and","@config.running",[">","@entity.lives",0]],"effects":[["if",[">=",["-",["time/now"],"@entity.lastHitAt"],"@config.invulnMs"],["do",["set","@entity.lastHitAt",["time/now"]],["set","@entity.lives",["-","@entity.lives",1]],["if",[">","@entity.lives",0],["do",["emit","LIFE_LOST",{"lives":"@entity.lives"}],["emit","RESPAWN",{"x":"@entity.respawnX","y":"@entity.respawnY"}]],["emit","GAME_OVER",{"id":"lives"}]]],null]]},{"from":"active","to":"active","event":"BODY_MOVED","eventId":"evt_VSEQS1S5H8JRM7BG3HTNTR3GMB","guard":"@config.running","effects":[["let",[["reached",["array/filter","@config.checkpoints",["fn","c",["and",["<=",["object/get","@c","atX"],"@payload.x"],[">",["object/get","@c","atX"],"@entity.cpX"]]]]]],["if",[">",["array/len","@reached"],0],["let",[["cp",["array/last","@reached"]]],["do",["set","@entity.respawnX",["object/get","@cp","x"]],["set","@entity.respawnY",["object/get","@cp","y"]],["set","@entity.cpX",["object/get","@cp","atX"]],["emit","CHECKPOINT_REACHED",{"id":["object/get","@cp","id"]}]]],null]]]},{"from":"active","to":"active","event":"RESTART","eventId":"evt_6F19CFEE9G74REYPYYCJTAGDB4","effects":[["set","@entity.lives","@config.maxLives"],["set","@entity.respawnX","@config.spawnX"],["set","@entity.respawnY","@config.spawnY"],["set","@entity.cpX",["-",0,1000000]],["set","@entity.lastHitAt",0]]}]},"config":{"spawnY":{"type":"number","default":0,"label":"Spawn Y","description":"Respawn y before any checkpoint is reached.","tier":"domain"},"invulnMs":{"type":"number","default":1500,"label":"Invulnerability Window (ms)","description":"Milliseconds after a accepted hit during which further DAMAGE is ignored, so a hazard overlapping the respawn can't chain-drain.","tier":"domain"},"checkpoints":{"type":"[Checkpoint]","default":[],"label":"Checkpoints","description":"Ordered along the run: when the player's x crosses atX the respawn point moves to (x, y). Must be sorted by atX ascending.","tier":"domain","items":{"type":"object","properties":{"id":{"name":"id","type":"string","required":true},"x":{"name":"x","type":"number","required":true},"y":{"name":"y","type":"number","required":true},"atX":{"name":"atX","type":"number","required":true}}}},"maxLives":{"type":"number","default":3,"label":"Max Lives","description":"Lives seeded on INIT/RESTART; reaching zero fires GAME_OVER.","tier":"domain"},"spawnX":{"type":"number","default":0,"label":"Spawn X","description":"Respawn x before any checkpoint is reached (match the body authority's spawn).","tier":"domain"},"running":{"type":"boolean","default":true,"label":"Running","description":"When true, DAMAGE and checkpoint crossings are processed; toggle to make the run harmless (practice mode).","tier":"domain"}},"scope":"instance"}],"pages":[{"name":"LivesPage","id":"pag_QQRP1A2B565JKE48NAZYVCM8R7","path":"/lives","traits":[{"ref":"Lives","refId":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"}]}],"types":{"Checkpoint":[{"name":"id","type":"string","required":true},{"name":"atX","type":"number","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_S5EFWWET0SD0CH3R0AWVHH523G":{"id":"ent_S5EFWWET0SD0CH3R0AWVHH523G","kind":"entity","bakedName":"LivesData","curName":"LivesData","renames":[],"owner":"workspace"},"evt_6F19CFEE9G74REYPYYCJTAGDB4":{"id":"evt_6F19CFEE9G74REYPYYCJTAGDB4","kind":"event","bakedName":"RESTART","curName":"RESTART","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_BDR82ZKMWDTE6ZCAF7MM322K96":{"id":"evt_BDR82ZKMWDTE6ZCAF7MM322K96","kind":"event","bakedName":"CHECKPOINT_REACHED","curName":"CHECKPOINT_REACHED","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_G9MF5ABEAQQ5BGPYCWQ81A9STG":{"id":"evt_G9MF5ABEAQQ5BGPYCWQ81A9STG","kind":"event","bakedName":"LIFE_LOST","curName":"LIFE_LOST","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_GQQJW88BWZ5YFSTB70FZ9622SK":{"id":"evt_GQQJW88BWZ5YFSTB70FZ9622SK","kind":"event","bakedName":"DAMAGE","curName":"DAMAGE","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_P9VEHG72ZSHFWHXMFAVWF1ZKWH":{"id":"evt_P9VEHG72ZSHFWHXMFAVWF1ZKWH","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_TR9EFJM05D02PWJG15YTPH1E50":{"id":"evt_TR9EFJM05D02PWJG15YTPH1E50","kind":"event","bakedName":"RESPAWN","curName":"RESPAWN","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_VSEQS1S5H8JRM7BG3HTNTR3GMB":{"id":"evt_VSEQS1S5H8JRM7BG3HTNTR3GMB","kind":"event","bakedName":"BODY_MOVED","curName":"BODY_MOVED","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"evt_XCVFYT43B91NMZDYTNS7C92QER":{"id":"evt_XCVFYT43B91NMZDYTNS7C92QER","kind":"event","bakedName":"GAME_OVER","curName":"GAME_OVER","renames":[],"owner":"workspace","parent":"trt_QQMSETSNDTTPX3PDMZ76YPN58N"},"orb_HQKNNVDEMNQAAXDGM96W2M92SP":{"id":"orb_HQKNNVDEMNQAAXDGM96W2M92SP","kind":"orbital","bakedName":"LivesOrbital","curName":"LivesOrbital","renames":[],"owner":"workspace"},"pag_QQRP1A2B565JKE48NAZYVCM8R7":{"id":"pag_QQRP1A2B565JKE48NAZYVCM8R7","kind":"page","bakedName":"LivesPage","curName":"LivesPage","renames":[],"owner":"workspace"},"trt_QQMSETSNDTTPX3PDMZ76YPN58N":{"id":"trt_QQMSETSNDTTPX3PDMZ76YPN58N","kind":"trait","bakedName":"Lives","curName":"Lives","renames":[],"owner":"workspace"}}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"std-loop-lock","version":"1.0.0","description":"Headless winding-lock mechanic: locks that open only after the player travels a full revolution around their anchor. Listens BODY_MOVED and, while the player stays within a radial band of a lock's ring, accumulates the wrapped angular delta of their position into swept (radians, signed — either direction counts); when |swept| reaches turns × 2π the lock flips unlocked and emits LOOP_UNLOCKED once. Entering the band reseeds the angle so leaving and returning never jumps the sweep; progress is kept across exits, so a revolution can be completed in stages. RESTART re-locks every live lock (re-arming the live entity set, so SET_LOCKS-injected locks survive respawns). SET_LOCKS replaces the lock set at runtime for boards that import their locks. Renders nothing; boards draw the ring/chest and read swept from the shared entity (the render authority). Corresponds to the design-sheet field(s): challenge, rewards.","orbitals":[{"name":"LoopLockOrbital","id":"orb_4S5TQ1TMGHA88RKERM2ZYQDEX2","entity":{"name":"LoopLockData","id":"ent_9E4Y4E5DEKPQ9S87M4X2Q4536T","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"locks","type":"array","default":[],"items":{"type":"object","properties":{"lastAngle":{"name":"lastAngle","type":"number","required":false},"inside":{"name":"inside","type":"boolean","required":false},"x":{"name":"x","type":"number","required":true},"id":{"name":"id","type":"string","required":true},"radius":{"name":"radius","type":"number","required":true},"band":{"name":"band","type":"number","required":true},"reported":{"name":"reported","type":"boolean","required":false},"unlocked":{"name":"unlocked","type":"boolean","required":false},"turns":{"name":"turns","type":"number","required":true},"y":{"name":"y","type":"number","required":true},"swept":{"name":"swept","type":"number","required":false}}}}],"shared":true},"traits":[{"name":"LoopLock","id":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P","entityRebindable":true,"entityContract":{"requires":[],"provides":["locks"]},"effectRow":[{"kind":"emit","resource":"LOOP_UNLOCKED"},{"kind":"set","resource":"@entity.locks"}],"category":"lifecycle","linkedEntity":"LoopLockData","linkedEntityId":"ent_9E4Y4E5DEKPQ9S87M4X2Q4536T","entityRefIds":{"LoopLockData":"ent_9E4Y4E5DEKPQ9S87M4X2Q4536T"},"emits":[{"event":"LOOP_UNLOCKED","eventId":"evt_6CZ7NS30C7G63RK6Y2JEKFB0XC","description":"A lock's angular sweep reached turns × 2π and it flipped unlocked; boards layer treasure fx and rewards. When several locks open on one move, the first reports and the shared entity carries the rest.","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_X1ESNA72SKHCSKYCCRSCTF50WS","name":"Initialize"},{"key":"BODY_MOVED","id":"evt_9D8JTBSA7GN3R80SH9BTJY1PZ1","name":"Body Moved","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}],"listened":true},{"key":"SET_LOCKS","id":"evt_9PSJZEFSNPWTV4Z0S9H9XQSYYH","name":"Set Locks","payloadSchema":[{"name":"locks","type":"[object]","required":true,"properties":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"radius","type":"number","required":true},{"name":"band","type":"number","required":true},{"name":"turns","type":"number","required":true},{"name":"swept","type":"number"},{"name":"lastAngle","type":"number"},{"name":"inside","type":"boolean"},{"name":"unlocked","type":"boolean"},{"name":"reported","type":"boolean"}]}],"listened":true},{"key":"RESTART","id":"evt_62JGED1PTPVDBD0RGZJ4D5AKVT","name":"Restart","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"LOOP_UNLOCKED","id":"evt_6CZ7NS30C7G63RK6Y2JEKFB0XC","name":"Loop Unlocked","description":"A lock's angular sweep reached turns × 2π and it flipped unlocked; boards layer treasure fx and rewards. When several locks open on one move, the first reports and the shared entity carries the rest.","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_X1ESNA72SKHCSKYCCRSCTF50WS","effects":[["set","@entity.locks",["array/map","@config.locks",["fn","l",["object/merge","@l",{"swept":0,"lastAngle":0,"inside":false,"unlocked":false,"reported":false}]]]]]},{"from":"active","to":"active","event":"BODY_MOVED","eventId":"evt_9D8JTBSA7GN3R80SH9BTJY1PZ1","guard":"@config.running","effects":[["set","@entity.locks",["array/map","@entity.locks",["fn","l",["let",[["dx",["-","@payload.x",["object/get","@l","x"]]],["dy",["-","@payload.y",["object/get","@l","y"]]]],["let",[["dist",["math/hypot","@dx","@dy"]],["ang",["math/atan2","@dy","@dx"]]],["let",[["in",["<=",["math/abs",["-","@dist",["object/get","@l","radius"]]],["object/get","@l","band"]]]],["let",[["d",["if",["and","@in",["==",["object/get","@l","inside"],true]],["math/atan2",["math/sin",["-","@ang",["object/get","@l","lastAngle"]]],["math/cos",["-","@ang",["object/get","@l","lastAngle"]]]],0]]],["let",[["swept",["+",["object/get","@l","swept"],"@d"]]],["object/merge","@l",{"inside":"@in","lastAngle":["if","@in","@ang",["object/get","@l","lastAngle"]],"swept":"@swept","unlocked":["or",["object/get","@l","unlocked"],[">=",["math/abs","@swept"],["*",["object/get","@l","turns"],6.283185307179586]]]}]]]]]]]]],["let",[["newly",["array/filter","@entity.locks",["fn","l",["and",["==",["object/get","@l","unlocked"],true],["==",["object/get","@l","reported"],false]]]]]],["if",[">",["array/len","@newly"],0],["do",["set","@entity.locks",["array/map","@entity.locks",["fn","l",["if",["==",["object/get","@l","id"],["object/get",["array/first","@newly"],"id"]],["object/merge","@l",{"reported":true}],"@l"]]]],["emit","LOOP_UNLOCKED",{"id":["object/get",["array/first","@newly"],"id"],"x":["object/get",["array/first","@newly"],"x"],"y":["object/get",["array/first","@newly"],"y"]}]],null]]]},{"from":"active","to":"active","event":"SET_LOCKS","eventId":"evt_9PSJZEFSNPWTV4Z0S9H9XQSYYH","effects":[["set","@entity.locks",["array/map","@payload.locks",["fn","l",["object/merge","@l",{"swept":0,"lastAngle":0,"inside":false,"unlocked":false,"reported":false}]]]]]},{"from":"active","to":"active","event":"RESTART","eventId":"evt_62JGED1PTPVDBD0RGZJ4D5AKVT","effects":[["set","@entity.locks",["array/map","@entity.locks",["fn","l",["object/merge","@l",{"swept":0,"lastAngle":0,"inside":false,"unlocked":false,"reported":false}]]]]]}]},"config":{"locks":{"type":"[LoopLock]","default":[],"label":"Locks","description":"One row per winding lock: id, anchor (x, y in world units), ring radius, radial tolerance band, and revolutions required. swept/inside/unlocked are stamped at runtime. Seeded onto the entity on INIT; the live set is entity.locks — SET_LOCKS replaces it at runtime (boards that import locks), and RESTART re-arms the live set rather than re-reading config, so injected locks survive respawns.","tier":"domain","items":{"type":"object","properties":{"x":{"name":"x","type":"number","required":true},"turns":{"name":"turns","type":"number","required":true},"inside":{"name":"inside","type":"boolean","required":false},"reported":{"name":"reported","type":"boolean","required":false},"radius":{"name":"radius","type":"number","required":true},"band":{"name":"band","type":"number","required":true},"unlocked":{"name":"unlocked","type":"boolean","required":false},"swept":{"name":"swept","type":"number","required":false},"id":{"name":"id","type":"string","required":true},"y":{"name":"y","type":"number","required":true},"lastAngle":{"name":"lastAngle","type":"number","required":false}}}},"running":{"type":"boolean","default":true,"label":"Running","description":"When true, BODY_MOVED accumulates angular sweep and unlocks locks; toggle to freeze every lock as-is.","tier":"domain"}},"scope":"instance"}],"pages":[{"name":"LoopLockPage","id":"pag_Z0AWXBHGRCRC68E1B1W6PXD8AA","path":"/loop-lock","traits":[{"ref":"LoopLock","refId":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P"}]}],"types":{"LoopLock":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"radius","type":"number","required":true},{"name":"band","type":"number","required":true},{"name":"turns","type":"number","required":true},{"name":"swept","type":"number"},{"name":"lastAngle","type":"number"},{"name":"inside","type":"boolean"},{"name":"unlocked","type":"boolean"},{"name":"reported","type":"boolean"}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_9E4Y4E5DEKPQ9S87M4X2Q4536T":{"id":"ent_9E4Y4E5DEKPQ9S87M4X2Q4536T","kind":"entity","bakedName":"LoopLockData","curName":"LoopLockData","renames":[],"owner":"workspace"},"evt_62JGED1PTPVDBD0RGZJ4D5AKVT":{"id":"evt_62JGED1PTPVDBD0RGZJ4D5AKVT","kind":"event","bakedName":"RESTART","curName":"RESTART","renames":[],"owner":"workspace","parent":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P"},"evt_6CZ7NS30C7G63RK6Y2JEKFB0XC":{"id":"evt_6CZ7NS30C7G63RK6Y2JEKFB0XC","kind":"event","bakedName":"LOOP_UNLOCKED","curName":"LOOP_UNLOCKED","renames":[],"owner":"workspace","parent":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P"},"evt_9D8JTBSA7GN3R80SH9BTJY1PZ1":{"id":"evt_9D8JTBSA7GN3R80SH9BTJY1PZ1","kind":"event","bakedName":"BODY_MOVED","curName":"BODY_MOVED","renames":[],"owner":"workspace","parent":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P"},"evt_9PSJZEFSNPWTV4Z0S9H9XQSYYH":{"id":"evt_9PSJZEFSNPWTV4Z0S9H9XQSYYH","kind":"event","bakedName":"SET_LOCKS","curName":"SET_LOCKS","renames":[],"owner":"workspace","parent":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P"},"evt_X1ESNA72SKHCSKYCCRSCTF50WS":{"id":"evt_X1ESNA72SKHCSKYCCRSCTF50WS","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P"},"orb_4S5TQ1TMGHA88RKERM2ZYQDEX2":{"id":"orb_4S5TQ1TMGHA88RKERM2ZYQDEX2","kind":"orbital","bakedName":"LoopLockOrbital","curName":"LoopLockOrbital","renames":[],"owner":"workspace"},"pag_Z0AWXBHGRCRC68E1B1W6PXD8AA":{"id":"pag_Z0AWXBHGRCRC68E1B1W6PXD8AA","kind":"page","bakedName":"LoopLockPage","curName":"LoopLockPage","renames":[],"owner":"workspace"},"trt_M0C8NQGWN9EAMZZD0MMV19QP4P":{"id":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P","kind":"trait","bakedName":"LoopLock","curName":"LoopLock","renames":[],"owner":"workspace"}}}}
|
|
1
|
+
{"name":"std-loop-lock","version":"1.0.0","description":"Headless winding-lock mechanic: locks that open only after the player travels a full revolution around their anchor. Listens BODY_MOVED and, while the player stays within a radial band of a lock's ring, accumulates the wrapped angular delta of their position into swept (radians, signed — either direction counts); when |swept| reaches turns × 2π the lock flips unlocked and emits LOOP_UNLOCKED once. Entering the band reseeds the angle so leaving and returning never jumps the sweep; progress is kept across exits, so a revolution can be completed in stages. RESTART re-locks every live lock (re-arming the live entity set, so SET_LOCKS-injected locks survive respawns). SET_LOCKS replaces the lock set at runtime for boards that import their locks. Renders nothing; boards draw the ring/chest and read swept from the shared entity (the render authority). Corresponds to the design-sheet field(s): challenge, rewards.","orbitals":[{"name":"LoopLockOrbital","id":"orb_4S5TQ1TMGHA88RKERM2ZYQDEX2","entity":{"name":"LoopLockData","id":"ent_9E4Y4E5DEKPQ9S87M4X2Q4536T","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"locks","type":"array","default":[],"items":{"type":"object","properties":{"lastAngle":{"name":"lastAngle","type":"number","required":false},"id":{"name":"id","type":"string","required":true},"x":{"name":"x","type":"number","required":true},"inside":{"name":"inside","type":"boolean","required":false},"unlocked":{"name":"unlocked","type":"boolean","required":false},"swept":{"name":"swept","type":"number","required":false},"turns":{"name":"turns","type":"number","required":true},"reported":{"name":"reported","type":"boolean","required":false},"y":{"name":"y","type":"number","required":true},"radius":{"name":"radius","type":"number","required":true},"band":{"name":"band","type":"number","required":true}}}}],"shared":true},"traits":[{"name":"LoopLock","id":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P","entityRebindable":true,"entityContract":{"requires":[],"provides":["locks"]},"effectRow":[{"kind":"emit","resource":"LOOP_UNLOCKED"},{"kind":"set","resource":"@entity.locks"}],"category":"lifecycle","linkedEntity":"LoopLockData","linkedEntityId":"ent_9E4Y4E5DEKPQ9S87M4X2Q4536T","entityRefIds":{"LoopLockData":"ent_9E4Y4E5DEKPQ9S87M4X2Q4536T"},"emits":[{"event":"LOOP_UNLOCKED","eventId":"evt_6CZ7NS30C7G63RK6Y2JEKFB0XC","description":"A lock's angular sweep reached turns × 2π and it flipped unlocked; boards layer treasure fx and rewards. When several locks open on one move, the first reports and the shared entity carries the rest.","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_X1ESNA72SKHCSKYCCRSCTF50WS","name":"Initialize"},{"key":"BODY_MOVED","id":"evt_9D8JTBSA7GN3R80SH9BTJY1PZ1","name":"Body Moved","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}],"listened":true},{"key":"SET_LOCKS","id":"evt_9PSJZEFSNPWTV4Z0S9H9XQSYYH","name":"Set Locks","payloadSchema":[{"name":"locks","type":"[object]","required":true,"properties":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"radius","type":"number","required":true},{"name":"band","type":"number","required":true},{"name":"turns","type":"number","required":true},{"name":"swept","type":"number"},{"name":"lastAngle","type":"number"},{"name":"inside","type":"boolean"},{"name":"unlocked","type":"boolean"},{"name":"reported","type":"boolean"}]}],"listened":true},{"key":"RESTART","id":"evt_62JGED1PTPVDBD0RGZJ4D5AKVT","name":"Restart","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"LOOP_UNLOCKED","id":"evt_6CZ7NS30C7G63RK6Y2JEKFB0XC","name":"Loop Unlocked","description":"A lock's angular sweep reached turns × 2π and it flipped unlocked; boards layer treasure fx and rewards. When several locks open on one move, the first reports and the shared entity carries the rest.","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}]}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_X1ESNA72SKHCSKYCCRSCTF50WS","effects":[["set","@entity.locks",["array/map","@config.locks",["fn","l",["object/merge","@l",{"swept":0,"lastAngle":0,"inside":false,"unlocked":false,"reported":false}]]]]]},{"from":"active","to":"active","event":"BODY_MOVED","eventId":"evt_9D8JTBSA7GN3R80SH9BTJY1PZ1","guard":"@config.running","effects":[["set","@entity.locks",["array/map","@entity.locks",["fn","l",["let",[["dx",["-","@payload.x",["object/get","@l","x"]]],["dy",["-","@payload.y",["object/get","@l","y"]]]],["let",[["dist",["math/hypot","@dx","@dy"]],["ang",["math/atan2","@dy","@dx"]]],["let",[["in",["<=",["math/abs",["-","@dist",["object/get","@l","radius"]]],["object/get","@l","band"]]]],["let",[["d",["if",["and","@in",["==",["object/get","@l","inside"],true]],["math/atan2",["math/sin",["-","@ang",["object/get","@l","lastAngle"]]],["math/cos",["-","@ang",["object/get","@l","lastAngle"]]]],0]]],["let",[["swept",["+",["object/get","@l","swept"],"@d"]]],["object/merge","@l",{"inside":"@in","lastAngle":["if","@in","@ang",["object/get","@l","lastAngle"]],"swept":"@swept","unlocked":["or",["object/get","@l","unlocked"],[">=",["math/abs","@swept"],["*",["object/get","@l","turns"],6.283185307179586]]]}]]]]]]]]],["let",[["newly",["array/filter","@entity.locks",["fn","l",["and",["==",["object/get","@l","unlocked"],true],["==",["object/get","@l","reported"],false]]]]]],["if",[">",["array/len","@newly"],0],["do",["set","@entity.locks",["array/map","@entity.locks",["fn","l",["if",["==",["object/get","@l","id"],["object/get",["array/first","@newly"],"id"]],["object/merge","@l",{"reported":true}],"@l"]]]],["emit","LOOP_UNLOCKED",{"id":["object/get",["array/first","@newly"],"id"],"x":["object/get",["array/first","@newly"],"x"],"y":["object/get",["array/first","@newly"],"y"]}]],null]]]},{"from":"active","to":"active","event":"SET_LOCKS","eventId":"evt_9PSJZEFSNPWTV4Z0S9H9XQSYYH","effects":[["set","@entity.locks",["array/map","@payload.locks",["fn","l",["object/merge","@l",{"swept":0,"lastAngle":0,"inside":false,"unlocked":false,"reported":false}]]]]]},{"from":"active","to":"active","event":"RESTART","eventId":"evt_62JGED1PTPVDBD0RGZJ4D5AKVT","effects":[["set","@entity.locks",["array/map","@entity.locks",["fn","l",["object/merge","@l",{"swept":0,"lastAngle":0,"inside":false,"unlocked":false,"reported":false}]]]]]}]},"config":{"running":{"type":"boolean","default":true,"label":"Running","description":"When true, BODY_MOVED accumulates angular sweep and unlocks locks; toggle to freeze every lock as-is.","tier":"domain"},"locks":{"type":"[LoopLock]","default":[],"label":"Locks","description":"One row per winding lock: id, anchor (x, y in world units), ring radius, radial tolerance band, and revolutions required. swept/inside/unlocked are stamped at runtime. Seeded onto the entity on INIT; the live set is entity.locks — SET_LOCKS replaces it at runtime (boards that import locks), and RESTART re-arms the live set rather than re-reading config, so injected locks survive respawns.","tier":"domain","items":{"type":"object","properties":{"y":{"name":"y","type":"number","required":true},"swept":{"name":"swept","type":"number","required":false},"band":{"name":"band","type":"number","required":true},"unlocked":{"name":"unlocked","type":"boolean","required":false},"id":{"name":"id","type":"string","required":true},"lastAngle":{"name":"lastAngle","type":"number","required":false},"radius":{"name":"radius","type":"number","required":true},"x":{"name":"x","type":"number","required":true},"turns":{"name":"turns","type":"number","required":true},"reported":{"name":"reported","type":"boolean","required":false},"inside":{"name":"inside","type":"boolean","required":false}}}}},"scope":"instance"}],"pages":[{"name":"LoopLockPage","id":"pag_Z0AWXBHGRCRC68E1B1W6PXD8AA","path":"/loop-lock","traits":[{"ref":"LoopLock","refId":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P"}]}],"types":{"LoopLock":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"radius","type":"number","required":true},{"name":"band","type":"number","required":true},{"name":"turns","type":"number","required":true},{"name":"swept","type":"number"},{"name":"lastAngle","type":"number"},{"name":"inside","type":"boolean"},{"name":"unlocked","type":"boolean"},{"name":"reported","type":"boolean"}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_9E4Y4E5DEKPQ9S87M4X2Q4536T":{"id":"ent_9E4Y4E5DEKPQ9S87M4X2Q4536T","kind":"entity","bakedName":"LoopLockData","curName":"LoopLockData","renames":[],"owner":"workspace"},"evt_62JGED1PTPVDBD0RGZJ4D5AKVT":{"id":"evt_62JGED1PTPVDBD0RGZJ4D5AKVT","kind":"event","bakedName":"RESTART","curName":"RESTART","renames":[],"owner":"workspace","parent":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P"},"evt_6CZ7NS30C7G63RK6Y2JEKFB0XC":{"id":"evt_6CZ7NS30C7G63RK6Y2JEKFB0XC","kind":"event","bakedName":"LOOP_UNLOCKED","curName":"LOOP_UNLOCKED","renames":[],"owner":"workspace","parent":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P"},"evt_9D8JTBSA7GN3R80SH9BTJY1PZ1":{"id":"evt_9D8JTBSA7GN3R80SH9BTJY1PZ1","kind":"event","bakedName":"BODY_MOVED","curName":"BODY_MOVED","renames":[],"owner":"workspace","parent":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P"},"evt_9PSJZEFSNPWTV4Z0S9H9XQSYYH":{"id":"evt_9PSJZEFSNPWTV4Z0S9H9XQSYYH","kind":"event","bakedName":"SET_LOCKS","curName":"SET_LOCKS","renames":[],"owner":"workspace","parent":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P"},"evt_X1ESNA72SKHCSKYCCRSCTF50WS":{"id":"evt_X1ESNA72SKHCSKYCCRSCTF50WS","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P"},"orb_4S5TQ1TMGHA88RKERM2ZYQDEX2":{"id":"orb_4S5TQ1TMGHA88RKERM2ZYQDEX2","kind":"orbital","bakedName":"LoopLockOrbital","curName":"LoopLockOrbital","renames":[],"owner":"workspace"},"pag_Z0AWXBHGRCRC68E1B1W6PXD8AA":{"id":"pag_Z0AWXBHGRCRC68E1B1W6PXD8AA","kind":"page","bakedName":"LoopLockPage","curName":"LoopLockPage","renames":[],"owner":"workspace"},"trt_M0C8NQGWN9EAMZZD0MMV19QP4P":{"id":"trt_M0C8NQGWN9EAMZZD0MMV19QP4P","kind":"trait","bakedName":"LoopLock","curName":"LoopLock","renames":[],"owner":"workspace"}}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"std-motion-body","version":"1.1.0","description":"Headless continuous-motion authority: the SOLE writer of bodies + gravity + bias on physics boards. Every 50ms motion tick it integrates each body — thrust acceleration plus the board-wide bias field (biasAx/biasAy — the hill-force / wind / conveyor-belt channel, written only through the SET_BIAS intent) plus gravity feed velocity, damping bleeds it, maxSpeed caps it, velocity steps position, and the world walls clamp it (a clamped axis kills that axis's velocity). Intents: THRUST sets a body's acceleration (hold-to-push input: keydown pushes, keyup zeroes), IMPULSE kicks velocity instantly (jumps, d-pad nudges), PLACE teleports (spawns, curve-riding pins), SET_GRAVITY retunes the pull live, SET_BIAS steers the bias field, RESTART reseeds. Emits BODY_MOVED for the lead body (bodies[0]) every tick so boards that subscribe can react — boards that don't subscribe pay nothing. Renders nothing.","orbitals":[{"name":"MotionBodyOrbital","id":"orb_VXMWKKSYQYZBZ5R069HQAZ2FN1","entity":{"name":"MotionBodyData","id":"ent_NZ5GCJXT7GX3R023XETJ6NMJP3","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"bodies","type":"array","items":{"type":"object","properties":{"vx":{"name":"vx","type":"number","required":false},"vy":{"name":"vy","type":"number","required":false},"ay":{"name":"ay","type":"number","required":false},"id":{"name":"id","type":"string","required":true},"y":{"name":"y","type":"number","required":true},"x":{"name":"x","type":"number","required":true},"ax":{"name":"ax","type":"number","required":false}}}},{"name":"gravity","type":"number","default":0},{"name":"biasAx","type":"number","default":0},{"name":"biasAy","type":"number","default":0}],"shared":true},"traits":[{"name":"MotionBody","id":"trt_DY37T51ACZN6FJHHWJWR76GZEX","entityRebindable":true,"entityContract":{"requires":[],"provides":["biasAx","biasAy","bodies","gravity"]},"effectRow":[{"kind":"emit","resource":"BODY_MOVED","site":"tick"},{"kind":"set","resource":"@entity.biasAx"},{"kind":"set","resource":"@entity.biasAy"},{"kind":"set","resource":"@entity.bodies"},{"kind":"set","resource":"@entity.bodies","site":"tick"},{"kind":"set","resource":"@entity.gravity"},{"kind":"ticks","site":"tick"}],"category":"lifecycle","linkedEntity":"MotionBodyData","linkedEntityId":"ent_NZ5GCJXT7GX3R023XETJ6NMJP3","entityRefIds":{"MotionBodyData":"ent_NZ5GCJXT7GX3R023XETJ6NMJP3"},"emits":[{"event":"BODY_MOVED","eventId":"evt_01NFV8MG41820RK40XC6GDJTJB","description":"Lead body (bodies[0]) after this motion tick: position, velocity, and scalar speed; boards render it, objective mechanics score it, game rules adapt from it","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true},{"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":"speed","type":"number","required":true}]}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_ZYK249QM6GT389ZFM6W6KMPBP3","name":"Initialize"},{"key":"THRUST","id":"evt_H5SC8DRQJ9BS4S6YA3Y3FG723B","name":"Thrust","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"ax","type":"number","required":true},{"name":"ay","type":"number","required":true}],"listened":true},{"key":"IMPULSE","id":"evt_JMCK7QJRCQC6BQY4Z8C1BYYB1S","name":"Impulse","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"dvx","type":"number","required":true},{"name":"dvy","type":"number","required":true}],"listened":true},{"key":"PLACE","id":"evt_KWJEDYAJFD97PG82EP2TG7VES0","name":"Place","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}],"listened":true},{"key":"SET_GRAVITY","id":"evt_47YNT0BQ32VHH80MH9MJS85XQE","name":"Set Gravity","payloadSchema":[{"name":"gravity","type":"number","required":true}],"listened":true},{"key":"SET_BIAS","id":"evt_Y38V23BV12XGHB2RZYBYG86Q4W","name":"Set Bias","payloadSchema":[{"name":"biasAx","type":"number","required":true},{"name":"biasAy","type":"number","required":true}],"listened":true},{"key":"RESTART","id":"evt_ZC6K3WG5QZ2VZY7KHSPTWW8HFW","name":"Restart","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"BODY_MOVED","id":"evt_01NFV8MG41820RK40XC6GDJTJB","name":"Body Moved","description":"Lead body (bodies[0]) after this motion tick: position, velocity, and scalar speed; boards render it, objective mechanics score it, game rules adapt from it","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"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":"speed","type":"number","required":true}]}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_ZYK249QM6GT389ZFM6W6KMPBP3","effects":[["set","@entity.bodies","@config.bodies"],["set","@entity.gravity","@config.gravity"]]},{"from":"active","to":"active","event":"THRUST","eventId":"evt_H5SC8DRQJ9BS4S6YA3Y3FG723B","effects":[["set","@entity.bodies",["array/map","@entity.bodies",["fn","b",["if",["==","@b.id","@payload.id"],["object/merge","@b",{"ax":"@payload.ax","ay":"@payload.ay"}],"@b"]]]]]},{"from":"active","to":"active","event":"IMPULSE","eventId":"evt_JMCK7QJRCQC6BQY4Z8C1BYYB1S","effects":[["set","@entity.bodies",["array/map","@entity.bodies",["fn","b",["if",["==","@b.id","@payload.id"],["object/merge","@b",{"vx":["+",["object/get","@b","vx"],"@payload.dvx"],"vy":["+",["object/get","@b","vy"],"@payload.dvy"]}],"@b"]]]]]},{"from":"active","to":"active","event":"PLACE","eventId":"evt_KWJEDYAJFD97PG82EP2TG7VES0","effects":[["set","@entity.bodies",["array/map","@entity.bodies",["fn","b",["if",["==","@b.id","@payload.id"],["object/merge","@b",{"x":"@payload.x","y":"@payload.y"}],"@b"]]]]]},{"from":"active","to":"active","event":"SET_GRAVITY","eventId":"evt_47YNT0BQ32VHH80MH9MJS85XQE","effects":[["set","@entity.gravity","@payload.gravity"]]},{"from":"active","to":"active","event":"SET_BIAS","eventId":"evt_Y38V23BV12XGHB2RZYBYG86Q4W","effects":[["set","@entity.biasAx","@payload.biasAx"],["set","@entity.biasAy","@payload.biasAy"]]},{"from":"active","to":"active","event":"RESTART","eventId":"evt_ZC6K3WG5QZ2VZY7KHSPTWW8HFW","effects":[["set","@entity.bodies","@config.bodies"],["set","@entity.gravity","@config.gravity"]]}]},"ticks":[{"name":"motionTick","interval":50,"guard":["and","@config.running",[">",["array/len","@entity.bodies"],0]],"effects":[["do",["set","@entity.bodies",["array/map","@entity.bodies",["fn","b",["let",[["nvx",["math/clamp",["*",["+",["object/get","@b","vx"],["*",["+",["object/get","@b","ax"],"@entity.biasAx"],0.05]],"@config.damping"],["-",0,"@config.maxSpeed"],"@config.maxSpeed"]]],["let",[["nvy",["math/clamp",["*",["+",["object/get","@b","vy"],["*",["+",["+",["object/get","@b","ay"],"@entity.biasAy"],"@entity.gravity"],0.05]],"@config.damping"],["-",0,"@config.maxSpeed"],"@config.maxSpeed"]]],["let",[["nx",["math/clamp",["+",["object/get","@b","x"],["*","@nvx",0.05]],"@config.xMin","@config.xMax"]]],["let",[["ny",["math/clamp",["+",["object/get","@b","y"],["*","@nvy",0.05]],"@config.yMin","@config.yMax"]]],["object/merge","@b",{"x":"@nx","y":"@ny","vx":["if",["or",["==","@nx","@config.xMin"],["==","@nx","@config.xMax"]],0,"@nvx"],"vy":["if",["or",["==","@ny","@config.yMin"],["==","@ny","@config.yMax"]],0,"@nvy"]}]]]]]]]],["emit","BODY_MOVED",{"id":["object/get",["array/first","@entity.bodies"],"id"],"x":["object/get",["array/first","@entity.bodies"],"x"],"y":["object/get",["array/first","@entity.bodies"],"y"],"vx":["object/get",["array/first","@entity.bodies"],"vx"],"vy":["object/get",["array/first","@entity.bodies"],"vy"],"speed":["math/hypot",["object/get",["array/first","@entity.bodies"],"vx"],["object/get",["array/first","@entity.bodies"],"vy"]]}]]]}],"config":{"gravity":{"type":"number","default":0,"label":"Gravity","description":"Constant acceleration added to every body's vertical velocity each tick (positive pulls toward +y); seeded onto the entity so SET_GRAVITY can retune it live","tier":"domain"},"bodies":{"type":"[Body]","default":[],"label":"Initial Bodies","description":"Seed roster — bodies[0] is the lead body reported by BODY_MOVED","tier":"domain","items":{"type":"object","properties":{"y":{"name":"y","type":"number","required":true},"x":{"name":"x","type":"number","required":true},"ay":{"name":"ay","type":"number","required":false},"vy":{"name":"vy","type":"number","required":false},"id":{"name":"id","type":"string","required":true},"vx":{"name":"vx","type":"number","required":false},"ax":{"name":"ax","type":"number","required":false}}}},"yMax":{"type":"number","default":1000000,"label":"Ceiling","description":"Largest y a body may hold; hitting it zeroes vy","tier":"presentation"},"maxSpeed":{"type":"number","default":8,"label":"Max Speed","description":"Per-axis speed cap in world units per second","tier":"presentation"},"running":{"type":"boolean","default":true,"label":"Running","description":"When true the 50ms motion tick integrates; toggle to freeze all bodies","tier":"domain"},"damping":{"type":"number","default":0.98,"label":"Damping","description":"Velocity retained each 50ms tick (1 = frictionless coast, 0.9 = quick stop); the ice-to-mud feel knob","tier":"presentation"},"yMin":{"type":"number","default":-1000000,"label":"Floor","description":"Smallest y a body may hold; hitting it zeroes vy","tier":"presentation"},"xMax":{"type":"number","default":1000000,"label":"Right Wall","description":"Largest x a body may hold; hitting it zeroes vx","tier":"presentation"},"xMin":{"type":"number","default":-1000000,"label":"Left Wall","description":"Smallest x a body may hold; hitting it zeroes vx","tier":"presentation"}},"scope":"instance"}],"pages":[{"name":"MotionBodyPage","id":"pag_WP178EJE7073G9TRZ81PZCCWC4","path":"/motion-body","traits":[{"ref":"MotionBody","refId":"trt_DY37T51ACZN6FJHHWJWR76GZEX"}]}],"types":{"Body":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"vx","type":"number"},{"name":"vy","type":"number"},{"name":"ax","type":"number"},{"name":"ay","type":"number"}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_NZ5GCJXT7GX3R023XETJ6NMJP3":{"id":"ent_NZ5GCJXT7GX3R023XETJ6NMJP3","kind":"entity","bakedName":"MotionBodyData","curName":"MotionBodyData","renames":[],"owner":"workspace"},"evt_01NFV8MG41820RK40XC6GDJTJB":{"id":"evt_01NFV8MG41820RK40XC6GDJTJB","kind":"event","bakedName":"BODY_MOVED","curName":"BODY_MOVED","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_47YNT0BQ32VHH80MH9MJS85XQE":{"id":"evt_47YNT0BQ32VHH80MH9MJS85XQE","kind":"event","bakedName":"SET_GRAVITY","curName":"SET_GRAVITY","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_H5SC8DRQJ9BS4S6YA3Y3FG723B":{"id":"evt_H5SC8DRQJ9BS4S6YA3Y3FG723B","kind":"event","bakedName":"THRUST","curName":"THRUST","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_JMCK7QJRCQC6BQY4Z8C1BYYB1S":{"id":"evt_JMCK7QJRCQC6BQY4Z8C1BYYB1S","kind":"event","bakedName":"IMPULSE","curName":"IMPULSE","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_KWJEDYAJFD97PG82EP2TG7VES0":{"id":"evt_KWJEDYAJFD97PG82EP2TG7VES0","kind":"event","bakedName":"PLACE","curName":"PLACE","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_Y38V23BV12XGHB2RZYBYG86Q4W":{"id":"evt_Y38V23BV12XGHB2RZYBYG86Q4W","kind":"event","bakedName":"SET_BIAS","curName":"SET_BIAS","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_ZC6K3WG5QZ2VZY7KHSPTWW8HFW":{"id":"evt_ZC6K3WG5QZ2VZY7KHSPTWW8HFW","kind":"event","bakedName":"RESTART","curName":"RESTART","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_ZYK249QM6GT389ZFM6W6KMPBP3":{"id":"evt_ZYK249QM6GT389ZFM6W6KMPBP3","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"orb_VXMWKKSYQYZBZ5R069HQAZ2FN1":{"id":"orb_VXMWKKSYQYZBZ5R069HQAZ2FN1","kind":"orbital","bakedName":"MotionBodyOrbital","curName":"MotionBodyOrbital","renames":[],"owner":"workspace"},"pag_WP178EJE7073G9TRZ81PZCCWC4":{"id":"pag_WP178EJE7073G9TRZ81PZCCWC4","kind":"page","bakedName":"MotionBodyPage","curName":"MotionBodyPage","renames":[],"owner":"workspace"},"trt_DY37T51ACZN6FJHHWJWR76GZEX":{"id":"trt_DY37T51ACZN6FJHHWJWR76GZEX","kind":"trait","bakedName":"MotionBody","curName":"MotionBody","renames":[],"owner":"workspace"}}}}
|
|
1
|
+
{"name":"std-motion-body","version":"1.1.0","description":"Headless continuous-motion authority: the SOLE writer of bodies + gravity + bias on physics boards. Every 50ms motion tick it integrates each body — thrust acceleration plus the board-wide bias field (biasAx/biasAy — the hill-force / wind / conveyor-belt channel, written only through the SET_BIAS intent) plus gravity feed velocity, damping bleeds it, maxSpeed caps it, velocity steps position, and the world walls clamp it (a clamped axis kills that axis's velocity). Intents: THRUST sets a body's acceleration (hold-to-push input: keydown pushes, keyup zeroes), IMPULSE kicks velocity instantly (jumps, d-pad nudges), PLACE teleports (spawns, curve-riding pins), SET_GRAVITY retunes the pull live, SET_BIAS steers the bias field, RESTART reseeds. Emits BODY_MOVED for the lead body (bodies[0]) every tick so boards that subscribe can react — boards that don't subscribe pay nothing. Renders nothing.","orbitals":[{"name":"MotionBodyOrbital","id":"orb_VXMWKKSYQYZBZ5R069HQAZ2FN1","entity":{"name":"MotionBodyData","id":"ent_NZ5GCJXT7GX3R023XETJ6NMJP3","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"bodies","type":"array","items":{"type":"object","properties":{"ax":{"name":"ax","type":"number","required":false},"id":{"name":"id","type":"string","required":true},"ay":{"name":"ay","type":"number","required":false},"vx":{"name":"vx","type":"number","required":false},"y":{"name":"y","type":"number","required":true},"x":{"name":"x","type":"number","required":true},"vy":{"name":"vy","type":"number","required":false}}}},{"name":"gravity","type":"number","default":0},{"name":"biasAx","type":"number","default":0},{"name":"biasAy","type":"number","default":0}],"shared":true},"traits":[{"name":"MotionBody","id":"trt_DY37T51ACZN6FJHHWJWR76GZEX","entityRebindable":true,"entityContract":{"requires":[],"provides":["biasAx","biasAy","bodies","gravity"]},"effectRow":[{"kind":"emit","resource":"BODY_MOVED","site":"tick"},{"kind":"set","resource":"@entity.biasAx"},{"kind":"set","resource":"@entity.biasAy"},{"kind":"set","resource":"@entity.bodies"},{"kind":"set","resource":"@entity.bodies","site":"tick"},{"kind":"set","resource":"@entity.gravity"},{"kind":"ticks","site":"tick"}],"category":"lifecycle","linkedEntity":"MotionBodyData","linkedEntityId":"ent_NZ5GCJXT7GX3R023XETJ6NMJP3","entityRefIds":{"MotionBodyData":"ent_NZ5GCJXT7GX3R023XETJ6NMJP3"},"emits":[{"event":"BODY_MOVED","eventId":"evt_01NFV8MG41820RK40XC6GDJTJB","description":"Lead body (bodies[0]) after this motion tick: position, velocity, and scalar speed; boards render it, objective mechanics score it, game rules adapt from it","tier":"domain","scope":"external","payloadSchema":[{"name":"id","type":"string","required":true},{"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":"speed","type":"number","required":true}]}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_ZYK249QM6GT389ZFM6W6KMPBP3","name":"Initialize"},{"key":"THRUST","id":"evt_H5SC8DRQJ9BS4S6YA3Y3FG723B","name":"Thrust","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"ax","type":"number","required":true},{"name":"ay","type":"number","required":true}],"listened":true},{"key":"IMPULSE","id":"evt_JMCK7QJRCQC6BQY4Z8C1BYYB1S","name":"Impulse","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"dvx","type":"number","required":true},{"name":"dvy","type":"number","required":true}],"listened":true},{"key":"PLACE","id":"evt_KWJEDYAJFD97PG82EP2TG7VES0","name":"Place","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true}],"listened":true},{"key":"SET_GRAVITY","id":"evt_47YNT0BQ32VHH80MH9MJS85XQE","name":"Set Gravity","payloadSchema":[{"name":"gravity","type":"number","required":true}],"listened":true},{"key":"SET_BIAS","id":"evt_Y38V23BV12XGHB2RZYBYG86Q4W","name":"Set Bias","payloadSchema":[{"name":"biasAx","type":"number","required":true},{"name":"biasAy","type":"number","required":true}],"listened":true},{"key":"RESTART","id":"evt_ZC6K3WG5QZ2VZY7KHSPTWW8HFW","name":"Restart","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"BODY_MOVED","id":"evt_01NFV8MG41820RK40XC6GDJTJB","name":"Body Moved","description":"Lead body (bodies[0]) after this motion tick: position, velocity, and scalar speed; boards render it, objective mechanics score it, game rules adapt from it","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"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":"speed","type":"number","required":true}]}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_ZYK249QM6GT389ZFM6W6KMPBP3","effects":[["set","@entity.bodies","@config.bodies"],["set","@entity.gravity","@config.gravity"]]},{"from":"active","to":"active","event":"THRUST","eventId":"evt_H5SC8DRQJ9BS4S6YA3Y3FG723B","effects":[["set","@entity.bodies",["array/map","@entity.bodies",["fn","b",["if",["==","@b.id","@payload.id"],["object/merge","@b",{"ax":"@payload.ax","ay":"@payload.ay"}],"@b"]]]]]},{"from":"active","to":"active","event":"IMPULSE","eventId":"evt_JMCK7QJRCQC6BQY4Z8C1BYYB1S","effects":[["set","@entity.bodies",["array/map","@entity.bodies",["fn","b",["if",["==","@b.id","@payload.id"],["object/merge","@b",{"vx":["+",["object/get","@b","vx"],"@payload.dvx"],"vy":["+",["object/get","@b","vy"],"@payload.dvy"]}],"@b"]]]]]},{"from":"active","to":"active","event":"PLACE","eventId":"evt_KWJEDYAJFD97PG82EP2TG7VES0","effects":[["set","@entity.bodies",["array/map","@entity.bodies",["fn","b",["if",["==","@b.id","@payload.id"],["object/merge","@b",{"x":"@payload.x","y":"@payload.y"}],"@b"]]]]]},{"from":"active","to":"active","event":"SET_GRAVITY","eventId":"evt_47YNT0BQ32VHH80MH9MJS85XQE","effects":[["set","@entity.gravity","@payload.gravity"]]},{"from":"active","to":"active","event":"SET_BIAS","eventId":"evt_Y38V23BV12XGHB2RZYBYG86Q4W","effects":[["set","@entity.biasAx","@payload.biasAx"],["set","@entity.biasAy","@payload.biasAy"]]},{"from":"active","to":"active","event":"RESTART","eventId":"evt_ZC6K3WG5QZ2VZY7KHSPTWW8HFW","effects":[["set","@entity.bodies","@config.bodies"],["set","@entity.gravity","@config.gravity"]]}]},"ticks":[{"name":"motionTick","interval":50,"guard":["and","@config.running",[">",["array/len","@entity.bodies"],0]],"effects":[["do",["set","@entity.bodies",["array/map","@entity.bodies",["fn","b",["let",[["nvx",["math/clamp",["*",["+",["object/get","@b","vx"],["*",["+",["object/get","@b","ax"],"@entity.biasAx"],0.05]],"@config.damping"],["-",0,"@config.maxSpeed"],"@config.maxSpeed"]]],["let",[["nvy",["math/clamp",["*",["+",["object/get","@b","vy"],["*",["+",["+",["object/get","@b","ay"],"@entity.biasAy"],"@entity.gravity"],0.05]],"@config.damping"],["-",0,"@config.maxSpeed"],"@config.maxSpeed"]]],["let",[["nx",["math/clamp",["+",["object/get","@b","x"],["*","@nvx",0.05]],"@config.xMin","@config.xMax"]]],["let",[["ny",["math/clamp",["+",["object/get","@b","y"],["*","@nvy",0.05]],"@config.yMin","@config.yMax"]]],["object/merge","@b",{"x":"@nx","y":"@ny","vx":["if",["or",["==","@nx","@config.xMin"],["==","@nx","@config.xMax"]],0,"@nvx"],"vy":["if",["or",["==","@ny","@config.yMin"],["==","@ny","@config.yMax"]],0,"@nvy"]}]]]]]]]],["emit","BODY_MOVED",{"id":["object/get",["array/first","@entity.bodies"],"id"],"x":["object/get",["array/first","@entity.bodies"],"x"],"y":["object/get",["array/first","@entity.bodies"],"y"],"vx":["object/get",["array/first","@entity.bodies"],"vx"],"vy":["object/get",["array/first","@entity.bodies"],"vy"],"speed":["math/hypot",["object/get",["array/first","@entity.bodies"],"vx"],["object/get",["array/first","@entity.bodies"],"vy"]]}]]]}],"config":{"gravity":{"type":"number","default":0,"label":"Gravity","description":"Constant acceleration added to every body's vertical velocity each tick (positive pulls toward +y); seeded onto the entity so SET_GRAVITY can retune it live","tier":"domain"},"damping":{"type":"number","default":0.98,"label":"Damping","description":"Velocity retained each 50ms tick (1 = frictionless coast, 0.9 = quick stop); the ice-to-mud feel knob","tier":"presentation"},"bodies":{"type":"[Body]","default":[],"label":"Initial Bodies","description":"Seed roster — bodies[0] is the lead body reported by BODY_MOVED","tier":"domain","items":{"type":"object","properties":{"vy":{"name":"vy","type":"number","required":false},"vx":{"name":"vx","type":"number","required":false},"id":{"name":"id","type":"string","required":true},"ax":{"name":"ax","type":"number","required":false},"y":{"name":"y","type":"number","required":true},"ay":{"name":"ay","type":"number","required":false},"x":{"name":"x","type":"number","required":true}}}},"maxSpeed":{"type":"number","default":8,"label":"Max Speed","description":"Per-axis speed cap in world units per second","tier":"presentation"},"yMin":{"type":"number","default":-1000000,"label":"Floor","description":"Smallest y a body may hold; hitting it zeroes vy","tier":"presentation"},"xMax":{"type":"number","default":1000000,"label":"Right Wall","description":"Largest x a body may hold; hitting it zeroes vx","tier":"presentation"},"running":{"type":"boolean","default":true,"label":"Running","description":"When true the 50ms motion tick integrates; toggle to freeze all bodies","tier":"domain"},"yMax":{"type":"number","default":1000000,"label":"Ceiling","description":"Largest y a body may hold; hitting it zeroes vy","tier":"presentation"},"xMin":{"type":"number","default":-1000000,"label":"Left Wall","description":"Smallest x a body may hold; hitting it zeroes vx","tier":"presentation"}},"scope":"instance"}],"pages":[{"name":"MotionBodyPage","id":"pag_WP178EJE7073G9TRZ81PZCCWC4","path":"/motion-body","traits":[{"ref":"MotionBody","refId":"trt_DY37T51ACZN6FJHHWJWR76GZEX"}]}],"types":{"Body":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"vx","type":"number"},{"name":"vy","type":"number"},{"name":"ax","type":"number"},{"name":"ay","type":"number"}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_NZ5GCJXT7GX3R023XETJ6NMJP3":{"id":"ent_NZ5GCJXT7GX3R023XETJ6NMJP3","kind":"entity","bakedName":"MotionBodyData","curName":"MotionBodyData","renames":[],"owner":"workspace"},"evt_01NFV8MG41820RK40XC6GDJTJB":{"id":"evt_01NFV8MG41820RK40XC6GDJTJB","kind":"event","bakedName":"BODY_MOVED","curName":"BODY_MOVED","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_47YNT0BQ32VHH80MH9MJS85XQE":{"id":"evt_47YNT0BQ32VHH80MH9MJS85XQE","kind":"event","bakedName":"SET_GRAVITY","curName":"SET_GRAVITY","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_H5SC8DRQJ9BS4S6YA3Y3FG723B":{"id":"evt_H5SC8DRQJ9BS4S6YA3Y3FG723B","kind":"event","bakedName":"THRUST","curName":"THRUST","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_JMCK7QJRCQC6BQY4Z8C1BYYB1S":{"id":"evt_JMCK7QJRCQC6BQY4Z8C1BYYB1S","kind":"event","bakedName":"IMPULSE","curName":"IMPULSE","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_KWJEDYAJFD97PG82EP2TG7VES0":{"id":"evt_KWJEDYAJFD97PG82EP2TG7VES0","kind":"event","bakedName":"PLACE","curName":"PLACE","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_Y38V23BV12XGHB2RZYBYG86Q4W":{"id":"evt_Y38V23BV12XGHB2RZYBYG86Q4W","kind":"event","bakedName":"SET_BIAS","curName":"SET_BIAS","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_ZC6K3WG5QZ2VZY7KHSPTWW8HFW":{"id":"evt_ZC6K3WG5QZ2VZY7KHSPTWW8HFW","kind":"event","bakedName":"RESTART","curName":"RESTART","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"evt_ZYK249QM6GT389ZFM6W6KMPBP3":{"id":"evt_ZYK249QM6GT389ZFM6W6KMPBP3","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_DY37T51ACZN6FJHHWJWR76GZEX"},"orb_VXMWKKSYQYZBZ5R069HQAZ2FN1":{"id":"orb_VXMWKKSYQYZBZ5R069HQAZ2FN1","kind":"orbital","bakedName":"MotionBodyOrbital","curName":"MotionBodyOrbital","renames":[],"owner":"workspace"},"pag_WP178EJE7073G9TRZ81PZCCWC4":{"id":"pag_WP178EJE7073G9TRZ81PZCCWC4","kind":"page","bakedName":"MotionBodyPage","curName":"MotionBodyPage","renames":[],"owner":"workspace"},"trt_DY37T51ACZN6FJHHWJWR76GZEX":{"id":"trt_DY37T51ACZN6FJHHWJWR76GZEX","kind":"trait","bakedName":"MotionBody","curName":"MotionBody","renames":[],"owner":"workspace"}}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"std-objective-reach","version":"1.0.0","description":"Headless reach-the-objective mechanic: owns features + score + objectivesLeft. Listens HERO_STEPPED and, when the hero lands on a target-type feature, scores it (optionally removing the model), emits a BURST pickup particle, and emits PROGRESS so round-flow can decide win/lose. Never writes units.","orbitals":[{"name":"ObjectiveReachOrbital","id":"orb_G41T87QY14Z0J8N2G3RNAG2QZ6","entity":{"name":"ObjectiveState","id":"ent_X9Z14M04DB26NR19TRSKE2MVTP","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"features","type":"array","items":{"type":"object","properties":{"id":{"name":"id","type":"string","required":false},"color":{"name":"color","type":"string","required":false},"done":{"name":"done","type":"boolean","required":false},"z":{"name":"z","type":"number","required":false},"type":{"name":"type","type":"string","required":true},"elevation":{"name":"elevation","type":"number","required":false},"x":{"name":"x","type":"number","required":true},"assetUrl":{"name":"assetUrl","type":"object","required":false,"properties":{"url":{"name":"url","type":"string","required":false},"dimension":{"name":"dimension","type":"string","required":false},"thumbnailUrl":{"name":"thumbnailUrl","type":"string","required":false},"variant":{"name":"variant","type":"string","required":false},"name":{"name":"name","type":"string","required":false},"style":{"name":"style","type":"string","required":false},"category":{"name":"category","type":"string","required":false},"aspect":{"name":"aspect","type":"string","required":false},"role":{"name":"role","type":"string","required":false},"animations":{"name":"animations","type":"array","required":false,"items":{"type":"string"}}}},"y":{"name":"y","type":"number","required":true}}}},{"name":"score","type":"number","default":0},{"name":"objectivesLeft","type":"number","default":0}],"shared":true},"traits":[{"name":"ObjectiveReach","id":"trt_23DYNV6PQBBBNZ795B3MSK9GAC","entityRebindable":true,"entityContract":{"requires":[],"provides":["features","objectivesLeft","score"]},"effectRow":[{"kind":"emit","resource":"BURST"},{"kind":"emit","resource":"PROGRESS"},{"kind":"set","resource":"@entity.features"},{"kind":"set","resource":"@entity.objectivesLeft"},{"kind":"set","resource":"@entity.score"}],"category":"lifecycle","linkedEntity":"ObjectiveState","linkedEntityId":"ent_X9Z14M04DB26NR19TRSKE2MVTP","entityRefIds":{"ObjectiveState":"ent_X9Z14M04DB26NR19TRSKE2MVTP"},"emits":[{"event":"BURST","eventId":"evt_QRHC2855CVJPDN67787T610E3F","description":"Pickup particle produced when a target is reached; a fx-particles listener spawns it","tier":"domain","scope":"external","payloadSchema":[{"name":"particles","type":"[object]","properties":[{"name":"id","type":"string","required":true},{"name":"type","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"z","type":"number"},{"name":"y","type":"number"},{"name":"message","type":"string"},{"name":"ttl","type":"number","required":true}],"entity":"Fx"}]},{"event":"PROGRESS","eventId":"evt_R5P91QHB6CNK6DTWWKJJRAYZ3V","description":"Objectives remaining + moves remaining after this step; a round-flow listener decides win/lose","tier":"domain","scope":"external","payloadSchema":[{"name":"objectivesLeft","type":"number","required":true},{"name":"movesLeft","type":"number","required":true}]}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_W0E797AVXYDYZ8JBWQDV3BN0B8","name":"Initialize"},{"key":"HERO_STEPPED","id":"evt_Q9QB3W581NM0TKG8FVMB8WVX7E","name":"Hero Stepped","payloadSchema":[{"name":"unitId","type":"string"},{"name":"x","type":"number"},{"name":"z","type":"number"},{"name":"movesLeft","type":"number"}],"listened":true},{"key":"RESTART","id":"evt_6NZZ5DDWPAYB52ZVFXJN80123S","name":"Restart","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"BURST","id":"evt_QRHC2855CVJPDN67787T610E3F","name":"Burst","description":"Pickup particle produced when a target is reached; a fx-particles listener spawns it","tier":"domain","payloadSchema":[{"name":"particles","type":"[object]","properties":[{"name":"id","type":"string","required":true},{"name":"type","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"z","type":"number"},{"name":"y","type":"number"},{"name":"message","type":"string"},{"name":"ttl","type":"number","required":true}],"entity":"Fx"}]},{"key":"PROGRESS","id":"evt_R5P91QHB6CNK6DTWWKJJRAYZ3V","name":"Progress","description":"Objectives remaining + moves remaining after this step; a round-flow listener decides win/lose","tier":"domain","payloadSchema":[{"name":"objectivesLeft","type":"number","required":true},{"name":"movesLeft","type":"number","required":true}]}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_W0E797AVXYDYZ8JBWQDV3BN0B8","effects":[["set","@entity.features","@config.features"],["set","@entity.score","@config.startScore"],["set","@entity.objectivesLeft",["array/len",["array/filter","@config.features",["fn","f",["==",["object/get","@f","type"],"@config.targetType"]]]]]]},{"from":"active","to":"active","event":"HERO_STEPPED","eventId":"evt_Q9QB3W581NM0TKG8FVMB8WVX7E","guard":"@config.running","effects":[["let",[["matched",["array/filter","@entity.features",["fn","f",["and",["==",["object/get","@f","type"],"@config.targetType"],["and",["!=",["object/get","@f","done"],true],["<=",["grid/manhattan-distance",{"x":["object/get","@f","x"],"y":["object/get","@f","y"]},{"x":"@payload.x","y":"@payload.z"}],"@config.reachRadius"]]]]]]],["let",[["hitCount",["array/len","@matched"]]],["do",["set","@entity.score",["+","@entity.score",["*","@config.pointsPerTarget","@hitCount"]]],["set","@entity.objectivesLeft",["-","@entity.objectivesLeft","@hitCount"]],["set","@entity.features",["if","@config.removeOnReach",["array/filter","@entity.features",["fn","f",["not",["and",["==",["object/get","@f","type"],"@config.targetType"],["and",["!=",["object/get","@f","done"],true],["<=",["grid/manhattan-distance",{"x":["object/get","@f","x"],"y":["object/get","@f","y"]},{"x":"@payload.x","y":"@payload.z"}],"@config.reachRadius"]]]]]],["array/map","@entity.features",["fn","f",["if",["and",["==",["object/get","@f","type"],"@config.targetType"],["and",["!=",["object/get","@f","done"],true],["<=",["grid/manhattan-distance",{"x":["object/get","@f","x"],"y":["object/get","@f","y"]},{"x":"@payload.x","y":"@payload.z"}],"@config.reachRadius"]]],["object/merge","@f",{"done":true}],"@f"]]]]],["emit","BURST",{"particles":["array/map","@matched",["fn","f",{"id":["str/concat","fx-obj-",["object/get","@f","id"]],"type":"pickup","x":["object/get","@f","x"],"z":["object/get","@f","y"],"message":"+1","ttl":3}]]}],["emit","PROGRESS",{"objectivesLeft":"@entity.objectivesLeft","movesLeft":"@payload.movesLeft"}]]]]]},{"from":"active","to":"active","event":"RESTART","eventId":"evt_6NZZ5DDWPAYB52ZVFXJN80123S","effects":[["set","@entity.features","@config.features"],["set","@entity.score","@config.startScore"],["set","@entity.objectivesLeft",["array/len",["array/filter","@config.features",["fn","f",["==",["object/get","@f","type"],"@config.targetType"]]]]]]}]},"config":{"features":{"type":"[Feature]","default":[],"label":"Features","description":"Board features — collectible targets (matched by targetType) plus decorations","tier":"domain","items":{"type":"object","properties":{"id":{"name":"id","type":"string","required":false},"z":{"name":"z","type":"number","required":false},"y":{"name":"y","type":"number","required":true},"x":{"name":"x","type":"number","required":true},"assetUrl":{"name":"assetUrl","type":"object","required":false,"properties":{"aspect":{"name":"aspect","type":"string","required":false},"thumbnailUrl":{"name":"thumbnailUrl","type":"string","required":false},"name":{"name":"name","type":"string","required":false},"role":{"name":"role","type":"string","required":false},"variant":{"name":"variant","type":"string","required":false},"category":{"name":"category","type":"string","required":false},"animations":{"name":"animations","type":"array","required":false,"items":{"type":"string"}},"dimension":{"name":"dimension","type":"string","required":false},"style":{"name":"style","type":"string","required":false},"url":{"name":"url","type":"string","required":false}}},"done":{"name":"done","type":"boolean","required":false},"type":{"name":"type","type":"string","required":true},"elevation":{"name":"elevation","type":"number","required":false},"color":{"name":"color","type":"string","required":false}}}},"reachRadius":{"type":"number","default":0,"label":"Reach Radius","description":"Manhattan distance at which a target counts as reached: 0 = step onto the tile (collect), 1 = adjacent (deliver)","tier":"domain"},"pointsPerTarget":{"type":"number","default":1,"label":"Points Per Target","description":"Score awarded per objective reached","tier":"domain"},"startScore":{"type":"number","default":0,"label":"Start Score","description":"Score set on INIT","tier":"domain"},"targetType":{"type":"string","default":"gift","label":"Target Type","description":"Feature type counted as a collectible objective","tier":"domain"},"running":{"type":"boolean","default":true,"label":"Running","description":"When true, hero steps onto targets are scored; toggle to freeze","tier":"domain"},"removeOnReach":{"type":"boolean","default":true,"label":"Remove On Reach","description":"When true the target model is removed once reached (collect); when false it is flagged done and stays (visit/deliver)","tier":"domain"}},"scope":"instance"}],"pages":[{"name":"ObjectiveReachPage","id":"pag_4JF54CX5MHJT8P7TTGPD5X69NM","path":"/objective-reach","traits":[{"ref":"ObjectiveReach","refId":"trt_23DYNV6PQBBBNZ795B3MSK9GAC"}]}],"types":{"Asset":[{"name":"url","type":"asset"},{"name":"role","type":"string"},{"name":"category","type":"string"},{"name":"animations","type":"[string]"},{"name":"style","type":"string"},{"name":"variant","type":"string"},{"name":"dimension","type":"string"},{"name":"aspect","type":"string"},{"name":"name","type":"string"},{"name":"thumbnailUrl","type":"string"}],"Feature":[{"name":"id","type":"string"},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"z","type":"number"},{"name":"type","type":"string","required":true},{"name":"assetUrl","type":"object","properties":[{"name":"url","type":"asset"},{"name":"role","type":"string"},{"name":"category","type":"string"},{"name":"animations","type":"[string]"},{"name":"style","type":"string"},{"name":"variant","type":"string"},{"name":"dimension","type":"string"},{"name":"aspect","type":"string"},{"name":"name","type":"string"},{"name":"thumbnailUrl","type":"string"}]},{"name":"color","type":"string"},{"name":"elevation","type":"number"},{"name":"done","type":"boolean"}],"Fx":[{"name":"id","type":"string","required":true},{"name":"type","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"z","type":"number"},{"name":"y","type":"number"},{"name":"message","type":"string"},{"name":"ttl","type":"number","required":true}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_X9Z14M04DB26NR19TRSKE2MVTP":{"id":"ent_X9Z14M04DB26NR19TRSKE2MVTP","kind":"entity","bakedName":"ObjectiveState","curName":"ObjectiveState","renames":[],"owner":"workspace"},"evt_6NZZ5DDWPAYB52ZVFXJN80123S":{"id":"evt_6NZZ5DDWPAYB52ZVFXJN80123S","kind":"event","bakedName":"RESTART","curName":"RESTART","renames":[],"owner":"workspace","parent":"trt_23DYNV6PQBBBNZ795B3MSK9GAC"},"evt_Q9QB3W581NM0TKG8FVMB8WVX7E":{"id":"evt_Q9QB3W581NM0TKG8FVMB8WVX7E","kind":"event","bakedName":"HERO_STEPPED","curName":"HERO_STEPPED","renames":[],"owner":"workspace","parent":"trt_23DYNV6PQBBBNZ795B3MSK9GAC"},"evt_QRHC2855CVJPDN67787T610E3F":{"id":"evt_QRHC2855CVJPDN67787T610E3F","kind":"event","bakedName":"BURST","curName":"BURST","renames":[],"owner":"workspace","parent":"trt_23DYNV6PQBBBNZ795B3MSK9GAC"},"evt_R5P91QHB6CNK6DTWWKJJRAYZ3V":{"id":"evt_R5P91QHB6CNK6DTWWKJJRAYZ3V","kind":"event","bakedName":"PROGRESS","curName":"PROGRESS","renames":[],"owner":"workspace","parent":"trt_23DYNV6PQBBBNZ795B3MSK9GAC"},"evt_W0E797AVXYDYZ8JBWQDV3BN0B8":{"id":"evt_W0E797AVXYDYZ8JBWQDV3BN0B8","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_23DYNV6PQBBBNZ795B3MSK9GAC"},"orb_G41T87QY14Z0J8N2G3RNAG2QZ6":{"id":"orb_G41T87QY14Z0J8N2G3RNAG2QZ6","kind":"orbital","bakedName":"ObjectiveReachOrbital","curName":"ObjectiveReachOrbital","renames":[],"owner":"workspace"},"pag_4JF54CX5MHJT8P7TTGPD5X69NM":{"id":"pag_4JF54CX5MHJT8P7TTGPD5X69NM","kind":"page","bakedName":"ObjectiveReachPage","curName":"ObjectiveReachPage","renames":[],"owner":"workspace"},"trt_23DYNV6PQBBBNZ795B3MSK9GAC":{"id":"trt_23DYNV6PQBBBNZ795B3MSK9GAC","kind":"trait","bakedName":"ObjectiveReach","curName":"ObjectiveReach","renames":[],"owner":"workspace"}}}}
|
|
1
|
+
{"name":"std-objective-reach","version":"1.0.0","description":"Headless reach-the-objective mechanic: owns features + score + objectivesLeft. Listens HERO_STEPPED and, when the hero lands on a target-type feature, scores it (optionally removing the model), emits a BURST pickup particle, and emits PROGRESS so round-flow can decide win/lose. Never writes units.","orbitals":[{"name":"ObjectiveReachOrbital","id":"orb_G41T87QY14Z0J8N2G3RNAG2QZ6","entity":{"name":"ObjectiveState","id":"ent_X9Z14M04DB26NR19TRSKE2MVTP","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"features","type":"array","items":{"type":"object","properties":{"type":{"name":"type","type":"string","required":true},"color":{"name":"color","type":"string","required":false},"elevation":{"name":"elevation","type":"number","required":false},"z":{"name":"z","type":"number","required":false},"assetUrl":{"name":"assetUrl","type":"object","required":false,"properties":{"thumbnailUrl":{"name":"thumbnailUrl","type":"string","required":false},"url":{"name":"url","type":"string","required":false},"variant":{"name":"variant","type":"string","required":false},"style":{"name":"style","type":"string","required":false},"name":{"name":"name","type":"string","required":false},"dimension":{"name":"dimension","type":"string","required":false},"animations":{"name":"animations","type":"array","required":false,"items":{"type":"string"}},"aspect":{"name":"aspect","type":"string","required":false},"category":{"name":"category","type":"string","required":false},"role":{"name":"role","type":"string","required":false}}},"y":{"name":"y","type":"number","required":true},"done":{"name":"done","type":"boolean","required":false},"x":{"name":"x","type":"number","required":true},"id":{"name":"id","type":"string","required":false}}}},{"name":"score","type":"number","default":0},{"name":"objectivesLeft","type":"number","default":0}],"shared":true},"traits":[{"name":"ObjectiveReach","id":"trt_23DYNV6PQBBBNZ795B3MSK9GAC","entityRebindable":true,"entityContract":{"requires":[],"provides":["features","objectivesLeft","score"]},"effectRow":[{"kind":"emit","resource":"BURST"},{"kind":"emit","resource":"PROGRESS"},{"kind":"set","resource":"@entity.features"},{"kind":"set","resource":"@entity.objectivesLeft"},{"kind":"set","resource":"@entity.score"}],"category":"lifecycle","linkedEntity":"ObjectiveState","linkedEntityId":"ent_X9Z14M04DB26NR19TRSKE2MVTP","entityRefIds":{"ObjectiveState":"ent_X9Z14M04DB26NR19TRSKE2MVTP"},"emits":[{"event":"BURST","eventId":"evt_QRHC2855CVJPDN67787T610E3F","description":"Pickup particle produced when a target is reached; a fx-particles listener spawns it","tier":"domain","scope":"external","payloadSchema":[{"name":"particles","type":"[object]","properties":[{"name":"id","type":"string","required":true},{"name":"type","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"z","type":"number"},{"name":"y","type":"number"},{"name":"message","type":"string"},{"name":"ttl","type":"number","required":true}],"entity":"Fx"}]},{"event":"PROGRESS","eventId":"evt_R5P91QHB6CNK6DTWWKJJRAYZ3V","description":"Objectives remaining + moves remaining after this step; a round-flow listener decides win/lose","tier":"domain","scope":"external","payloadSchema":[{"name":"objectivesLeft","type":"number","required":true},{"name":"movesLeft","type":"number","required":true}]}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_W0E797AVXYDYZ8JBWQDV3BN0B8","name":"Initialize"},{"key":"HERO_STEPPED","id":"evt_Q9QB3W581NM0TKG8FVMB8WVX7E","name":"Hero Stepped","payloadSchema":[{"name":"unitId","type":"string"},{"name":"x","type":"number"},{"name":"z","type":"number"},{"name":"movesLeft","type":"number"}],"listened":true},{"key":"RESTART","id":"evt_6NZZ5DDWPAYB52ZVFXJN80123S","name":"Restart","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"BURST","id":"evt_QRHC2855CVJPDN67787T610E3F","name":"Burst","description":"Pickup particle produced when a target is reached; a fx-particles listener spawns it","tier":"domain","payloadSchema":[{"name":"particles","type":"[object]","properties":[{"name":"id","type":"string","required":true},{"name":"type","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"z","type":"number"},{"name":"y","type":"number"},{"name":"message","type":"string"},{"name":"ttl","type":"number","required":true}],"entity":"Fx"}]},{"key":"PROGRESS","id":"evt_R5P91QHB6CNK6DTWWKJJRAYZ3V","name":"Progress","description":"Objectives remaining + moves remaining after this step; a round-flow listener decides win/lose","tier":"domain","payloadSchema":[{"name":"objectivesLeft","type":"number","required":true},{"name":"movesLeft","type":"number","required":true}]}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_W0E797AVXYDYZ8JBWQDV3BN0B8","effects":[["set","@entity.features","@config.features"],["set","@entity.score","@config.startScore"],["set","@entity.objectivesLeft",["array/len",["array/filter","@config.features",["fn","f",["==",["object/get","@f","type"],"@config.targetType"]]]]]]},{"from":"active","to":"active","event":"HERO_STEPPED","eventId":"evt_Q9QB3W581NM0TKG8FVMB8WVX7E","guard":"@config.running","effects":[["let",[["matched",["array/filter","@entity.features",["fn","f",["and",["==",["object/get","@f","type"],"@config.targetType"],["and",["!=",["object/get","@f","done"],true],["<=",["grid/manhattan-distance",{"x":["object/get","@f","x"],"y":["object/get","@f","y"]},{"x":"@payload.x","y":"@payload.z"}],"@config.reachRadius"]]]]]]],["let",[["hitCount",["array/len","@matched"]]],["do",["set","@entity.score",["+","@entity.score",["*","@config.pointsPerTarget","@hitCount"]]],["set","@entity.objectivesLeft",["-","@entity.objectivesLeft","@hitCount"]],["set","@entity.features",["if","@config.removeOnReach",["array/filter","@entity.features",["fn","f",["not",["and",["==",["object/get","@f","type"],"@config.targetType"],["and",["!=",["object/get","@f","done"],true],["<=",["grid/manhattan-distance",{"x":["object/get","@f","x"],"y":["object/get","@f","y"]},{"x":"@payload.x","y":"@payload.z"}],"@config.reachRadius"]]]]]],["array/map","@entity.features",["fn","f",["if",["and",["==",["object/get","@f","type"],"@config.targetType"],["and",["!=",["object/get","@f","done"],true],["<=",["grid/manhattan-distance",{"x":["object/get","@f","x"],"y":["object/get","@f","y"]},{"x":"@payload.x","y":"@payload.z"}],"@config.reachRadius"]]],["object/merge","@f",{"done":true}],"@f"]]]]],["emit","BURST",{"particles":["array/map","@matched",["fn","f",{"id":["str/concat","fx-obj-",["object/get","@f","id"]],"type":"pickup","x":["object/get","@f","x"],"z":["object/get","@f","y"],"message":"+1","ttl":3}]]}],["emit","PROGRESS",{"objectivesLeft":"@entity.objectivesLeft","movesLeft":"@payload.movesLeft"}]]]]]},{"from":"active","to":"active","event":"RESTART","eventId":"evt_6NZZ5DDWPAYB52ZVFXJN80123S","effects":[["set","@entity.features","@config.features"],["set","@entity.score","@config.startScore"],["set","@entity.objectivesLeft",["array/len",["array/filter","@config.features",["fn","f",["==",["object/get","@f","type"],"@config.targetType"]]]]]]}]},"config":{"targetType":{"type":"string","default":"gift","label":"Target Type","description":"Feature type counted as a collectible objective","tier":"domain"},"removeOnReach":{"type":"boolean","default":true,"label":"Remove On Reach","description":"When true the target model is removed once reached (collect); when false it is flagged done and stays (visit/deliver)","tier":"domain"},"features":{"type":"[Feature]","default":[],"label":"Features","description":"Board features — collectible targets (matched by targetType) plus decorations","tier":"domain","items":{"type":"object","properties":{"color":{"name":"color","type":"string","required":false},"z":{"name":"z","type":"number","required":false},"elevation":{"name":"elevation","type":"number","required":false},"id":{"name":"id","type":"string","required":false},"type":{"name":"type","type":"string","required":true},"x":{"name":"x","type":"number","required":true},"assetUrl":{"name":"assetUrl","type":"object","required":false,"properties":{"style":{"name":"style","type":"string","required":false},"thumbnailUrl":{"name":"thumbnailUrl","type":"string","required":false},"url":{"name":"url","type":"string","required":false},"role":{"name":"role","type":"string","required":false},"name":{"name":"name","type":"string","required":false},"dimension":{"name":"dimension","type":"string","required":false},"animations":{"name":"animations","type":"array","required":false,"items":{"type":"string"}},"aspect":{"name":"aspect","type":"string","required":false},"category":{"name":"category","type":"string","required":false},"variant":{"name":"variant","type":"string","required":false}}},"done":{"name":"done","type":"boolean","required":false},"y":{"name":"y","type":"number","required":true}}}},"reachRadius":{"type":"number","default":0,"label":"Reach Radius","description":"Manhattan distance at which a target counts as reached: 0 = step onto the tile (collect), 1 = adjacent (deliver)","tier":"domain"},"running":{"type":"boolean","default":true,"label":"Running","description":"When true, hero steps onto targets are scored; toggle to freeze","tier":"domain"},"startScore":{"type":"number","default":0,"label":"Start Score","description":"Score set on INIT","tier":"domain"},"pointsPerTarget":{"type":"number","default":1,"label":"Points Per Target","description":"Score awarded per objective reached","tier":"domain"}},"scope":"instance"}],"pages":[{"name":"ObjectiveReachPage","id":"pag_4JF54CX5MHJT8P7TTGPD5X69NM","path":"/objective-reach","traits":[{"ref":"ObjectiveReach","refId":"trt_23DYNV6PQBBBNZ795B3MSK9GAC"}]}],"types":{"Asset":[{"name":"url","type":"asset"},{"name":"role","type":"string"},{"name":"category","type":"string"},{"name":"animations","type":"[string]"},{"name":"style","type":"string"},{"name":"variant","type":"string"},{"name":"dimension","type":"string"},{"name":"aspect","type":"string"},{"name":"name","type":"string"},{"name":"thumbnailUrl","type":"string"}],"Feature":[{"name":"id","type":"string"},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"z","type":"number"},{"name":"type","type":"string","required":true},{"name":"assetUrl","type":"object","properties":[{"name":"url","type":"asset"},{"name":"role","type":"string"},{"name":"category","type":"string"},{"name":"animations","type":"[string]"},{"name":"style","type":"string"},{"name":"variant","type":"string"},{"name":"dimension","type":"string"},{"name":"aspect","type":"string"},{"name":"name","type":"string"},{"name":"thumbnailUrl","type":"string"}]},{"name":"color","type":"string"},{"name":"elevation","type":"number"},{"name":"done","type":"boolean"}],"Fx":[{"name":"id","type":"string","required":true},{"name":"type","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"z","type":"number"},{"name":"y","type":"number"},{"name":"message","type":"string"},{"name":"ttl","type":"number","required":true}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_X9Z14M04DB26NR19TRSKE2MVTP":{"id":"ent_X9Z14M04DB26NR19TRSKE2MVTP","kind":"entity","bakedName":"ObjectiveState","curName":"ObjectiveState","renames":[],"owner":"workspace"},"evt_6NZZ5DDWPAYB52ZVFXJN80123S":{"id":"evt_6NZZ5DDWPAYB52ZVFXJN80123S","kind":"event","bakedName":"RESTART","curName":"RESTART","renames":[],"owner":"workspace","parent":"trt_23DYNV6PQBBBNZ795B3MSK9GAC"},"evt_Q9QB3W581NM0TKG8FVMB8WVX7E":{"id":"evt_Q9QB3W581NM0TKG8FVMB8WVX7E","kind":"event","bakedName":"HERO_STEPPED","curName":"HERO_STEPPED","renames":[],"owner":"workspace","parent":"trt_23DYNV6PQBBBNZ795B3MSK9GAC"},"evt_QRHC2855CVJPDN67787T610E3F":{"id":"evt_QRHC2855CVJPDN67787T610E3F","kind":"event","bakedName":"BURST","curName":"BURST","renames":[],"owner":"workspace","parent":"trt_23DYNV6PQBBBNZ795B3MSK9GAC"},"evt_R5P91QHB6CNK6DTWWKJJRAYZ3V":{"id":"evt_R5P91QHB6CNK6DTWWKJJRAYZ3V","kind":"event","bakedName":"PROGRESS","curName":"PROGRESS","renames":[],"owner":"workspace","parent":"trt_23DYNV6PQBBBNZ795B3MSK9GAC"},"evt_W0E797AVXYDYZ8JBWQDV3BN0B8":{"id":"evt_W0E797AVXYDYZ8JBWQDV3BN0B8","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_23DYNV6PQBBBNZ795B3MSK9GAC"},"orb_G41T87QY14Z0J8N2G3RNAG2QZ6":{"id":"orb_G41T87QY14Z0J8N2G3RNAG2QZ6","kind":"orbital","bakedName":"ObjectiveReachOrbital","curName":"ObjectiveReachOrbital","renames":[],"owner":"workspace"},"pag_4JF54CX5MHJT8P7TTGPD5X69NM":{"id":"pag_4JF54CX5MHJT8P7TTGPD5X69NM","kind":"page","bakedName":"ObjectiveReachPage","curName":"ObjectiveReachPage","renames":[],"owner":"workspace"},"trt_23DYNV6PQBBBNZ795B3MSK9GAC":{"id":"trt_23DYNV6PQBBBNZ795B3MSK9GAC","kind":"trait","bakedName":"ObjectiveReach","curName":"ObjectiveReach","renames":[],"owner":"workspace"}}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"std-pad-lock","version":"1.0.0","description":"Headless pad-lock mechanic: floor pads that light when the player steps on them, completing a set when every pad is lit. Listens BODY_MOVED and lights any unlit live pad the player's rect touches (|dx| <= reachX, |dy| <= reachY of the pad center); a lit pad stays lit. Pads may carry a group number (grp 0 = ungrouped, always live): when groups are used, only pads of the lowest uncompleted group are live — pads of later groups refuse to light until the current group finishes, so one sum must be finished before the next. When a group completes the trait emits PAD_GROUP_COMPLETED once for it (first newly completed group reports; the shared entity carries the rest); when every pad in the set is lit it stamps completed and emits PAD_SET_COMPLETED once. The lowest uncompleted group is stamped on the shared entity as currentGrp so boards can pulse exactly the live pads (0 = no group open / ungrouped pads). RESTART unlights every live pad and resets the set (re-arming the live entity set, so SET_PADS-injected pads survive respawns). SET_PADS replaces the pad set at runtime for boards that import their pads. Renders nothing; boards draw the pads and read lit from the shared entity (the render authority). Corresponds to the design-sheet field(s): challenge, mechanics.","orbitals":[{"name":"PadLockOrbital","id":"orb_X3FTTJNTRGXC88SXBC38N358JQ","entity":{"name":"PadLockData","id":"ent_9XQSR0W4K929MNJ2VP6SQJXAG6","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"pads","type":"array","default":[],"items":{"type":"object","properties":{"grp":{"name":"grp","type":"number","required":true},"y":{"name":"y","type":"number","required":true},"id":{"name":"id","type":"string","required":true},"x":{"name":"x","type":"number","required":true},"lit":{"name":"lit","type":"boolean","required":false}}}},{"name":"groupsDone","type":"array","default":[],"items":{"type":"number"}},{"name":"currentGrp","type":"number","default":0},{"name":"completed","type":"boolean","default":false}],"shared":true},"traits":[{"name":"PadLock","id":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX","entityRebindable":true,"entityContract":{"requires":[],"provides":["completed","currentGrp","groupsDone","pads"]},"effectRow":[{"kind":"emit","resource":"PAD_GROUP_COMPLETED"},{"kind":"emit","resource":"PAD_SET_COMPLETED"},{"kind":"set","resource":"@entity.completed"},{"kind":"set","resource":"@entity.currentGrp"},{"kind":"set","resource":"@entity.groupsDone"},{"kind":"set","resource":"@entity.pads"}],"category":"lifecycle","linkedEntity":"PadLockData","linkedEntityId":"ent_9XQSR0W4K929MNJ2VP6SQJXAG6","entityRefIds":{"PadLockData":"ent_9XQSR0W4K929MNJ2VP6SQJXAG6"},"emits":[{"event":"PAD_GROUP_COMPLETED","eventId":"evt_WG241MR30G1G829KQHE5PHAE3F","description":"Every pad of one group is lit; fires once per group, in group order — later groups stay dead until the lowest uncompleted group finishes. Boards layer a small fx and unlock the next group's pads.","tier":"domain","scope":"external","payloadSchema":[{"name":"grp","type":"number","required":true}]},{"event":"PAD_SET_COMPLETED","eventId":"evt_DH083KRK999MMSVFZ83E0DZ9QE","description":"Every pad in the set is lit; fires once per run. Boards layer the treasure fx and spill the bonus reward.","tier":"domain","scope":"external"}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_GT40K216HYK8Z0YHV7CVTZY95W","name":"Initialize"},{"key":"BODY_MOVED","id":"evt_GQS73J09QP4VVACYYM9WZZGF8J","name":"Body Moved","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}],"listened":true},{"key":"SET_PADS","id":"evt_QNE8ZDDJMESA78KK1NSHEYQDXR","name":"Set Pads","payloadSchema":[{"name":"pads","type":"[object]","required":true,"properties":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"grp","type":"number","required":true},{"name":"lit","type":"boolean"}]}],"listened":true},{"key":"RESTART","id":"evt_Z3B3N8J3VX1XYHRZE33NBCD8QC","name":"Restart","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"PAD_GROUP_COMPLETED","id":"evt_WG241MR30G1G829KQHE5PHAE3F","name":"Pad Group Completed","description":"Every pad of one group is lit; fires once per group, in group order — later groups stay dead until the lowest uncompleted group finishes. Boards layer a small fx and unlock the next group's pads.","tier":"domain","payloadSchema":[{"name":"grp","type":"number","required":true}]},{"key":"PAD_SET_COMPLETED","id":"evt_DH083KRK999MMSVFZ83E0DZ9QE","name":"Pad Set Completed","description":"Every pad in the set is lit; fires once per run. Boards layer the treasure fx and spill the bonus reward.","tier":"domain"}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_GT40K216HYK8Z0YHV7CVTZY95W","effects":[["set","@entity.pads",["array/map","@config.pads",["fn","p",["object/merge","@p",{"lit":false}]]]],["set","@entity.groupsDone",[]],["set","@entity.currentGrp",0],["set","@entity.completed",false]]},{"from":"active","to":"active","event":"BODY_MOVED","eventId":"evt_GQS73J09QP4VVACYYM9WZZGF8J","guard":"@config.running","effects":[["let",[["grpIds",["array/reduce",["array/map",["array/filter","@entity.pads",["fn","p",[">",["object/get","@p","grp"],0]]],["fn","p",["object/get","@p","grp"]]],[],["fn",["acc","g"],["if",[">",["array/len",["array/filter","@acc",["fn","x",["==","@x","@g"]]]],0],"@acc",["array/append","@acc","@g"]]]]]],["let",[["openGrps",["array/filter","@grpIds",["fn","g",["<",["array/len",["array/filter","@entity.pads",["fn","p",["and",["==",["object/get","@p","grp"],"@g"],["==",["object/get","@p","lit"],true]]]]],["array/len",["array/filter","@entity.pads",["fn","p",["==",["object/get","@p","grp"],"@g"]]]]]]]]],["let",[["currentGrp",["array/reduce","@openGrps",9999,["fn",["acc","g"],["math/min","@acc","@g"]]]]],["let",[["newPads",["array/map","@entity.pads",["fn","p",["object/merge","@p",{"lit":["or",["object/get","@p","lit"],["and",["or",["==",["object/get","@p","grp"],0],["==",["object/get","@p","grp"],"@currentGrp"]],["and",["<=",["math/abs",["-","@payload.x",["object/get","@p","x"]]],"@config.reachX"],["<=",["math/abs",["-","@payload.y",["object/get","@p","y"]]],"@config.reachY"]]]]}]]]]],["let",[["doneNow",["array/filter","@grpIds",["fn","g",["==",["array/len",["array/filter","@newPads",["fn","p",["and",["==",["object/get","@p","grp"],"@g"],["==",["object/get","@p","lit"],true]]]]],["array/len",["array/filter","@newPads",["fn","p",["==",["object/get","@p","grp"],"@g"]]]]]]]]],["let",[["newlyGrp",["array/filter","@doneNow",["fn","g",["==",["array/len",["array/filter","@entity.groupsDone",["fn","d",["==","@d","@g"]]]],0]]]]],["do",["set","@entity.pads","@newPads"],["set","@entity.currentGrp",["if",["==","@currentGrp",9999],0,"@currentGrp"]],["if",[">",["array/len","@newlyGrp"],0],["do",["set","@entity.groupsDone","@doneNow"],["emit","PAD_GROUP_COMPLETED",{"grp":["array/first","@newlyGrp"]}]],null],["if",["and",["==","@entity.completed",false],["==",["array/len",["array/filter","@newPads",["fn","p",["==",["object/get","@p","lit"],false]]]],0]],["do",["set","@entity.completed",true],["emit","PAD_SET_COMPLETED",{}]],null]]]]]]]]]},{"from":"active","to":"active","event":"SET_PADS","eventId":"evt_QNE8ZDDJMESA78KK1NSHEYQDXR","effects":[["set","@entity.pads",["array/map","@payload.pads",["fn","p",["object/merge","@p",{"lit":false}]]]],["set","@entity.groupsDone",[]],["set","@entity.currentGrp",0],["set","@entity.completed",false]]},{"from":"active","to":"active","event":"RESTART","eventId":"evt_Z3B3N8J3VX1XYHRZE33NBCD8QC","effects":[["set","@entity.pads",["array/map","@entity.pads",["fn","p",["object/merge","@p",{"lit":false}]]]],["set","@entity.groupsDone",[]],["set","@entity.currentGrp",0],["set","@entity.completed",false]]}]},"config":{"running":{"type":"boolean","default":true,"label":"Running","description":"When true, BODY_MOVED lights touched live pads and reports group/set completion; toggle to freeze every pad as-is.","tier":"domain"},"reachX":{"type":"number","default":0.7,"label":"Reach X","description":"Horizontal tolerance (world units) around a pad's center when testing player contact (approximates the body's half-width plus a step).","tier":"domain"},"pads":{"type":"[PadLock]","default":[],"label":"Pads","description":"One row per floor pad: id, center (x, y in world units), and grp (0 = ungrouped, always live; N = live only while it is the lowest uncompleted group). lit is stamped at runtime. Seeded onto the entity on INIT; the live set is entity.pads — SET_PADS replaces it at runtime (boards that import pads), and RESTART re-arms the live set rather than re-reading config, so injected pads survive respawns.","tier":"domain","items":{"type":"object","properties":{"lit":{"name":"lit","type":"boolean","required":false},"x":{"name":"x","type":"number","required":true},"grp":{"name":"grp","type":"number","required":true},"y":{"name":"y","type":"number","required":true},"id":{"name":"id","type":"string","required":true}}}},"reachY":{"type":"number","default":1.2,"label":"Reach Y","description":"Vertical tolerance (world units) around a pad's center when testing player contact (covers skating over the surface the pad sits on).","tier":"domain"}},"scope":"instance"}],"pages":[{"name":"PadLockPage","id":"pag_SZ8RW2WENH7ARQ6H5PSC7WQRC0","path":"/pad-lock","traits":[{"ref":"PadLock","refId":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"}]}],"types":{"PadLock":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"grp","type":"number","required":true},{"name":"lit","type":"boolean"}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_9XQSR0W4K929MNJ2VP6SQJXAG6":{"id":"ent_9XQSR0W4K929MNJ2VP6SQJXAG6","kind":"entity","bakedName":"PadLockData","curName":"PadLockData","renames":[],"owner":"workspace"},"evt_DH083KRK999MMSVFZ83E0DZ9QE":{"id":"evt_DH083KRK999MMSVFZ83E0DZ9QE","kind":"event","bakedName":"PAD_SET_COMPLETED","curName":"PAD_SET_COMPLETED","renames":[],"owner":"workspace","parent":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"},"evt_GQS73J09QP4VVACYYM9WZZGF8J":{"id":"evt_GQS73J09QP4VVACYYM9WZZGF8J","kind":"event","bakedName":"BODY_MOVED","curName":"BODY_MOVED","renames":[],"owner":"workspace","parent":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"},"evt_GT40K216HYK8Z0YHV7CVTZY95W":{"id":"evt_GT40K216HYK8Z0YHV7CVTZY95W","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"},"evt_QNE8ZDDJMESA78KK1NSHEYQDXR":{"id":"evt_QNE8ZDDJMESA78KK1NSHEYQDXR","kind":"event","bakedName":"SET_PADS","curName":"SET_PADS","renames":[],"owner":"workspace","parent":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"},"evt_WG241MR30G1G829KQHE5PHAE3F":{"id":"evt_WG241MR30G1G829KQHE5PHAE3F","kind":"event","bakedName":"PAD_GROUP_COMPLETED","curName":"PAD_GROUP_COMPLETED","renames":[],"owner":"workspace","parent":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"},"evt_Z3B3N8J3VX1XYHRZE33NBCD8QC":{"id":"evt_Z3B3N8J3VX1XYHRZE33NBCD8QC","kind":"event","bakedName":"RESTART","curName":"RESTART","renames":[],"owner":"workspace","parent":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"},"orb_X3FTTJNTRGXC88SXBC38N358JQ":{"id":"orb_X3FTTJNTRGXC88SXBC38N358JQ","kind":"orbital","bakedName":"PadLockOrbital","curName":"PadLockOrbital","renames":[],"owner":"workspace"},"pag_SZ8RW2WENH7ARQ6H5PSC7WQRC0":{"id":"pag_SZ8RW2WENH7ARQ6H5PSC7WQRC0","kind":"page","bakedName":"PadLockPage","curName":"PadLockPage","renames":[],"owner":"workspace"},"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX":{"id":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX","kind":"trait","bakedName":"PadLock","curName":"PadLock","renames":[],"owner":"workspace"}}}}
|
|
1
|
+
{"name":"std-pad-lock","version":"1.0.0","description":"Headless pad-lock mechanic: floor pads that light when the player steps on them, completing a set when every pad is lit. Listens BODY_MOVED and lights any unlit live pad the player's rect touches (|dx| <= reachX, |dy| <= reachY of the pad center); a lit pad stays lit. Pads may carry a group number (grp 0 = ungrouped, always live): when groups are used, only pads of the lowest uncompleted group are live — pads of later groups refuse to light until the current group finishes, so one sum must be finished before the next. When a group completes the trait emits PAD_GROUP_COMPLETED once for it (first newly completed group reports; the shared entity carries the rest); when every pad in the set is lit it stamps completed and emits PAD_SET_COMPLETED once. The lowest uncompleted group is stamped on the shared entity as currentGrp so boards can pulse exactly the live pads (0 = no group open / ungrouped pads). RESTART unlights every live pad and resets the set (re-arming the live entity set, so SET_PADS-injected pads survive respawns). SET_PADS replaces the pad set at runtime for boards that import their pads. Renders nothing; boards draw the pads and read lit from the shared entity (the render authority). Corresponds to the design-sheet field(s): challenge, mechanics.","orbitals":[{"name":"PadLockOrbital","id":"orb_X3FTTJNTRGXC88SXBC38N358JQ","entity":{"name":"PadLockData","id":"ent_9XQSR0W4K929MNJ2VP6SQJXAG6","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"pads","type":"array","default":[],"items":{"type":"object","properties":{"x":{"name":"x","type":"number","required":true},"lit":{"name":"lit","type":"boolean","required":false},"grp":{"name":"grp","type":"number","required":true},"y":{"name":"y","type":"number","required":true},"id":{"name":"id","type":"string","required":true}}}},{"name":"groupsDone","type":"array","default":[],"items":{"type":"number"}},{"name":"currentGrp","type":"number","default":0},{"name":"completed","type":"boolean","default":false}],"shared":true},"traits":[{"name":"PadLock","id":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX","entityRebindable":true,"entityContract":{"requires":[],"provides":["completed","currentGrp","groupsDone","pads"]},"effectRow":[{"kind":"emit","resource":"PAD_GROUP_COMPLETED"},{"kind":"emit","resource":"PAD_SET_COMPLETED"},{"kind":"set","resource":"@entity.completed"},{"kind":"set","resource":"@entity.currentGrp"},{"kind":"set","resource":"@entity.groupsDone"},{"kind":"set","resource":"@entity.pads"}],"category":"lifecycle","linkedEntity":"PadLockData","linkedEntityId":"ent_9XQSR0W4K929MNJ2VP6SQJXAG6","entityRefIds":{"PadLockData":"ent_9XQSR0W4K929MNJ2VP6SQJXAG6"},"emits":[{"event":"PAD_GROUP_COMPLETED","eventId":"evt_WG241MR30G1G829KQHE5PHAE3F","description":"Every pad of one group is lit; fires once per group, in group order — later groups stay dead until the lowest uncompleted group finishes. Boards layer a small fx and unlock the next group's pads.","tier":"domain","scope":"external","payloadSchema":[{"name":"grp","type":"number","required":true}]},{"event":"PAD_SET_COMPLETED","eventId":"evt_DH083KRK999MMSVFZ83E0DZ9QE","description":"Every pad in the set is lit; fires once per run. Boards layer the treasure fx and spill the bonus reward.","tier":"domain","scope":"external"}],"stateMachine":{"states":[{"name":"active","isInitial":true}],"events":[{"key":"INIT","id":"evt_GT40K216HYK8Z0YHV7CVTZY95W","name":"Initialize"},{"key":"BODY_MOVED","id":"evt_GQS73J09QP4VVACYYM9WZZGF8J","name":"Body Moved","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}],"listened":true},{"key":"SET_PADS","id":"evt_QNE8ZDDJMESA78KK1NSHEYQDXR","name":"Set Pads","payloadSchema":[{"name":"pads","type":"[object]","required":true,"properties":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"grp","type":"number","required":true},{"name":"lit","type":"boolean"}]}],"listened":true},{"key":"RESTART","id":"evt_Z3B3N8J3VX1XYHRZE33NBCD8QC","name":"Restart","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"PAD_GROUP_COMPLETED","id":"evt_WG241MR30G1G829KQHE5PHAE3F","name":"Pad Group Completed","description":"Every pad of one group is lit; fires once per group, in group order — later groups stay dead until the lowest uncompleted group finishes. Boards layer a small fx and unlock the next group's pads.","tier":"domain","payloadSchema":[{"name":"grp","type":"number","required":true}]},{"key":"PAD_SET_COMPLETED","id":"evt_DH083KRK999MMSVFZ83E0DZ9QE","name":"Pad Set Completed","description":"Every pad in the set is lit; fires once per run. Boards layer the treasure fx and spill the bonus reward.","tier":"domain"}],"transitions":[{"from":"active","to":"active","event":"INIT","eventId":"evt_GT40K216HYK8Z0YHV7CVTZY95W","effects":[["set","@entity.pads",["array/map","@config.pads",["fn","p",["object/merge","@p",{"lit":false}]]]],["set","@entity.groupsDone",[]],["set","@entity.currentGrp",0],["set","@entity.completed",false]]},{"from":"active","to":"active","event":"BODY_MOVED","eventId":"evt_GQS73J09QP4VVACYYM9WZZGF8J","guard":"@config.running","effects":[["let",[["grpIds",["array/reduce",["array/map",["array/filter","@entity.pads",["fn","p",[">",["object/get","@p","grp"],0]]],["fn","p",["object/get","@p","grp"]]],[],["fn",["acc","g"],["if",[">",["array/len",["array/filter","@acc",["fn","x",["==","@x","@g"]]]],0],"@acc",["array/append","@acc","@g"]]]]]],["let",[["openGrps",["array/filter","@grpIds",["fn","g",["<",["array/len",["array/filter","@entity.pads",["fn","p",["and",["==",["object/get","@p","grp"],"@g"],["==",["object/get","@p","lit"],true]]]]],["array/len",["array/filter","@entity.pads",["fn","p",["==",["object/get","@p","grp"],"@g"]]]]]]]]],["let",[["currentGrp",["array/reduce","@openGrps",9999,["fn",["acc","g"],["math/min","@acc","@g"]]]]],["let",[["newPads",["array/map","@entity.pads",["fn","p",["object/merge","@p",{"lit":["or",["object/get","@p","lit"],["and",["or",["==",["object/get","@p","grp"],0],["==",["object/get","@p","grp"],"@currentGrp"]],["and",["<=",["math/abs",["-","@payload.x",["object/get","@p","x"]]],"@config.reachX"],["<=",["math/abs",["-","@payload.y",["object/get","@p","y"]]],"@config.reachY"]]]]}]]]]],["let",[["doneNow",["array/filter","@grpIds",["fn","g",["==",["array/len",["array/filter","@newPads",["fn","p",["and",["==",["object/get","@p","grp"],"@g"],["==",["object/get","@p","lit"],true]]]]],["array/len",["array/filter","@newPads",["fn","p",["==",["object/get","@p","grp"],"@g"]]]]]]]]],["let",[["newlyGrp",["array/filter","@doneNow",["fn","g",["==",["array/len",["array/filter","@entity.groupsDone",["fn","d",["==","@d","@g"]]]],0]]]]],["do",["set","@entity.pads","@newPads"],["set","@entity.currentGrp",["if",["==","@currentGrp",9999],0,"@currentGrp"]],["if",[">",["array/len","@newlyGrp"],0],["do",["set","@entity.groupsDone","@doneNow"],["emit","PAD_GROUP_COMPLETED",{"grp":["array/first","@newlyGrp"]}]],null],["if",["and",["==","@entity.completed",false],["==",["array/len",["array/filter","@newPads",["fn","p",["==",["object/get","@p","lit"],false]]]],0]],["do",["set","@entity.completed",true],["emit","PAD_SET_COMPLETED",{}]],null]]]]]]]]]},{"from":"active","to":"active","event":"SET_PADS","eventId":"evt_QNE8ZDDJMESA78KK1NSHEYQDXR","effects":[["set","@entity.pads",["array/map","@payload.pads",["fn","p",["object/merge","@p",{"lit":false}]]]],["set","@entity.groupsDone",[]],["set","@entity.currentGrp",0],["set","@entity.completed",false]]},{"from":"active","to":"active","event":"RESTART","eventId":"evt_Z3B3N8J3VX1XYHRZE33NBCD8QC","effects":[["set","@entity.pads",["array/map","@entity.pads",["fn","p",["object/merge","@p",{"lit":false}]]]],["set","@entity.groupsDone",[]],["set","@entity.currentGrp",0],["set","@entity.completed",false]]}]},"config":{"reachY":{"type":"number","default":1.2,"label":"Reach Y","description":"Vertical tolerance (world units) around a pad's center when testing player contact (covers skating over the surface the pad sits on).","tier":"domain"},"pads":{"type":"[PadLock]","default":[],"label":"Pads","description":"One row per floor pad: id, center (x, y in world units), and grp (0 = ungrouped, always live; N = live only while it is the lowest uncompleted group). lit is stamped at runtime. Seeded onto the entity on INIT; the live set is entity.pads — SET_PADS replaces it at runtime (boards that import pads), and RESTART re-arms the live set rather than re-reading config, so injected pads survive respawns.","tier":"domain","items":{"type":"object","properties":{"grp":{"name":"grp","type":"number","required":true},"lit":{"name":"lit","type":"boolean","required":false},"x":{"name":"x","type":"number","required":true},"id":{"name":"id","type":"string","required":true},"y":{"name":"y","type":"number","required":true}}}},"reachX":{"type":"number","default":0.7,"label":"Reach X","description":"Horizontal tolerance (world units) around a pad's center when testing player contact (approximates the body's half-width plus a step).","tier":"domain"},"running":{"type":"boolean","default":true,"label":"Running","description":"When true, BODY_MOVED lights touched live pads and reports group/set completion; toggle to freeze every pad as-is.","tier":"domain"}},"scope":"instance"}],"pages":[{"name":"PadLockPage","id":"pag_SZ8RW2WENH7ARQ6H5PSC7WQRC0","path":"/pad-lock","traits":[{"ref":"PadLock","refId":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"}]}],"types":{"PadLock":[{"name":"id","type":"string","required":true},{"name":"x","type":"number","required":true},{"name":"y","type":"number","required":true},{"name":"grp","type":"number","required":true},{"name":"lit","type":"boolean"}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_9XQSR0W4K929MNJ2VP6SQJXAG6":{"id":"ent_9XQSR0W4K929MNJ2VP6SQJXAG6","kind":"entity","bakedName":"PadLockData","curName":"PadLockData","renames":[],"owner":"workspace"},"evt_DH083KRK999MMSVFZ83E0DZ9QE":{"id":"evt_DH083KRK999MMSVFZ83E0DZ9QE","kind":"event","bakedName":"PAD_SET_COMPLETED","curName":"PAD_SET_COMPLETED","renames":[],"owner":"workspace","parent":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"},"evt_GQS73J09QP4VVACYYM9WZZGF8J":{"id":"evt_GQS73J09QP4VVACYYM9WZZGF8J","kind":"event","bakedName":"BODY_MOVED","curName":"BODY_MOVED","renames":[],"owner":"workspace","parent":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"},"evt_GT40K216HYK8Z0YHV7CVTZY95W":{"id":"evt_GT40K216HYK8Z0YHV7CVTZY95W","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"},"evt_QNE8ZDDJMESA78KK1NSHEYQDXR":{"id":"evt_QNE8ZDDJMESA78KK1NSHEYQDXR","kind":"event","bakedName":"SET_PADS","curName":"SET_PADS","renames":[],"owner":"workspace","parent":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"},"evt_WG241MR30G1G829KQHE5PHAE3F":{"id":"evt_WG241MR30G1G829KQHE5PHAE3F","kind":"event","bakedName":"PAD_GROUP_COMPLETED","curName":"PAD_GROUP_COMPLETED","renames":[],"owner":"workspace","parent":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"},"evt_Z3B3N8J3VX1XYHRZE33NBCD8QC":{"id":"evt_Z3B3N8J3VX1XYHRZE33NBCD8QC","kind":"event","bakedName":"RESTART","curName":"RESTART","renames":[],"owner":"workspace","parent":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX"},"orb_X3FTTJNTRGXC88SXBC38N358JQ":{"id":"orb_X3FTTJNTRGXC88SXBC38N358JQ","kind":"orbital","bakedName":"PadLockOrbital","curName":"PadLockOrbital","renames":[],"owner":"workspace"},"pag_SZ8RW2WENH7ARQ6H5PSC7WQRC0":{"id":"pag_SZ8RW2WENH7ARQ6H5PSC7WQRC0","kind":"page","bakedName":"PadLockPage","curName":"PadLockPage","renames":[],"owner":"workspace"},"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX":{"id":"trt_45DJ2MWWVGEDR4QSX3JWF3FCKX","kind":"trait","bakedName":"PadLock","curName":"PadLock","renames":[],"owner":"workspace"}}}}
|