@jgengine/shell 0.25.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +109 -0
  2. package/dist/GamePlayerShell.d.ts +8 -0
  3. package/dist/GamePlayerShell.js +15 -1
  4. package/dist/Shell3dPresentation.js +29 -11
  5. package/dist/devtools/FrameTelemetry.d.ts +12 -0
  6. package/dist/devtools/FrameTelemetry.js +68 -0
  7. package/dist/devtools/agentBridge.js +2 -0
  8. package/dist/devtools/devtoolsReports.d.ts +2 -0
  9. package/dist/devtools/devtoolsReports.js +3 -0
  10. package/dist/devtools/frameSampler.d.ts +127 -0
  11. package/dist/devtools/frameSampler.js +345 -0
  12. package/dist/environment/AuthoredDaylight.d.ts +28 -0
  13. package/dist/environment/AuthoredDaylight.js +42 -0
  14. package/dist/environment/Daylight.d.ts +55 -7
  15. package/dist/environment/Daylight.js +126 -29
  16. package/dist/environment/EnvironmentScene.js +51 -8
  17. package/dist/environment/daylightCycle.d.ts +26 -4
  18. package/dist/environment/daylightCycle.js +36 -5
  19. package/dist/postfx/PostProcessing.d.ts +7 -1
  20. package/dist/postfx/PostProcessing.js +28 -2
  21. package/dist/postfx/autoExposure.d.ts +49 -0
  22. package/dist/postfx/autoExposure.js +189 -0
  23. package/dist/postfx/gradeShader.js +43 -4
  24. package/dist/presentationRecovery3d.js +2 -1
  25. package/dist/render/CascadedShadows.d.ts +3 -1
  26. package/dist/render/CascadedShadows.js +9 -1
  27. package/dist/render/EnvironmentLighting.d.ts +10 -1
  28. package/dist/render/EnvironmentLighting.js +11 -3
  29. package/dist/render/IrradianceVolumeLighting.d.ts +18 -0
  30. package/dist/render/IrradianceVolumeLighting.js +35 -0
  31. package/dist/render/SceneLighting.d.ts +14 -1
  32. package/dist/render/SceneLighting.js +29 -8
  33. package/dist/render/authoredGrade.d.ts +11 -0
  34. package/dist/render/authoredGrade.js +26 -0
  35. package/dist/render/decalGeometry.d.ts +26 -0
  36. package/dist/render/decalGeometry.js +54 -0
  37. package/dist/render/decalTexture.d.ts +13 -0
  38. package/dist/render/decalTexture.js +114 -0
  39. package/dist/render/modelWind.d.ts +28 -0
  40. package/dist/render/modelWind.js +103 -0
  41. package/dist/render/presentationLook.d.ts +15 -0
  42. package/dist/render/presentationLook.js +18 -0
  43. package/dist/render/stableTextureSet.d.ts +9 -0
  44. package/dist/render/stableTextureSet.js +24 -0
  45. package/dist/render/triplanarMaterial.d.ts +52 -0
  46. package/dist/render/triplanarMaterial.js +169 -0
  47. package/dist/render/useModelInstance.d.ts +1 -1
  48. package/dist/render/useModelInstance.js +3 -1
  49. package/dist/scatter/scatterModels.js +2 -0
  50. package/dist/scene/DecalRenderer.d.ts +2 -0
  51. package/dist/scene/DecalRenderer.js +74 -0
  52. package/dist/scene/GrassFieldRenderer.js +3 -2
  53. package/dist/scene/builtinSceneKindRenderers.js +2 -0
  54. package/dist/settings/appliedSettings.js +16 -13
  55. package/dist/terrain/GrassCover.d.ts +21 -0
  56. package/dist/terrain/GrassCover.js +84 -0
  57. package/dist/terrain/grassCoverGeometry.d.ts +40 -0
  58. package/dist/terrain/grassCoverGeometry.js +112 -0
  59. package/dist/terrain/terrainDetailMaterial.d.ts +12 -0
  60. package/dist/terrain/terrainDetailMaterial.js +54 -1
  61. package/dist/terrain/terrainSurfaces.d.ts +6 -0
  62. package/dist/terrain/terrainSurfaces.js +10 -0
  63. package/dist/world/WorldScene.js +2 -1
  64. package/package.json +4 -4
  65. package/skills/jgengine/api.md +59 -6
  66. package/skills/jgengine/capabilities.md +4 -0
  67. package/skills/jgengine-ui/api.md +114 -23
  68. package/skills/jgengine-ui/capabilities.md +14 -0
  69. package/skills/jgengine-ui/reference-primitives.md +4 -2
  70. package/skills/jgengine-world/SKILL.md +7 -1
  71. package/skills/jgengine-world/api.md +222 -8
  72. package/skills/jgengine-world/capabilities.md +42 -2
  73. package/skills/jgengine-world/recipes/npc-senses.md +8 -2
  74. package/skills/jgengine-world/recipes/vehicle-feel.md +5 -0
@@ -462,6 +462,14 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
462
462
 
463
463
  - `createKinematicVehicle` (function) · `import { createKinematicVehicle } from "@jgengine/core/world"`
464
464
 
465
+ ## lane-graph — directed lane topology with junctions, signals and parking for vehicle traffic
466
+
467
+ - `createLaneGraph` (function) · `import { createLaneGraph } from "@jgengine/core/world"`
468
+
469
+ ## lane-graph-from-scene — read an authored lane graph, signals and parking out of the scene document
470
+
471
+ - `laneGraphFromDocument` (function) · `import { laneGraphFromDocument } from "@jgengine/core/world"`
472
+
465
473
  ## lean-metrics — measure a motorcycle's lean — steady lean, time to lean, countersteer tip-in
466
474
 
467
475
  - `measureLean` (function) · `import { measureLean } from "@jgengine/core/physics/handlingProbe"`
@@ -549,14 +557,26 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
549
557
 
550
558
  - `sweepMovingSphere` (function) · `import { sweepMovingSphere } from "@jgengine/core/physics/ballisticSweep"`
551
559
 
560
+ ## nav-crowd — move many agents across an editor-baked nav mesh with avoidance
561
+
562
+ - `createNavCrowd` (function) · `import { createNavCrowd } from "@jgengine/core/world"`
563
+
552
564
  ## nav-from-solids — block world solids on a nav grid
553
565
 
554
566
  - `populateNavGridFromSolids` (function) · `import { populateNavGridFromSolids } from "@jgengine/core/nav/navFromEnvironment"`
555
567
 
568
+ ## nav-runtime — route agents on an editor-baked nav mesh with authored links and re-bakes that keep polygon identity
569
+
570
+ - `createNavRuntime` (function) · `import { createNavRuntime } from "@jgengine/core/world"`
571
+
556
572
  ## navmesh-bake — voxelize scene triangles into an agent-sized polygon nav mesh
557
573
 
558
574
  - `bakeNavMesh` (function) · `import { bakeNavMesh } from "@jgengine/navbake"`
559
575
 
576
+ ## navmesh-from-scene — read the editor's baked nav mesh off a scene document
577
+
578
+ - `navMeshFromBake` (function) · `import { navMeshFromBake } from "@jgengine/core/world"`
579
+
560
580
  ## navmesh-query — route, snap, and raycast on a polygon navmesh with retunable area costs and a bounded search
561
581
 
562
582
  - `createNavMeshQuery` (function) · `import { createNavMeshQuery } from "@jgengine/core/world"`
@@ -610,9 +630,9 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
610
630
 
611
631
  - `definePatrolOrder` (function) · `import { definePatrolOrder } from "@jgengine/core/world"`
612
632
 
613
- ## perception-service — retain sight, sound, and damage observations with range, cone, occlusion, and decay policy
633
+ ## perception-service — retain sightings, sounds and damage with cone, range, occlusion, decaying memory and shared squad knowledge
614
634
 
615
- - `createPerception` (function) · `import { createPerception } from "@jgengine/core/sensor/perception"`
635
+ - `createPerception` (function) · `import { createPerception } from "@jgengine/core/world"`
616
636
 
617
637
  ## physics-backend — one interface over interchangeable rigid-body solvers — bodies, joints, raycast, shapecast, snapshot
618
638
 
@@ -707,6 +727,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
707
727
  - `controlGroupKey` (function) · `import { controlGroupKey } from "@jgengine/core/world"`
708
728
  - `resolveControlGroupIntent` (function) · `import { resolveControlGroupIntent } from "@jgengine/core/world"`
709
729
 
730
+ ## rvo-avoidance — reciprocal collision avoidance between many steering agents
731
+
732
+ - `createRvoCrowd` (function) · `import { createRvoCrowd } from "@jgengine/core/world"`
733
+
710
734
  ## scatter-coverage — shared density/budget semantics for scatterable kinds
711
735
 
712
736
  - `ScatterCoverageKind` (type) · `import { ScatterCoverageKind } from "@jgengine/core/world"`
@@ -881,6 +905,10 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
881
905
  - `setTouchControlsMode` (function) · `import { setTouchControlsMode } from "@jgengine/core/input/touchControlsMode"`
882
906
  - `touchButtonShape` (function) · `import { touchButtonShape } from "@jgengine/core/input/touchScheme"`
883
907
 
908
+ ## traffic — lane-graph traffic with car following, signals, right-of-way, lane changes and parking
909
+
910
+ - `createTraffic` (function) · `import { createTraffic } from "@jgengine/core/world"`
911
+
884
912
  ## ui-sound-cues — default procedural click/hover/open/close/confirm/deny/notify cues on a "ui" bus, overridable per game
885
913
 
886
914
  - `withUiCueSounds` (function) · `import { withUiCueSounds } from "@jgengine/core/audio/uiCues"`
@@ -889,14 +917,26 @@ Reach for these before hand-rolling. Each row is *the thing you need* → *the p
889
917
 
890
918
  - `resolveTerrainGradeStep` (function) · `import { resolveTerrainGradeStep } from "@jgengine/core/movement/terrainGrade"`
891
919
 
920
+ ## utility-brain — pick actions by decaying-need appeal with response curves, hysteresis and interrupts
921
+
922
+ - `createUtilityBrain` (function) · `import { createUtilityBrain } from "@jgengine/core/world"`
923
+
892
924
  ## vehicle-backend-link — collide a vehicle sim with a physics backend — shove props, stop at walls, slide along them
893
925
 
894
926
  - `createVehicleBackendLink` (function) · `import { createVehicleBackendLink } from "@jgengine/core/physics/vehicleBackendLink"`
895
927
 
928
+ ## vehicle-damage — fixed-zone crash damage that changes handling and shows a bounded dent, serializable
929
+
930
+ - `createVehicleDamage` (function) · `import { createVehicleDamage } from "@jgengine/core/world"`
931
+
896
932
  ## vehicle-dynamics — force-based car handling — tires, load transfer, drivetrain, assists — tuned with physical numbers
897
933
 
898
934
  - `createVehicleDynamics` (function) · `import { createVehicleDynamics } from "@jgengine/core/physics/vehicleDynamics"`
899
935
 
936
+ ## vehicle-parts — compose data-driven tuning parts (tires, engine, brakes) onto a vehicle tuning and read the resulting feel
937
+
938
+ - `applyVehicleParts` (function) · `import { applyVehicleParts } from "@jgengine/core/world"`
939
+
900
940
  ## vehicle-seats — enter, exit and swap seats in a car or mount (GTA-style boarding) with driver and passenger slots
901
941
 
902
942
  - `createVehicleSeats` (function) · `import { createVehicleSeats } from "@jgengine/core/world"`
@@ -15,8 +15,14 @@ Working example: the `guard-probe` dev demo (`apps/dev/src/demo/guardProbe.ts`),
15
15
  senses. Each tick, push the stimuli your game produces (`sound` with a
16
16
  `loudness` that scales range, `damage`) and call `observe(npc, candidates, nowMs)`
17
17
  with a *bounded* candidate list from a spatial query, never every entity. Pass
18
- `occluded` for walls. Memory decays linearly over `memorySeconds`; each observer
19
- judges a stimulus once.
18
+ `isSegmentClear` for walls — a caller function over your collision layer that
19
+ returns true when nothing blocks the line; it is only called for pairs already
20
+ inside range and cone, so keep that cheap. Memory decays linearly over
21
+ `memorySeconds`; each observer judges a stimulus once. Pass `squadMates` so one
22
+ member's sighting lands in every mate's memory stamped with `sourceId` and
23
+ `sourceTick`; `maxSharesPerTick` caps the broadcast. `memoryOf(id, target)` is
24
+ the one question "is this still known, and how sure", and `stats()` says what
25
+ the pass cost (pairs, range prunes, line checks, shares).
20
26
  - **Memory → blackboard.** A small system copies the facts the graph needs into
21
27
  the NPC's persistent blackboard: `behaviorControl(ctx).blackboard(id)`. Write
22
28
  plain scalars (`alerted`, `lastKnownX`, `lastKnownZ`, `confidence`). Actions
@@ -5,6 +5,10 @@
5
5
  ## The seams
6
6
 
7
7
  - **Sim.** `createVehicleDynamics(tuning, { surfaceFriction?, clampMove?, groundHeight? })` from `@jgengine/core/physics/vehicleDynamics`. Yaw comes from tire forces, so balance, slides and recovery are outcomes of the numbers, not special cases. It has `snapshot()`/`restore()` for prediction and replay, `retune()` for upgrades and damage, and per-tick modifiers (`driveScale`, `gripScale`, `steerScale`, `brakeScale`, `thrust` for boost).
8
+ - **Arcade sim.** `createKinematicVehicle(tuning, { surfaceFriction?, dragAt?, clampMove? })` from `@jgengine/core/physics/kinematicVehicle` is the cheap steer-yaw model for chases and ambient cars. Its grip is a `GripCurve` (slip → force) sampled each tick against surface friction, handbrake and downforce; `weightTransfer: { comHeight, wheelbase, trackWidth, sensitivity? }` cuts that curve as weight moves under braking/traction/cornering and reports `weightTransfer`/`loadGrip`. `retune()` swaps handling in play, and `gripScale` on the per-tick modifiers is the one-frame hook. Use the force model above when balance has to come out of the numbers.
9
+ - **Parts.** `applyVehicleParts(base, parts)` (`@jgengine/core/physics/vehicleParts`) folds data-driven parts onto a tuning — `{ id, slot, effects: { engineAccel: { scale, add } }, gripCurve? }` — in install order, and returns the composed tuning plus a comparable `VehicleFeel`. `withPart` swaps one part in its slot, `feelOf(tuning)` reads the numbers out of anything, and `vehicle.retune(setup.tuning)` installs it mid-play without losing momentum.
10
+ - **Damage.** `createVehicleDamage({ zones, disableAt?, onTransition? })` (`@jgengine/core/physics/vehicleDamage`) takes local hit points and impulses, steps fixed zones through thresholds, and returns bounded `deformation()` (a per-zone offset the renderer applies, plus `detached`) and `effect()` (grip/drive/brake/top-speed scales, `steerPull`, `drag`). Feed `effect()` through `damagedTuning(base, effect)` + `retune` for lasting damage, or `modifiers()` for one frame; `damagedAxis(axis, effect)` applies the bent-frame pull. It serializes, so a save or a host correction resumes mid-crash. There is no mesh editing: every zone has one authored `deform` limit.
11
+ - The dent is rendered by the game's own `renderEntity` (it already receives the entity each render) — the zone's `offset` displaces that part, and `detached` hides it. No shell seam is needed.
8
12
  - **Terrain.** Add a `suspension` block (spring and damper rates, travel, ride height, anti-roll) and pass `groundHeight` for ramps, hills and jumps. Each wheel then samples the ground, the body heaves, pitches and rolls on real springs, slopes pull the car downhill, and the step reports `airborne`, `landingSpeed` and per-corner `wheelLoads`. Without the block the car stays on a flat plane.
9
13
  - **Input.** Put `createAxisShaper` (`@jgengine/core/input/axisShaper`) between `ctx.input.axis(...)` and the sim. Keys get `riseRate`/`returnRate`, so a tap steers a little and a hold builds up; sticks get `deadzone`/`curve` with no lag. Pass `{ analog: analogAxes(bindings, ctx.input.analog()) }` each frame so each axis picks the right profile.
10
14
  - **Pad feel.** Set the stick deadzone, curve and trigger deadzone once in `defineGame({ gamepad: { deadzone, curve, triggerDeadzone } })`. The shell applies it before any analog value reaches `ctx.input`, so per-axis shaping in `createAxisShaper` only adds ramps and speed scaling on top.
@@ -36,6 +40,7 @@
36
40
  - **Sound.** Play a one-shot on `step.landingSpeed` (thud, suspension clunk).
37
41
  - **Proof.** For jumps and air control, `measureAir` reports apex height and time, double-jump height, and air rotation rates.
38
42
  - **Proof.** `measureHandling(() => createVehicleDynamics(tuning), options?)` from `@jgengine/core/physics/handlingProbe` returns deterministic numbers. Assert them in a test. For a sprung car, `measureRide` adds settle time, brake dive, roll per g and landing bounces.
43
+ - **Proof.** For the arcade sim, `feelOf(setup.tuning)` gives comparable numbers per build, and a test drives the same scripted inputs on two `surfaceFriction` values (or before/after `damagedTuning`) and asserts the grip difference — slip and lateral speed retained, and top speed reached.
39
44
 
40
45
  ## Workflow
41
46