@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
|
{
|
|
2
|
-
"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 lock. Renders nothing; boards draw the ring/chest and read swept from the shared entity (the render authority).",
|
|
2
|
+
"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 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
|
"ledger": {
|
|
4
4
|
"entries": {
|
|
5
5
|
"ent_01M119MVXMDX7KPCDQRRYHABX8": {
|
|
@@ -777,7 +777,61 @@
|
|
|
777
777
|
]
|
|
778
778
|
}
|
|
779
779
|
}
|
|
780
|
-
]
|
|
780
|
+
],
|
|
781
|
+
"types": {
|
|
782
|
+
"LoopLock": [
|
|
783
|
+
{
|
|
784
|
+
"name": "id",
|
|
785
|
+
"required": true,
|
|
786
|
+
"type": "string"
|
|
787
|
+
},
|
|
788
|
+
{
|
|
789
|
+
"name": "x",
|
|
790
|
+
"required": true,
|
|
791
|
+
"type": "number"
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
"name": "y",
|
|
795
|
+
"required": true,
|
|
796
|
+
"type": "number"
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
"name": "radius",
|
|
800
|
+
"required": true,
|
|
801
|
+
"type": "number"
|
|
802
|
+
},
|
|
803
|
+
{
|
|
804
|
+
"name": "band",
|
|
805
|
+
"required": true,
|
|
806
|
+
"type": "number"
|
|
807
|
+
},
|
|
808
|
+
{
|
|
809
|
+
"name": "turns",
|
|
810
|
+
"required": true,
|
|
811
|
+
"type": "number"
|
|
812
|
+
},
|
|
813
|
+
{
|
|
814
|
+
"name": "swept",
|
|
815
|
+
"type": "number"
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
"name": "lastAngle",
|
|
819
|
+
"type": "number"
|
|
820
|
+
},
|
|
821
|
+
{
|
|
822
|
+
"name": "inside",
|
|
823
|
+
"type": "boolean"
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
"name": "unlocked",
|
|
827
|
+
"type": "boolean"
|
|
828
|
+
},
|
|
829
|
+
{
|
|
830
|
+
"name": "reported",
|
|
831
|
+
"type": "boolean"
|
|
832
|
+
}
|
|
833
|
+
]
|
|
834
|
+
}
|
|
781
835
|
}
|
|
782
836
|
],
|
|
783
837
|
"schemaVersion": 1,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "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
|
+
"description": "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
|
"ledger": {
|
|
4
4
|
"entries": {
|
|
5
5
|
"ent_01KXG04TKBJ5BFB1E634XZRG5Z": {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"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 pad and resets the set. Renders nothing; boards draw the pads and read lit from the shared entity (the render authority).",
|
|
2
|
+
"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 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
|
"ledger": {
|
|
4
4
|
"entries": {
|
|
5
5
|
"ent_01M11SKWZK3WVGRB0CXK5XDRD1": {
|
|
@@ -925,7 +925,35 @@
|
|
|
925
925
|
]
|
|
926
926
|
}
|
|
927
927
|
}
|
|
928
|
-
]
|
|
928
|
+
],
|
|
929
|
+
"types": {
|
|
930
|
+
"PadLock": [
|
|
931
|
+
{
|
|
932
|
+
"name": "id",
|
|
933
|
+
"required": true,
|
|
934
|
+
"type": "string"
|
|
935
|
+
},
|
|
936
|
+
{
|
|
937
|
+
"name": "x",
|
|
938
|
+
"required": true,
|
|
939
|
+
"type": "number"
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
"name": "y",
|
|
943
|
+
"required": true,
|
|
944
|
+
"type": "number"
|
|
945
|
+
},
|
|
946
|
+
{
|
|
947
|
+
"name": "grp",
|
|
948
|
+
"required": true,
|
|
949
|
+
"type": "number"
|
|
950
|
+
},
|
|
951
|
+
{
|
|
952
|
+
"name": "lit",
|
|
953
|
+
"type": "boolean"
|
|
954
|
+
}
|
|
955
|
+
]
|
|
956
|
+
}
|
|
929
957
|
}
|
|
930
958
|
],
|
|
931
959
|
"schemaVersion": 1,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "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
|
+
"description": "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
|
"ledger": {
|
|
4
4
|
"entries": {
|
|
5
5
|
"ent_01M0PCAKKXX0TFABTMPC8BNH64": {
|
|
@@ -906,7 +906,68 @@
|
|
|
906
906
|
}
|
|
907
907
|
]
|
|
908
908
|
}
|
|
909
|
-
]
|
|
909
|
+
],
|
|
910
|
+
"types": {
|
|
911
|
+
"Patrol": [
|
|
912
|
+
{
|
|
913
|
+
"name": "id",
|
|
914
|
+
"required": true,
|
|
915
|
+
"type": "string"
|
|
916
|
+
},
|
|
917
|
+
{
|
|
918
|
+
"name": "x0",
|
|
919
|
+
"required": true,
|
|
920
|
+
"type": "number"
|
|
921
|
+
},
|
|
922
|
+
{
|
|
923
|
+
"name": "x1",
|
|
924
|
+
"required": true,
|
|
925
|
+
"type": "number"
|
|
926
|
+
},
|
|
927
|
+
{
|
|
928
|
+
"name": "y",
|
|
929
|
+
"required": true,
|
|
930
|
+
"type": "number"
|
|
931
|
+
},
|
|
932
|
+
{
|
|
933
|
+
"name": "speed",
|
|
934
|
+
"required": true,
|
|
935
|
+
"type": "number"
|
|
936
|
+
},
|
|
937
|
+
{
|
|
938
|
+
"name": "waveAmp",
|
|
939
|
+
"type": "number"
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
"name": "wavePeriod",
|
|
943
|
+
"type": "number"
|
|
944
|
+
},
|
|
945
|
+
{
|
|
946
|
+
"name": "x",
|
|
947
|
+
"type": "number"
|
|
948
|
+
},
|
|
949
|
+
{
|
|
950
|
+
"name": "dir",
|
|
951
|
+
"type": "number"
|
|
952
|
+
},
|
|
953
|
+
{
|
|
954
|
+
"name": "t",
|
|
955
|
+
"type": "number"
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
"name": "cy",
|
|
959
|
+
"type": "number"
|
|
960
|
+
},
|
|
961
|
+
{
|
|
962
|
+
"name": "touching",
|
|
963
|
+
"type": "boolean"
|
|
964
|
+
},
|
|
965
|
+
{
|
|
966
|
+
"name": "hit",
|
|
967
|
+
"type": "boolean"
|
|
968
|
+
}
|
|
969
|
+
]
|
|
970
|
+
}
|
|
910
971
|
}
|
|
911
972
|
],
|
|
912
973
|
"schemaVersion": 1,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "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
|
+
"description": "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
|
"ledger": {
|
|
4
4
|
"entries": {
|
|
5
5
|
"ent_01M1GJ1RVVTJT76K1YZHQJGRG1": {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "Headless run/jump platformer-physics authority: the SOLE writer of body + fell + hazardId + goalId on side-view boards. Where std-motion-body owns free 2D drift (no collision), this atom owns the platformer contract: every 33ms physics tick it integrates gravity into the body's vertical velocity, steps position in per-second units, and collides the body rect against the 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
|
+
"description": "Headless run/jump platformer-physics authority: the SOLE writer of body + fell + hazardId + goalId on side-view boards. Where std-motion-body owns free 2D drift (no collision), this atom owns the platformer contract: every 33ms physics tick it integrates gravity into the body's vertical velocity, steps position in per-second units, and collides the body rect against the 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
|
"ledger": {
|
|
4
4
|
"entries": {
|
|
5
5
|
"ent_01M0H2SJBB5TG61D238AWJW3KC": {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "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
|
+
"description": "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
|
"ledger": {
|
|
4
4
|
"entries": {
|
|
5
5
|
"ent_01M0PEDYHYWBHKSA6ZVNM086R4": {
|
|
@@ -1204,7 +1204,29 @@
|
|
|
1204
1204
|
"TutorialEmptyPreview": "trt_01M0S4ZSRVQBN2JT81Y534547C"
|
|
1205
1205
|
}
|
|
1206
1206
|
}
|
|
1207
|
-
]
|
|
1207
|
+
],
|
|
1208
|
+
"types": {
|
|
1209
|
+
"TutorialStep": [
|
|
1210
|
+
{
|
|
1211
|
+
"name": "id",
|
|
1212
|
+
"required": true,
|
|
1213
|
+
"type": "string"
|
|
1214
|
+
},
|
|
1215
|
+
{
|
|
1216
|
+
"name": "title",
|
|
1217
|
+
"required": true,
|
|
1218
|
+
"type": "string"
|
|
1219
|
+
},
|
|
1220
|
+
{
|
|
1221
|
+
"name": "body",
|
|
1222
|
+
"type": "string"
|
|
1223
|
+
},
|
|
1224
|
+
{
|
|
1225
|
+
"name": "demoId",
|
|
1226
|
+
"type": "string"
|
|
1227
|
+
}
|
|
1228
|
+
]
|
|
1229
|
+
}
|
|
1208
1230
|
}
|
|
1209
1231
|
],
|
|
1210
1232
|
"schemaVersion": 1,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "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
|
+
"description": "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
|
"ledger": {
|
|
4
4
|
"entries": {
|
|
5
5
|
"ent_01M11M409RW0H8NTF5AKJH3NTJ": {
|
|
@@ -1032,7 +1032,80 @@
|
|
|
1032
1032
|
]
|
|
1033
1033
|
}
|
|
1034
1034
|
}
|
|
1035
|
-
]
|
|
1035
|
+
],
|
|
1036
|
+
"types": {
|
|
1037
|
+
"VelocityGate": [
|
|
1038
|
+
{
|
|
1039
|
+
"name": "id",
|
|
1040
|
+
"required": true,
|
|
1041
|
+
"type": "string"
|
|
1042
|
+
},
|
|
1043
|
+
{
|
|
1044
|
+
"name": "x",
|
|
1045
|
+
"required": true,
|
|
1046
|
+
"type": "number"
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
"name": "y",
|
|
1050
|
+
"required": true,
|
|
1051
|
+
"type": "number"
|
|
1052
|
+
},
|
|
1053
|
+
{
|
|
1054
|
+
"name": "width",
|
|
1055
|
+
"required": true,
|
|
1056
|
+
"type": "number"
|
|
1057
|
+
},
|
|
1058
|
+
{
|
|
1059
|
+
"name": "height",
|
|
1060
|
+
"required": true,
|
|
1061
|
+
"type": "number"
|
|
1062
|
+
},
|
|
1063
|
+
{
|
|
1064
|
+
"name": "minSpeed",
|
|
1065
|
+
"required": true,
|
|
1066
|
+
"type": "number"
|
|
1067
|
+
},
|
|
1068
|
+
{
|
|
1069
|
+
"name": "maxSpeed",
|
|
1070
|
+
"required": true,
|
|
1071
|
+
"type": "number"
|
|
1072
|
+
},
|
|
1073
|
+
{
|
|
1074
|
+
"name": "dwellMs",
|
|
1075
|
+
"required": true,
|
|
1076
|
+
"type": "number"
|
|
1077
|
+
},
|
|
1078
|
+
{
|
|
1079
|
+
"name": "dir",
|
|
1080
|
+
"required": true,
|
|
1081
|
+
"type": "number"
|
|
1082
|
+
},
|
|
1083
|
+
{
|
|
1084
|
+
"name": "hint",
|
|
1085
|
+
"type": "string"
|
|
1086
|
+
},
|
|
1087
|
+
{
|
|
1088
|
+
"name": "open",
|
|
1089
|
+
"type": "boolean"
|
|
1090
|
+
},
|
|
1091
|
+
{
|
|
1092
|
+
"name": "touching",
|
|
1093
|
+
"type": "boolean"
|
|
1094
|
+
},
|
|
1095
|
+
{
|
|
1096
|
+
"name": "denied",
|
|
1097
|
+
"type": "boolean"
|
|
1098
|
+
},
|
|
1099
|
+
{
|
|
1100
|
+
"name": "held",
|
|
1101
|
+
"type": "number"
|
|
1102
|
+
},
|
|
1103
|
+
{
|
|
1104
|
+
"name": "reported",
|
|
1105
|
+
"type": "boolean"
|
|
1106
|
+
}
|
|
1107
|
+
]
|
|
1108
|
+
}
|
|
1036
1109
|
}
|
|
1037
1110
|
],
|
|
1038
1111
|
"schemaVersion": 1,
|