@almadar/std 16.203.0 → 16.204.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/ui/game/atoms/std-choice-gate.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/std-fx-narrative.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/std-fx-particles.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/std-game-design-sheet.lolo +69 -0
- package/behaviors/lolo/ui/game/atoms/std-gate-lock.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/std-lives.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/std-loop-lock.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/std-objective-flow.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/std-pad-lock.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/std-patrol-hazard.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/std-pickup.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/std-platformer-body.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/std-tutorial-overlay.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/std-velocity-gate.lolo +1 -1
- package/behaviors/registry/ui/game/atoms/std-choice-gate.orb +82 -2
- package/behaviors/registry/ui/game/atoms/std-fx-narrative.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-fx-particles.orb +82 -2
- package/behaviors/registry/ui/game/atoms/std-game-design-sheet.orb +527 -0
- package/behaviors/registry/ui/game/atoms/std-gate-lock.orb +48 -2
- package/behaviors/registry/ui/game/atoms/std-lives.orb +26 -2
- package/behaviors/registry/ui/game/atoms/std-loop-lock.orb +56 -2
- package/behaviors/registry/ui/game/atoms/std-objective-flow.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-pad-lock.orb +30 -2
- package/behaviors/registry/ui/game/atoms/std-patrol-hazard.orb +63 -2
- 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-tutorial-overlay.orb +24 -2
- package/behaviors/registry/ui/game/atoms/std-velocity-gate.orb +75 -2
- package/dist/behaviors/exports-reader.js +2552 -2508
- package/dist/behaviors/functions/index.d.ts +88 -14
- package/dist/behaviors/functions/index.js +2550 -2509
- package/dist/behaviors/index.d.ts +1 -1
- package/dist/behaviors/index.js +2553 -2509
- package/dist/behaviors/query.js +2552 -2508
- package/dist/behaviors-embeddings.hash.json +3 -3
- package/dist/behaviors-embeddings.json +29 -25
- package/dist/behaviors-registry.json +441 -17
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2553 -2509
- package/dist/knob-embeddings.hash.json +3 -3
- package/dist/knob-embeddings.json +1 -1
- package/dist/registry/factory-signatures.json +1 -1
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
app std-choice-gate "1.0.0"
|
|
2
|
-
"Headless choice-gate mechanic for side-view boards: a gate of N labeled option platforms where progress stops until the player commits to an answer. Listens BODY_MOVED and judges a gate when the player stands grounded on one of its option platforms (|dx| <= reachX of the option center, |dy| <= reachY of the gate's option plane — the pad-lock touch pattern): the correct option stamps the gate solved + chosen on the shared entity and emits CHOICE_CORRECT once (a solved gate never judges again, so the path stays open); a wrong option emits CHOICE_WRONG carrying the gate id, the chosen optionId, and the option's world position, so the board can bounce the player back and float the gate's hint (the board owns the bounce — the atom only reports). RESTART unsolves every gate. Renders nothing; boards draw the option platforms and labels from the shared entity (the render authority)."
|
|
2
|
+
"Headless choice-gate mechanic for side-view boards: a gate of N labeled option platforms where progress stops until the player commits to an answer. Listens BODY_MOVED and judges a gate when the player stands grounded on one of its option platforms (|dx| <= reachX of the option center, |dy| <= reachY of the gate's option plane — the pad-lock touch pattern): the correct option stamps the gate solved + chosen on the shared entity and emits CHOICE_CORRECT once (a solved gate never judges again, so the path stays open); a wrong option emits CHOICE_WRONG carrying the gate id, the chosen optionId, and the option's world position, so the board can bounce the player back and float the gate's hint (the board owns the bounce — the atom only reports). RESTART unsolves every gate. Renders nothing; boards draw the option platforms and labels from the shared entity (the render authority). Corresponds to the design-sheet field(s): challenge, agency."
|
|
3
3
|
orbital ChoiceGateOrbital {
|
|
4
4
|
type ChoiceOption = {
|
|
5
5
|
id : string!
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
app std-fx-narrative "1.0.0"
|
|
2
|
-
"Headless pedagogy→fx translator for game boards and learning shells: turns high-level narrative events into big transient screen-space or world-space text effects consumed by std-fx-particles / fx-overlay. Levels emit NARRATE { text, style } and get a correctly styled, centered (or positioned) floating text burst without hand-rolling particle structs. Tutorials emit TUTORIAL_SHOW and the atom forwards SHOW to a composed std-tutorial-overlay trait. Renders nothing; centralizes the FX vocabulary so every level's teaching text looks and behaves the same."
|
|
2
|
+
"Headless pedagogy→fx translator for game boards and learning shells: turns high-level narrative events into big transient screen-space or world-space text effects consumed by std-fx-particles / fx-overlay. Levels emit NARRATE { text, style } and get a correctly styled, centered (or positioned) floating text burst without hand-rolling particle structs. Tutorials emit TUTORIAL_SHOW and the atom forwards SHOW to a composed std-tutorial-overlay trait. Renders nothing; centralizes the FX vocabulary so every level's teaching text looks and behaves the same. Corresponds to the design-sheet field(s): feedback."
|
|
3
3
|
|
|
4
4
|
orbital FxNarrativeOrbital {
|
|
5
5
|
type NarrativeCue = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
app std-fx-particles "1.1.0"
|
|
2
|
-
"Headless transient-fx mechanic serving BOTH game boards and learning shells: appends spawned particles on BURST — stamping maxTtl (fade envelope) and bornAt (epoch ms, smooth render interpolation) when absent — decays each entry's ttl every tick, drops the dead ones, and clears on RESTART. Name-blind mechanism: the effect-kind vocabulary is consumer-declared (FxPreset tables at the render call sites). Composed onto a [runtime, shared] entity; renders nothing — the board/shell owns the single render authority (draw-fx-layer for space \"world\", fx-overlay for space \"screen\")."
|
|
2
|
+
"Headless transient-fx mechanic serving BOTH game boards and learning shells: appends spawned particles on BURST — stamping maxTtl (fade envelope) and bornAt (epoch ms, smooth render interpolation) when absent — decays each entry's ttl every tick, drops the dead ones, and clears on RESTART. Name-blind mechanism: the effect-kind vocabulary is consumer-declared (FxPreset tables at the render call sites). Composed onto a [runtime, shared] entity; renders nothing — the board/shell owns the single render authority (draw-fx-layer for space \"world\", fx-overlay for space \"screen\"). Corresponds to the design-sheet field(s): feedback, rewards."
|
|
3
3
|
orbital FxParticlesOrbital {
|
|
4
4
|
type Fx = {
|
|
5
5
|
id : string!
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
app std-game-design-sheet "1.0.0"
|
|
2
|
+
"Headless game-design metadata authority: every game or level in the std library MUST compose this atom and fill its design sheet before declaring mechanics. The sheet forces the author to state the core loop, challenge, goals, feedback, agency, mechanics, dynamics, engagement drivers, and rewards. The atom owns no rendering and no rules; it is the single source of truth for intent metadata. Domain-specific extensions (e.g., math target or grade level for an educational game) live in the consuming package, not here. Future game atoms (platformer-body, objective-flow, fx-narrative, pickup, gate-lock, etc.) correspond to fields here, and level organisms bind those atoms together while declaring how each field is realized."
|
|
3
|
+
|
|
4
|
+
orbital GameDesignSheetOrbital {
|
|
5
|
+
type GameDesign = {
|
|
6
|
+
coreLoop : string!
|
|
7
|
+
challenge : string!
|
|
8
|
+
goals : [string]!
|
|
9
|
+
feedback : string!
|
|
10
|
+
agency : string!
|
|
11
|
+
mechanics : [string]!
|
|
12
|
+
dynamics : [string]!
|
|
13
|
+
engagement : [string]!
|
|
14
|
+
rewards : [string]!
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
entity GameDesignState [runtime, shared] {
|
|
18
|
+
id : string!
|
|
19
|
+
design : GameDesign = {}
|
|
20
|
+
declared : boolean = false
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
trait GameDesignSheet -> @rebindable GameDesignState [lifecycle] {
|
|
24
|
+
initial: active
|
|
25
|
+
|
|
26
|
+
state active {
|
|
27
|
+
INIT -> active
|
|
28
|
+
(set @entity.design @config.design)
|
|
29
|
+
(set @entity.declared true)
|
|
30
|
+
(emit DESIGN_DECLARED { design: @entity.design })
|
|
31
|
+
|
|
32
|
+
RESTART -> active
|
|
33
|
+
(set @entity.design @config.design)
|
|
34
|
+
(set @entity.declared true)
|
|
35
|
+
(emit DESIGN_DECLARED { design: @entity.design })
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
emits {
|
|
39
|
+
DESIGN_DECLARED -> external {
|
|
40
|
+
design : GameDesign!
|
|
41
|
+
}
|
|
42
|
+
@description "The compiled game-design sheet is emitted once on INIT and again on RESTART so organism-level authorities, analytics, or tutorial overlays can react to it."
|
|
43
|
+
@tier "domain"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
listens {
|
|
47
|
+
RESTART { id : string }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
config {
|
|
51
|
+
design : GameDesign = {
|
|
52
|
+
coreLoop: "",
|
|
53
|
+
challenge: "",
|
|
54
|
+
goals: [],
|
|
55
|
+
feedback: "",
|
|
56
|
+
agency: "",
|
|
57
|
+
mechanics: [],
|
|
58
|
+
dynamics: [],
|
|
59
|
+
engagement: [],
|
|
60
|
+
rewards: []
|
|
61
|
+
}
|
|
62
|
+
@label "Design Sheet"
|
|
63
|
+
@description "Required game-design metadata. All string/array fields must be non-empty for a finished level; empty defaults fail validation until the author fills them in."
|
|
64
|
+
@tier "domain"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
page "/game-design-sheet" as GameDesignSheetPage -> GameDesignSheet
|
|
69
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
app std-gate-lock "1.0.0"
|
|
2
|
-
"Headless collectible-gate mechanic: doors that stay shut until the player's collected total reaches their cost. Listens COLLECT (the board's running total — stars, coins, keys) and flips every door whose cost is met, stamping open on the shared door rows and emitting GATE_OPENED for the first newly opened door (the shared entity is the render authority for the rest). While a closed door's rect contains the player it emits GATE_BLOCKED once per approach — re-arming only after the player steps out — so the board can answer with a PLACE back and a locked fx. RESTART re-locks every door and zeroes the total. Renders nothing; boards draw closed doors as bars/walls and open ones as gaps."
|
|
2
|
+
"Headless collectible-gate mechanic: doors that stay shut until the player's collected total reaches their cost. Listens COLLECT (the board's running total — stars, coins, keys) and flips every door whose cost is met, stamping open on the shared door rows and emitting GATE_OPENED for the first newly opened door (the shared entity is the render authority for the rest). While a closed door's rect contains the player it emits GATE_BLOCKED once per approach — re-arming only after the player steps out — so the board can answer with a PLACE back and a locked fx. RESTART re-locks every door and zeroes the total. Renders nothing; boards draw closed doors as bars/walls and open ones as gaps. Corresponds to the design-sheet field(s): challenge, rewards."
|
|
3
3
|
orbital GateLockOrbital {
|
|
4
4
|
type Door = {
|
|
5
5
|
id : string!
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
app std-lives "1.0.0"
|
|
2
|
-
"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."
|
|
2
|
+
"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."
|
|
3
3
|
orbital LivesOrbital {
|
|
4
4
|
type Checkpoint = {
|
|
5
5
|
id : string!
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
app std-loop-lock "1.0.0"
|
|
2
|
-
"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 lock. Renders nothing; boards draw the ring/chest and read swept from the shared entity (the render authority)."
|
|
2
|
+
"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 lock. 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."
|
|
3
3
|
orbital LoopLockOrbital {
|
|
4
4
|
type LoopLock = {
|
|
5
5
|
id : string!
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
app std-objective-flow "1.0.0"
|
|
2
|
-
"Headless win/lose authority for objective boards: owns only result. Listens PROGRESS (objectivesLeft + movesLeft) and sets result to won when every objective is reached, lost when the move budget runs out first, else none. Renders nothing."
|
|
2
|
+
"Headless win/lose authority for objective boards: owns only result. Listens PROGRESS (objectivesLeft + movesLeft) and sets result to won when every objective is reached, lost when the move budget runs out first, else none. Renders nothing. Corresponds to the design-sheet field(s): goals, feedback."
|
|
3
3
|
orbital ObjectiveFlowOrbital {
|
|
4
4
|
entity FlowState [runtime, shared] {
|
|
5
5
|
id : string!
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
app std-pad-lock "1.0.0"
|
|
2
|
-
"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 pad and resets the set. Renders nothing; boards draw the pads and read lit from the shared entity (the render authority)."
|
|
2
|
+
"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 pad and resets the set. 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."
|
|
3
3
|
orbital PadLockOrbital {
|
|
4
4
|
type PadLock = {
|
|
5
5
|
id : string!
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
app std-patrol-hazard "1.0.0"
|
|
2
|
-
"Headless patrol-hazard mechanic for side-view boards: moves each configured patrol back and forth along its [x0, x1] beat at its own speed (33ms tick, ping-pong with clamped turnarounds; a patrol declaring waveAmp/wavePeriod also bobs vertically — cy = y + waveAmp·sin(2πt/wavePeriod from a per-row time accumulator — and the hit test and render read cy, so a waveAmp of 0 keeps the flat beat), tracks the player position off the body authority's BODY_MOVED, and emits PATROL_HIT once per contact — a per-patrol hit flag re-arms only after the player separates, so damage rules stay sparse (when two patrols connect on the same tick the first reports; the other reports on the next tick). Patrols live on a [runtime, shared] entity for the render layer (boards draw them as markers/sprites); damage, lives, and respawn stay downstream (std-lives) — this atom simulates, it never judges. Renders nothing."
|
|
2
|
+
"Headless patrol-hazard mechanic for side-view boards: moves each configured patrol back and forth along its [x0, x1] beat at its own speed (33ms tick, ping-pong with clamped turnarounds; a patrol declaring waveAmp/wavePeriod also bobs vertically — cy = y + waveAmp·sin(2πt/wavePeriod from a per-row time accumulator — and the hit test and render read cy, so a waveAmp of 0 keeps the flat beat), tracks the player position off the body authority's BODY_MOVED, and emits PATROL_HIT once per contact — a per-patrol hit flag re-arms only after the player separates, so damage rules stay sparse (when two patrols connect on the same tick the first reports; the other reports on the next tick). Patrols live on a [runtime, shared] entity for the render layer (boards draw them as markers/sprites); damage, lives, and respawn stay downstream (std-lives) — this atom simulates, it never judges. Renders nothing. Corresponds to the design-sheet field(s): challenge, dynamics."
|
|
3
3
|
orbital PatrolHazardOrbital {
|
|
4
4
|
type Patrol = {
|
|
5
5
|
id : string!
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
app std-pickup "1.0.0"
|
|
2
|
-
"Headless side-view collectible authority — the platformer twin of grid std-gather. Listens BODY_MOVED and, when the player touches an uncollected feature (|dx| <= reachX, |dy| <= reachY of the feature center — the coef-pad touch idiom minus the grounded requirement, so airborne pickups work), stamps it collected on the shared entity and emits PICKED once per item (id, kind, position, glyph, message) plus COLLECT{total} with the running count (the event std-gate-lock already consumes). When every feature is collected it emits PICKUP_SET_COMPLETED once. RESTART re-arms every feature and zeroes the count. kind is board-defined vocabulary (star, boost, …) — this atom reports, boards judge. Renders nothing; boards draw the features and read collected from the shared entity."
|
|
2
|
+
"Headless side-view collectible authority — the platformer twin of grid std-gather. Listens BODY_MOVED and, when the player touches an uncollected feature (|dx| <= reachX, |dy| <= reachY of the feature center — the coef-pad touch idiom minus the grounded requirement, so airborne pickups work), stamps it collected on the shared entity and emits PICKED once per item (id, kind, position, glyph, message) plus COLLECT{total} with the running count (the event std-gate-lock already consumes). When every feature is collected it emits PICKUP_SET_COMPLETED once. RESTART re-arms every feature and zeroes the count. kind is board-defined vocabulary (star, boost, …) — this atom reports, boards judge. Renders nothing; boards draw the features and read collected from the shared entity. Corresponds to the design-sheet field(s): rewards."
|
|
3
3
|
orbital PickupOrbital {
|
|
4
4
|
type PickupFeature = {
|
|
5
5
|
id : string!
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
app std-platformer-body "1.0.0"
|
|
2
|
-
"Headless run/jump platformer-physics authority: the SOLE writer of body + fell + hazardId + goalId on side-view boards. Where std-motion-body owns free 2D drift (no collision), this atom owns the platformer contract: every 33ms physics tick it integrates gravity into the body's vertical velocity, steps position in per-second units, and collides the body rect against the config platforms with one-way semantics — a body moving in the gravity direction that overlaps a ground/platform tile lands on its anti-gravity face (vy zeroed, grounded set), while a body moving against gravity passes through, so jumping up through a platform and walking up a staircase both just work. The sign of gravity IS the vertical convention: positive pulls toward +y (screen boards, y down — sprite canvases), negative toward −y (math canvases, y up); jumps always fire against it. Intents: STEER sets horizontal velocity (dir −1/0/1 × moveSpeed, hold-to-run: keydown steers, keyup steers 0), JUMP kicks vertical velocity when grounded, PLACE teleports (spawns, hazard respawns), RESTART reseeds. Emits BODY_MOVED every tick for the render layer (boards that don't subscribe pay nothing), plus the sparse rule signals a board needs to score: BODY_JUMPED, BODY_LANDED (with impact speed), BODY_HAZARD (once per hazard entry, re-arms on exit), BODY_GOAL (same arming), BODY_FELL (once per fall past killY, re-armed by PLACE/RESTART). Drift regions: config.driftRegions lists axis-aligned rects each carrying a constant acceleration (ax, ay) applied with the same 0.033s dt whenever the body's center is inside (empty list = zero behavior change). Curve skating: when config.skate is on and the grounded body comes within skateSnap of the config.skateCurve surface, the body rides the curve — y snaps to the interpolated surface and tangential gravity (g·slope/(1+slope²)) accelerates vx, and the vertical velocity is the tangential projection (s = vx·cos θ, vy = s·sin θ — no discontinuous jumps at sample boundaries), so the body slides downhill along the graph itself and launches ballistically off its ends; jumping kicks free. Sparse BODY_SKATE_START/BODY_SKATE_END signals fire on engage/disengage so boards can layer fx. Lives, score, and win/lose stay downstream — this atom simulates, it never judges. Renders nothing."
|
|
2
|
+
"Headless run/jump platformer-physics authority: the SOLE writer of body + fell + hazardId + goalId on side-view boards. Where std-motion-body owns free 2D drift (no collision), this atom owns the platformer contract: every 33ms physics tick it integrates gravity into the body's vertical velocity, steps position in per-second units, and collides the body rect against the config platforms with one-way semantics — a body moving in the gravity direction that overlaps a ground/platform tile lands on its anti-gravity face (vy zeroed, grounded set), while a body moving against gravity passes through, so jumping up through a platform and walking up a staircase both just work. The sign of gravity IS the vertical convention: positive pulls toward +y (screen boards, y down — sprite canvases), negative toward −y (math canvases, y up); jumps always fire against it. Intents: STEER sets horizontal velocity (dir −1/0/1 × moveSpeed, hold-to-run: keydown steers, keyup steers 0), JUMP kicks vertical velocity when grounded, PLACE teleports (spawns, hazard respawns), RESTART reseeds. Emits BODY_MOVED every tick for the render layer (boards that don't subscribe pay nothing), plus the sparse rule signals a board needs to score: BODY_JUMPED, BODY_LANDED (with impact speed), BODY_HAZARD (once per hazard entry, re-arms on exit), BODY_GOAL (same arming), BODY_FELL (once per fall past killY, re-armed by PLACE/RESTART). Drift regions: config.driftRegions lists axis-aligned rects each carrying a constant acceleration (ax, ay) applied with the same 0.033s dt whenever the body's center is inside (empty list = zero behavior change). Curve skating: when config.skate is on and the grounded body comes within skateSnap of the config.skateCurve surface, the body rides the curve — y snaps to the interpolated surface and tangential gravity (g·slope/(1+slope²)) accelerates vx, and the vertical velocity is the tangential projection (s = vx·cos θ, vy = s·sin θ — no discontinuous jumps at sample boundaries), so the body slides downhill along the graph itself and launches ballistically off its ends; jumping kicks free. Sparse BODY_SKATE_START/BODY_SKATE_END signals fire on engage/disengage so boards can layer fx. Lives, score, and win/lose stay downstream — this atom simulates, it never judges. Renders nothing. Corresponds to the design-sheet field(s): mechanics, dynamics."
|
|
3
3
|
orbital PlatformerBodyOrbital {
|
|
4
4
|
type PlatformerBody = {
|
|
5
5
|
x : number!
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
app std-tutorial-overlay "1.0.0"
|
|
2
|
-
"Tutorial modal with live-demo steps for game boards and learning shells: a paged overlay — title, a live previewTrait frame playing the mechanic via std-tutorial-autodemo (a bare game canvas, no shell chrome), one line of body copy, a step counter, and Back / Next / Skip — composed entirely from registered render types (stack + text + button + trait frame) into the overlay slot, so no new UI component is needed. autoShow opens it on INIT for first-time players; a board's help button re-opens it any time via SHOW (which rewinds to step one). DISMISS (or finishing the last step) marks the run done, clears the overlay, and emits TUTORIAL_DONE so the board can unpause or log. Steps are pure config — a board teaches a new mechanic by adding one { id, title, body, demoId } row plus a previewTrait binding."
|
|
2
|
+
"Tutorial modal with live-demo steps for game boards and learning shells: a paged overlay — title, a live previewTrait frame playing the mechanic via std-tutorial-autodemo (a bare game canvas, no shell chrome), one line of body copy, a step counter, and Back / Next / Skip — composed entirely from registered render types (stack + text + button + trait frame) into the overlay slot, so no new UI component is needed. autoShow opens it on INIT for first-time players; a board's help button re-opens it any time via SHOW (which rewinds to step one). DISMISS (or finishing the last step) marks the run done, clears the overlay, and emits TUTORIAL_DONE so the board can unpause or log. Steps are pure config — a board teaches a new mechanic by adding one { id, title, body, demoId } row plus a previewTrait binding. Corresponds to the design-sheet field(s): feedback, agency."
|
|
3
3
|
orbital TutorialOverlayOrbital {
|
|
4
4
|
type TutorialStep = {
|
|
5
5
|
id : string!
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
app std-velocity-gate "1.0.0"
|
|
2
|
-
"Headless velocity-gate mechanic: gates that open only when the player crosses them inside a speed band, optionally in a required direction, optionally sustained for a dwell. Listens BODY_MOVED and, per closed gate, tests the player's rect (padded by reachMargin), their speed against [minSpeed, maxSpeed], and their horizontal direction against dir (0 = either). Instant gates (dwellMs 0) open on the first passing cross; dwell gates (dwellMs > 0) accumulate ~33ms per passing move and open once held reaches dwellMs — a failing move resets the hold. The first newly opened gate emits VELOCITY_GATE_OPENED (the shared entity carries the rest). Entering a closed INSTANT gate while NOT passing emits VELOCITY_GATE_DENIED once per approach — re-arming only after the player steps out — so the board can answer with a PLACE back and a hint fx; dwell gates never deny (a hot entry is fine — coming to rest inside is the point), a failed hold simply resets. RESTART re-closes every gate. Renders nothing; boards draw the gate band/chest and read open/held from the shared entity (the render authority)."
|
|
2
|
+
"Headless velocity-gate mechanic: gates that open only when the player crosses them inside a speed band, optionally in a required direction, optionally sustained for a dwell. Listens BODY_MOVED and, per closed gate, tests the player's rect (padded by reachMargin), their speed against [minSpeed, maxSpeed], and their horizontal direction against dir (0 = either). Instant gates (dwellMs 0) open on the first passing cross; dwell gates (dwellMs > 0) accumulate ~33ms per passing move and open once held reaches dwellMs — a failing move resets the hold. The first newly opened gate emits VELOCITY_GATE_OPENED (the shared entity carries the rest). Entering a closed INSTANT gate while NOT passing emits VELOCITY_GATE_DENIED once per approach — re-arming only after the player steps out — so the board can answer with a PLACE back and a hint fx; dwell gates never deny (a hot entry is fine — coming to rest inside is the point), a failed hold simply resets. RESTART re-closes every gate. Renders nothing; boards draw the gate band/chest and read open/held from the shared entity (the render authority). Corresponds to the design-sheet field(s): challenge, mechanics."
|
|
3
3
|
orbital VelocityGateOrbital {
|
|
4
4
|
type VelocityGate = {
|
|
5
5
|
id : string!
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "Headless choice-gate mechanic for side-view boards: a gate of N labeled option platforms where progress stops until the player commits to an answer. Listens BODY_MOVED and judges a gate when the player stands grounded on one of its option platforms (|dx| <= reachX of the option center, |dy| <= reachY of the gate's option plane — the pad-lock touch pattern): the correct option stamps the gate solved + chosen on the shared entity and emits CHOICE_CORRECT once (a solved gate never judges again, so the path stays open); a wrong option emits CHOICE_WRONG carrying the gate id, the chosen optionId, and the option's world position, so the board can bounce the player back and float the gate's hint (the board owns the bounce — the atom only reports). RESTART unsolves every gate. Renders nothing; boards draw the option platforms and labels from the shared entity (the render authority).",
|
|
2
|
+
"description": "Headless choice-gate mechanic for side-view boards: a gate of N labeled option platforms where progress stops until the player commits to an answer. Listens BODY_MOVED and judges a gate when the player stands grounded on one of its option platforms (|dx| <= reachX of the option center, |dy| <= reachY of the gate's option plane — the pad-lock touch pattern): the correct option stamps the gate solved + chosen on the shared entity and emits CHOICE_CORRECT once (a solved gate never judges again, so the path stays open); a wrong option emits CHOICE_WRONG carrying the gate id, the chosen optionId, and the option's world position, so the board can bounce the player back and float the gate's hint (the board owns the bounce — the atom only reports). RESTART unsolves every gate. Renders nothing; boards draw the option platforms and labels from the shared entity (the render authority). Corresponds to the design-sheet field(s): challenge, agency.",
|
|
3
3
|
"ledger": {
|
|
4
4
|
"entries": {
|
|
5
5
|
"ent_01M144Y1KF1D8W68N3195C53AC": {
|
|
@@ -847,7 +847,87 @@
|
|
|
847
847
|
]
|
|
848
848
|
}
|
|
849
849
|
}
|
|
850
|
-
]
|
|
850
|
+
],
|
|
851
|
+
"types": {
|
|
852
|
+
"ChoiceGate": [
|
|
853
|
+
{
|
|
854
|
+
"name": "id",
|
|
855
|
+
"required": true,
|
|
856
|
+
"type": "string"
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
"name": "x",
|
|
860
|
+
"required": true,
|
|
861
|
+
"type": "number"
|
|
862
|
+
},
|
|
863
|
+
{
|
|
864
|
+
"name": "y",
|
|
865
|
+
"required": true,
|
|
866
|
+
"type": "number"
|
|
867
|
+
},
|
|
868
|
+
{
|
|
869
|
+
"name": "hint",
|
|
870
|
+
"type": "string"
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
"name": "options",
|
|
874
|
+
"properties": [
|
|
875
|
+
{
|
|
876
|
+
"name": "id",
|
|
877
|
+
"required": true,
|
|
878
|
+
"type": "string"
|
|
879
|
+
},
|
|
880
|
+
{
|
|
881
|
+
"name": "dx",
|
|
882
|
+
"required": true,
|
|
883
|
+
"type": "number"
|
|
884
|
+
},
|
|
885
|
+
{
|
|
886
|
+
"name": "label",
|
|
887
|
+
"required": true,
|
|
888
|
+
"type": "string"
|
|
889
|
+
},
|
|
890
|
+
{
|
|
891
|
+
"name": "correct",
|
|
892
|
+
"required": true,
|
|
893
|
+
"type": "boolean"
|
|
894
|
+
}
|
|
895
|
+
],
|
|
896
|
+
"required": true,
|
|
897
|
+
"type": "[object]"
|
|
898
|
+
},
|
|
899
|
+
{
|
|
900
|
+
"name": "solved",
|
|
901
|
+
"type": "boolean"
|
|
902
|
+
},
|
|
903
|
+
{
|
|
904
|
+
"name": "chosen",
|
|
905
|
+
"type": "string"
|
|
906
|
+
}
|
|
907
|
+
],
|
|
908
|
+
"ChoiceOption": [
|
|
909
|
+
{
|
|
910
|
+
"name": "id",
|
|
911
|
+
"required": true,
|
|
912
|
+
"type": "string"
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
"name": "dx",
|
|
916
|
+
"required": true,
|
|
917
|
+
"type": "number"
|
|
918
|
+
},
|
|
919
|
+
{
|
|
920
|
+
"name": "label",
|
|
921
|
+
"required": true,
|
|
922
|
+
"type": "string"
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
"name": "correct",
|
|
926
|
+
"required": true,
|
|
927
|
+
"type": "boolean"
|
|
928
|
+
}
|
|
929
|
+
]
|
|
930
|
+
}
|
|
851
931
|
}
|
|
852
932
|
],
|
|
853
933
|
"schemaVersion": 1,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "Headless pedagogy→fx translator for game boards and learning shells: turns high-level narrative events into big transient screen-space or world-space text effects consumed by std-fx-particles / fx-overlay. Levels emit NARRATE { text, style } and get a correctly styled, centered (or positioned) floating text burst without hand-rolling particle structs. Tutorials emit TUTORIAL_SHOW and the atom forwards SHOW to a composed std-tutorial-overlay trait. Renders nothing; centralizes the FX vocabulary so every level's teaching text looks and behaves the same.",
|
|
2
|
+
"description": "Headless pedagogy→fx translator for game boards and learning shells: turns high-level narrative events into big transient screen-space or world-space text effects consumed by std-fx-particles / fx-overlay. Levels emit NARRATE { text, style } and get a correctly styled, centered (or positioned) floating text burst without hand-rolling particle structs. Tutorials emit TUTORIAL_SHOW and the atom forwards SHOW to a composed std-tutorial-overlay trait. Renders nothing; centralizes the FX vocabulary so every level's teaching text looks and behaves the same. Corresponds to the design-sheet field(s): feedback.",
|
|
3
3
|
"ledger": {
|
|
4
4
|
"entries": {
|
|
5
5
|
"ent_01M1GXD11PARSZADDZ8Y7G9B7Q": {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "Headless transient-fx mechanic serving BOTH game boards and learning shells: appends spawned particles on BURST — stamping maxTtl (fade envelope) and bornAt (epoch ms, smooth render interpolation) when absent — decays each entry's ttl every tick, drops the dead ones, and clears on RESTART. Name-blind mechanism: the effect-kind vocabulary is consumer-declared (FxPreset tables at the render call sites). Composed onto a [runtime, shared] entity; renders nothing — the board/shell owns the single render authority (draw-fx-layer for space \"world\", fx-overlay for space \"screen\").",
|
|
2
|
+
"description": "Headless transient-fx mechanic serving BOTH game boards and learning shells: appends spawned particles on BURST — stamping maxTtl (fade envelope) and bornAt (epoch ms, smooth render interpolation) when absent — decays each entry's ttl every tick, drops the dead ones, and clears on RESTART. Name-blind mechanism: the effect-kind vocabulary is consumer-declared (FxPreset tables at the render call sites). Composed onto a [runtime, shared] entity; renders nothing — the board/shell owns the single render authority (draw-fx-layer for space \"world\", fx-overlay for space \"screen\"). Corresponds to the design-sheet field(s): feedback, rewards.",
|
|
3
3
|
"ledger": {
|
|
4
4
|
"entries": {
|
|
5
5
|
"ent_01KXG04TFZP9QXE9KF516SP9KC": {
|
|
@@ -643,7 +643,87 @@
|
|
|
643
643
|
}
|
|
644
644
|
]
|
|
645
645
|
}
|
|
646
|
-
]
|
|
646
|
+
],
|
|
647
|
+
"types": {
|
|
648
|
+
"Fx": [
|
|
649
|
+
{
|
|
650
|
+
"name": "id",
|
|
651
|
+
"required": true,
|
|
652
|
+
"type": "string"
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
"name": "type",
|
|
656
|
+
"required": true,
|
|
657
|
+
"type": "string"
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
"name": "x",
|
|
661
|
+
"required": true,
|
|
662
|
+
"type": "number"
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
"name": "z",
|
|
666
|
+
"type": "number"
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
"name": "y",
|
|
670
|
+
"type": "number"
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
"name": "message",
|
|
674
|
+
"type": "string"
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
"name": "ttl",
|
|
678
|
+
"required": true,
|
|
679
|
+
"type": "number"
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
"name": "maxTtl",
|
|
683
|
+
"type": "number"
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
"name": "bornAt",
|
|
687
|
+
"type": "number"
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
"name": "space",
|
|
691
|
+
"type": "string"
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
"name": "effect",
|
|
695
|
+
"type": "string"
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
"name": "color",
|
|
699
|
+
"type": "string"
|
|
700
|
+
},
|
|
701
|
+
{
|
|
702
|
+
"name": "size",
|
|
703
|
+
"type": "number"
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
"name": "vx",
|
|
707
|
+
"type": "number"
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
"name": "vy",
|
|
711
|
+
"type": "number"
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
"name": "vz",
|
|
715
|
+
"type": "number"
|
|
716
|
+
},
|
|
717
|
+
{
|
|
718
|
+
"name": "particleCount",
|
|
719
|
+
"type": "number"
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
"name": "animation",
|
|
723
|
+
"type": "string"
|
|
724
|
+
}
|
|
725
|
+
]
|
|
726
|
+
}
|
|
647
727
|
}
|
|
648
728
|
],
|
|
649
729
|
"schemaVersion": 1,
|