@jgengine/shell 0.10.0 → 0.11.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 (234) hide show
  1. package/CHANGELOG.md +13 -2
  2. package/LICENSE +203 -661
  3. package/README.md +1 -1
  4. package/dist/GamePhaseStamp.d.ts +1 -0
  5. package/dist/GamePhaseStamp.js +9 -0
  6. package/dist/GamePlayerShell.d.ts +0 -12
  7. package/dist/GamePlayerShell.js +88 -1043
  8. package/dist/GameUiPreview.js +0 -2
  9. package/dist/audio/audioEngine.js +30 -8
  10. package/dist/audio/audioWire.d.ts +22 -0
  11. package/dist/audio/audioWire.js +19 -0
  12. package/dist/behaviour.d.ts +2 -1
  13. package/dist/behaviour.js +2 -1
  14. package/dist/behaviourAttach.d.ts +1 -0
  15. package/dist/behaviourAttach.js +1 -0
  16. package/dist/behaviourDriver.d.ts +1 -0
  17. package/dist/behaviourDriver.js +1 -0
  18. package/dist/boundActionDispatch.d.ts +13 -0
  19. package/dist/boundActionDispatch.js +37 -0
  20. package/dist/camera/GameCameraRig.d.ts +5 -2
  21. package/dist/camera/GameCameraRig.js +2 -2
  22. package/dist/camera/GameFirstPersonCamera.d.ts +9 -2
  23. package/dist/camera/GameFirstPersonCamera.js +8 -3
  24. package/dist/camera/GameInspectionCamera.d.ts +1 -1
  25. package/dist/camera/GameInspectionCamera.js +2 -2
  26. package/dist/camera/GameOrbitCamera.js +24 -9
  27. package/dist/camera/cameraBlendMath.d.ts +3 -0
  28. package/dist/camera/cameraBlendMath.js +3 -0
  29. package/dist/camera/fovPreference.d.ts +6 -1
  30. package/dist/camera/fovPreference.js +6 -1
  31. package/dist/camera/index.d.ts +4 -7
  32. package/dist/camera/index.js +4 -7
  33. package/dist/camera/inspectionCameraMath.d.ts +7 -2
  34. package/dist/camera/inspectionCameraMath.js +7 -2
  35. package/dist/camera/orbitCameraMath.d.ts +36 -6
  36. package/dist/camera/orbitCameraMath.js +56 -6
  37. package/dist/camera/rigMath.d.ts +94 -24
  38. package/dist/camera/rigMath.js +100 -24
  39. package/dist/camera/rigResolve.d.ts +4 -2
  40. package/dist/camera/rigResolve.js +4 -2
  41. package/dist/camera/shakeChannel.d.ts +6 -2
  42. package/dist/camera/shakeChannel.js +6 -2
  43. package/dist/camera/shakeChannelMath.d.ts +1 -0
  44. package/dist/camera/shakeChannelMath.js +1 -0
  45. package/dist/cartridge/runtime.d.ts +15 -0
  46. package/dist/cartridge/runtime.js +556 -0
  47. package/dist/cartridge/spec.d.ts +188 -0
  48. package/dist/cartridge/spec.js +19 -0
  49. package/dist/cartridge/validate.d.ts +2 -0
  50. package/dist/cartridge/validate.js +78 -0
  51. package/dist/cartridge.d.ts +1 -1
  52. package/dist/cartridge.js +3 -3
  53. package/dist/commandSink.d.ts +8 -3
  54. package/dist/commandSink.js +8 -3
  55. package/dist/defineGame.js +25 -6
  56. package/dist/devtools/ColPanel.d.ts +1 -0
  57. package/dist/devtools/ColPanel.js +14 -0
  58. package/dist/devtools/DevtoolsOverlay.d.ts +7 -3
  59. package/dist/devtools/DevtoolsOverlay.js +19 -450
  60. package/dist/devtools/KeysPanel.d.ts +4 -0
  61. package/dist/devtools/KeysPanel.js +31 -0
  62. package/dist/devtools/LogsPanel.d.ts +1 -0
  63. package/dist/devtools/LogsPanel.js +12 -0
  64. package/dist/devtools/NetPanel.d.ts +4 -0
  65. package/dist/devtools/NetPanel.js +10 -0
  66. package/dist/devtools/PerfPanel.d.ts +4 -0
  67. package/dist/devtools/PerfPanel.js +53 -0
  68. package/dist/devtools/TunePanel.d.ts +3 -0
  69. package/dist/devtools/TunePanel.js +309 -0
  70. package/dist/devtools/agentBridge.d.ts +41 -0
  71. package/dist/devtools/agentBridge.js +262 -0
  72. package/dist/devtools/collisionDebug.d.ts +6 -0
  73. package/dist/devtools/collisionDebug.js +6 -0
  74. package/dist/devtools/collisionDebugMath.d.ts +8 -2
  75. package/dist/devtools/collisionDebugMath.js +24 -5
  76. package/dist/devtools/devtoolsOverrides.d.ts +6 -0
  77. package/dist/devtools/devtoolsOverrides.js +48 -0
  78. package/dist/devtools/panelAtoms.d.ts +9 -0
  79. package/dist/devtools/panelAtoms.js +10 -0
  80. package/dist/devtools/perfDiagnose.d.ts +2 -0
  81. package/dist/devtools/perfDiagnose.js +43 -0
  82. package/dist/diagnostics/RuntimeDiagnostics.d.ts +29 -0
  83. package/dist/diagnostics/RuntimeDiagnostics.js +69 -0
  84. package/dist/drivers/FrameDriver.d.ts +37 -0
  85. package/dist/drivers/FrameDriver.js +232 -0
  86. package/dist/drivers/HudOnlyDriver.d.ts +16 -0
  87. package/dist/drivers/HudOnlyDriver.js +60 -0
  88. package/dist/environment/Daylight.d.ts +23 -7
  89. package/dist/environment/Daylight.js +106 -13
  90. package/dist/environment/EnvironmentScene.js +32 -6
  91. package/dist/environment/VolumetricClouds.d.ts +17 -0
  92. package/dist/environment/VolumetricClouds.js +202 -0
  93. package/dist/environment/daylightCycle.d.ts +3 -1
  94. package/dist/environment/daylightCycle.js +3 -1
  95. package/dist/environment/groundPadMath.d.ts +3 -0
  96. package/dist/environment/groundPadMath.js +3 -0
  97. package/dist/environment/index.d.ts +1 -0
  98. package/dist/environment/index.js +1 -0
  99. package/dist/environment/skyLightingPolicy.d.ts +2 -0
  100. package/dist/environment/skyLightingPolicy.js +2 -0
  101. package/dist/hotbarActions.d.ts +26 -0
  102. package/dist/hotbarActions.js +27 -0
  103. package/dist/inputSink.d.ts +16 -4
  104. package/dist/inputSink.js +57 -7
  105. package/dist/materialOverride.d.ts +10 -0
  106. package/dist/materialOverride.js +15 -3
  107. package/dist/multiplayer.js +8 -2
  108. package/dist/postfx/PostProcessing.js +47 -9
  109. package/dist/postfx/gradeShader.js +9 -1
  110. package/dist/registry.d.ts +3 -2
  111. package/dist/render/EnvironmentLighting.d.ts +10 -0
  112. package/dist/render/EnvironmentLighting.js +34 -0
  113. package/dist/render/SceneLighting.d.ts +7 -0
  114. package/dist/render/SceneLighting.js +18 -0
  115. package/dist/render/SceneModels.d.ts +14 -0
  116. package/dist/render/SceneModels.js +337 -0
  117. package/dist/render/defaultSurface.d.ts +29 -0
  118. package/dist/render/defaultSurface.js +101 -0
  119. package/dist/render/modelLoad.d.ts +24 -0
  120. package/dist/render/modelLoad.js +73 -0
  121. package/dist/render/modelRender.d.ts +11 -0
  122. package/dist/render/modelRender.js +15 -0
  123. package/dist/render/resolveModel.d.ts +39 -3
  124. package/dist/render/resolveModel.js +79 -2
  125. package/dist/render/useEntityRenderCues.d.ts +13 -0
  126. package/dist/render/useEntityRenderCues.js +62 -0
  127. package/dist/scatter/InstancedScatter.d.ts +24 -0
  128. package/dist/scatter/InstancedScatter.js +130 -0
  129. package/dist/scatter/scatterModels.d.ts +25 -0
  130. package/dist/scatter/scatterModels.js +61 -0
  131. package/dist/scatter/scatterProxies.d.ts +6 -0
  132. package/dist/scatter/scatterProxies.js +94 -0
  133. package/dist/scatter.d.ts +1 -0
  134. package/dist/scatter.js +1 -0
  135. package/dist/scene/AuthoredScene.d.ts +82 -0
  136. package/dist/scene/AuthoredScene.js +173 -0
  137. package/dist/scene/GeneratedAssetRenderer.d.ts +14 -0
  138. package/dist/scene/GeneratedAssetRenderer.js +59 -0
  139. package/dist/scene/GrassFieldRenderer.d.ts +2 -0
  140. package/dist/scene/GrassFieldRenderer.js +25 -0
  141. package/dist/scene/SoilPatchRenderer.d.ts +2 -0
  142. package/dist/scene/SoilPatchRenderer.js +21 -0
  143. package/dist/scene/StudioStage.d.ts +37 -0
  144. package/dist/scene/StudioStage.js +42 -0
  145. package/dist/scene/WaterRenderer.d.ts +2 -0
  146. package/dist/scene/WaterRenderer.js +37 -0
  147. package/dist/scene/builtinSceneKindRenderers.d.ts +2 -0
  148. package/dist/scene/builtinSceneKindRenderers.js +22 -0
  149. package/dist/scene/sceneKindRenderers.d.ts +28 -0
  150. package/dist/scene/sceneKindRenderers.js +17 -0
  151. package/dist/scene.d.ts +1 -0
  152. package/dist/scene.js +1 -0
  153. package/dist/settings/appliedSettings.d.ts +5 -0
  154. package/dist/settings/appliedSettings.js +9 -0
  155. package/dist/settings/settingsController.d.ts +2 -0
  156. package/dist/settings/settingsController.js +22 -1
  157. package/dist/shellConstants.d.ts +4 -0
  158. package/dist/shellConstants.js +4 -0
  159. package/dist/shellMovement.d.ts +8 -0
  160. package/dist/shellMovement.js +11 -0
  161. package/dist/shellPointer.d.ts +20 -0
  162. package/dist/shellPointer.js +28 -0
  163. package/dist/structures/PlacementGhost.d.ts +4 -0
  164. package/dist/structures/PlacementGhost.js +4 -0
  165. package/dist/structures/TransformGizmo.d.ts +43 -0
  166. package/dist/structures/TransformGizmo.js +55 -0
  167. package/dist/structures/index.d.ts +1 -0
  168. package/dist/structures/index.js +1 -0
  169. package/dist/terrain/GrassField.js +1 -1
  170. package/dist/terrain/TerraformBrushCursor.js +3 -0
  171. package/dist/terrain/grassBudget.d.ts +11 -2
  172. package/dist/terrain/grassBudget.js +20 -4
  173. package/dist/terrain/grassGeometry.d.ts +3 -0
  174. package/dist/terrain/grassGeometry.js +3 -0
  175. package/dist/terrain/grassMaterial.d.ts +2 -0
  176. package/dist/terrain/grassMaterial.js +2 -0
  177. package/dist/terrain/random.d.ts +3 -0
  178. package/dist/terrain/random.js +3 -0
  179. package/dist/terrain/soilPatchMaterial.d.ts +10 -0
  180. package/dist/terrain/soilPatchMaterial.js +109 -0
  181. package/dist/terrain/terrainDetailMaterial.d.ts +19 -2
  182. package/dist/terrain/terrainDetailMaterial.js +72 -5
  183. package/dist/terrain/terrainMath.d.ts +8 -1
  184. package/dist/terrain/terrainMath.js +8 -1
  185. package/dist/touch/TouchControlsOverlay.d.ts +9 -5
  186. package/dist/touch/TouchControlsOverlay.js +201 -22
  187. package/dist/useShellMultiplayerSync.d.ts +9 -0
  188. package/dist/useShellMultiplayerSync.js +98 -0
  189. package/dist/visibility/CullingProvider.js +1 -1
  190. package/dist/water/OceanConfig.d.ts +2 -0
  191. package/dist/water/OceanConfig.js +2 -0
  192. package/dist/weather/fireSpreadPose.d.ts +1 -0
  193. package/dist/weather/fireSpreadPose.js +1 -0
  194. package/dist/weather/weatherGeometry.d.ts +1 -0
  195. package/dist/weather/weatherGeometry.js +1 -0
  196. package/dist/weather/weatherMath.d.ts +3 -0
  197. package/dist/weather/weatherMath.js +3 -0
  198. package/dist/weather/weatherUniforms.d.ts +3 -0
  199. package/dist/weather/weatherUniforms.js +3 -0
  200. package/dist/world/RetainedVfx.d.ts +10 -0
  201. package/dist/world/RetainedVfx.js +136 -0
  202. package/dist/world/WorldHud.d.ts +49 -2
  203. package/dist/world/WorldHud.js +87 -2
  204. package/dist/world/WorldScene.d.ts +21 -0
  205. package/dist/world/WorldScene.js +159 -0
  206. package/dist/world/WorldVfx.d.ts +9 -0
  207. package/dist/world/WorldVfx.js +184 -0
  208. package/dist/world/entityPose.d.ts +2 -0
  209. package/dist/world/entityPose.js +2 -0
  210. package/dist/world/floatTextStyle.d.ts +1 -0
  211. package/dist/world/floatTextStyle.js +1 -0
  212. package/dist/world/telegraphPulse.d.ts +1 -0
  213. package/dist/world/telegraphPulse.js +1 -0
  214. package/dist/world/worldBarSamples.d.ts +25 -0
  215. package/dist/world/worldBarSamples.js +38 -0
  216. package/dist/worldSky.d.ts +5 -0
  217. package/dist/worldSky.js +11 -0
  218. package/dist/worldSync.d.ts +2 -1
  219. package/dist/worldSync.js +2 -1
  220. package/package.json +6 -6
  221. package/skills/jgengine/SKILL.md +51 -0
  222. package/skills/jgengine/api.md +434 -0
  223. package/skills/jgengine/capabilities.md +29 -0
  224. package/skills/jgengine/reference-cartridge.md +72 -0
  225. package/skills/jgengine-ui/SKILL.md +36 -0
  226. package/skills/jgengine-ui/api.md +1852 -0
  227. package/skills/jgengine-ui/capabilities.md +142 -0
  228. package/skills/jgengine-ui/reference.md +500 -0
  229. package/skills/jgengine-ui/references/visual-scorecard.md +73 -0
  230. package/skills/jgengine-world/SKILL.md +38 -0
  231. package/skills/jgengine-world/api.md +2652 -0
  232. package/skills/jgengine-world/capabilities.md +370 -0
  233. package/skills/jgengine-world/reference.md +222 -0
  234. package/llms.txt +0 -2761
@@ -1,3 +1,4 @@
1
+ /** @internal */
1
2
  export function resolveInspectionCameraConfig(config) {
2
3
  return {
3
4
  anchor: config?.anchor ?? "target",
@@ -24,7 +25,9 @@ export function resolveInspectionCameraConfig(config) {
24
25
  dampingFactor: config?.dampingFactor ?? 0.08,
25
26
  };
26
27
  }
27
- /** Seeds the camera/target world position before OrbitControls mounts. Falls back to `initialDistance` behind `target` on the -Z axis, raised by 40% of that distance, when `initialPosition` is unset. */
28
+ /** Seeds the camera/target world position before OrbitControls mounts. Falls back to `initialDistance` behind `target` on the -Z axis, raised by 40% of that distance, when `initialPosition` is unset.
29
+ * @internal
30
+ */
28
31
  export function seedInspectionCamera(config) {
29
32
  if (config.initialPosition !== null) {
30
33
  return { camera: config.initialPosition, target: config.target };
@@ -38,7 +41,9 @@ export function seedInspectionCamera(config) {
38
41
  target: config.target,
39
42
  };
40
43
  }
41
- /** Maps the anchor mode onto three-stdlib OrbitControls' native `zoomToCursor` flag. */
44
+ /** Maps the anchor mode onto three-stdlib OrbitControls' native `zoomToCursor` flag.
45
+ * @internal
46
+ */
42
47
  export function resolveInspectionZoomToCursor(anchor) {
43
48
  return anchor === "cursor";
44
49
  }
@@ -1,6 +1,10 @@
1
- /** Horizontal facing derived from an orbit camera orbiting a target on the XZ plane. */
1
+ /** Horizontal facing derived from an orbit camera orbiting a target on the XZ plane.
2
+ * @internal
3
+ */
2
4
  export declare function orbitYawFromCamera(cameraX: number, cameraZ: number, targetX: number, targetZ: number): number;
3
- /** Elevation the camera looks along (radians): negative = aiming down, positive = aiming up, 0 = level. Feeds aim.pitch so vertical aim tracks the camera. */
5
+ /** Elevation the camera looks along (radians): negative = aiming down, positive = aiming up, 0 = level. Feeds aim.pitch so vertical aim tracks the camera.
6
+ * @internal
7
+ */
4
8
  export declare function cameraLookPitch(camera: Vec3, target: Vec3): number;
5
9
  export interface Vec3 {
6
10
  x: number;
@@ -19,6 +23,12 @@ export interface OrbitCameraConfig {
19
23
  targetHeight?: number;
20
24
  initialDistance?: number;
21
25
  initialHeight?: number;
26
+ /** Initial horizontal facing of the boom (radians): 0 = camera behind on -Z, PI = camera on +Z. Seeds the rig when set; unset keeps the legacy -Z placement. */
27
+ initialYaw?: number;
28
+ /** Initial boom elevation (radians): 0 = level, positive = camera above the target looking down. Seeds the rig when set; unset derives elevation from `initialHeight`/`initialDistance`. */
29
+ initialPitch?: number;
30
+ /** Signed boom-elevation clamp `[min, max]` (radians): min < 0 dips below the target, max > 0 rises overhead. Maps onto `minPolarAngle`/`maxPolarAngle` (polar = PI/2 − pitch); explicit polar fields win. */
31
+ pitchClamp?: readonly [number, number];
22
32
  /** Extra offset applied on top of entity position for the orbit target. */
23
33
  targetOffset?: Partial<Vec3>;
24
34
  /** Keep orbit radius locked while the follow target moves. */
@@ -64,6 +74,8 @@ export interface ResolvedOrbitCameraConfig {
64
74
  targetHeight: number;
65
75
  initialDistance: number;
66
76
  initialHeight: number;
77
+ initialYaw?: number;
78
+ initialPitch?: number;
67
79
  targetOffset?: Partial<Vec3>;
68
80
  followLock: boolean;
69
81
  followEnabled: boolean;
@@ -87,22 +99,38 @@ export interface OrbitFollowRuntimeState {
87
99
  camera: Vec3;
88
100
  lockedDistance: number | null;
89
101
  }
90
- /** Frame-rate independent exponential smoothing factor in [0, 1]. */
102
+ /** Frame-rate independent exponential smoothing factor in [0, 1].
103
+ * @internal
104
+ */
91
105
  export declare function smoothBlend(deltaSeconds: number, speed: number): number;
106
+ /** @internal */
92
107
  export declare function resolveOrbitCameraConfig(patch?: OrbitCameraConfig): ResolvedOrbitCameraConfig;
108
+ /**
109
+ * FOV that keeps a target's on-screen size constant as the spring-arm pulls the
110
+ * camera in. Widens the base FOV by the desired/pulled distance ratio; a no-op
111
+ * (returns the base) whenever the camera sits at or beyond its desired distance.
112
+ * @internal
113
+ */
114
+ export declare function compensatedFov(baseFovDegrees: number, desiredDistance: number, pulledDistance: number): number;
115
+ /** @internal */
93
116
  export declare function resolveTargetSmoothing(config: ResolvedOrbitCameraConfig, dragging: boolean): number;
117
+ /** @internal */
94
118
  export declare function resolveFollowTargetFromPosition(position: readonly [number, number, number], config: Pick<ResolvedOrbitCameraConfig, "targetHeight" | "targetOffset">): Vec3;
119
+ /** @internal */
95
120
  export declare function lerpVec3(from: Vec3, to: Vec3, blend: number): Vec3;
121
+ /** @internal */
96
122
  export declare function distanceBetween(a: Vec3, b: Vec3): number;
123
+ /** @internal */
97
124
  export declare function seedOrbitFollowState(input: {
98
125
  entityPosition: readonly [number, number, number];
99
- config: Pick<ResolvedOrbitCameraConfig, "targetHeight" | "targetOffset" | "initialDistance" | "initialHeight">;
126
+ config: Pick<ResolvedOrbitCameraConfig, "targetHeight" | "targetOffset" | "initialDistance" | "initialHeight" | "initialYaw" | "initialPitch">;
100
127
  }): OrbitFollowRuntimeState;
101
128
  /**
102
129
  * Pure orbit follow step — smooth target tracking, camera carries target delta
103
130
  * (OrbitControls alone keeps camera fixed when only target moves), optional
104
131
  * distance lock. Call each frame before OrbitControls.update() in the shell.
105
- */
132
+ * @internal
133
+ */
106
134
  export declare function orbitFollowStep(input: {
107
135
  state: OrbitFollowRuntimeState;
108
136
  desiredTarget: Vec3;
@@ -112,7 +140,9 @@ export declare function orbitFollowStep(input: {
112
140
  }): OrbitFollowRuntimeState & {
113
141
  distance: number;
114
142
  };
115
- /** @deprecated Use orbitFollowStep — kept for older call sites. */
143
+ /** @deprecated Use orbitFollowStep — kept for older call sites.
144
+ * @internal
145
+ */
116
146
  export declare function cameraFollowStep(input: {
117
147
  camera: Vec3;
118
148
  target: Vec3;
@@ -1,10 +1,14 @@
1
- /** Horizontal facing derived from an orbit camera orbiting a target on the XZ plane. */
1
+ /** Horizontal facing derived from an orbit camera orbiting a target on the XZ plane.
2
+ * @internal
3
+ */
2
4
  export function orbitYawFromCamera(cameraX, cameraZ, targetX, targetZ) {
3
5
  const dx = targetX - cameraX;
4
6
  const dz = targetZ - cameraZ;
5
7
  return Math.atan2(dx, dz);
6
8
  }
7
- /** Elevation the camera looks along (radians): negative = aiming down, positive = aiming up, 0 = level. Feeds aim.pitch so vertical aim tracks the camera. */
9
+ /** Elevation the camera looks along (radians): negative = aiming down, positive = aiming up, 0 = level. Feeds aim.pitch so vertical aim tracks the camera.
10
+ * @internal
11
+ */
8
12
  export function cameraLookPitch(camera, target) {
9
13
  const horizontal = Math.hypot(target.x - camera.x, target.z - camera.z);
10
14
  return Math.atan2(target.y - camera.y, horizontal);
@@ -31,23 +35,48 @@ export const DEFAULT_ORBIT_CAMERA = {
31
35
  export const GAME_SIM_FRAME_PRIORITY = 0;
32
36
  /** Orbit follow reads the latest entity pose after GAME_SIM_FRAME_PRIORITY. */
33
37
  export const ORBIT_CAMERA_FRAME_PRIORITY = -1;
34
- /** Frame-rate independent exponential smoothing factor in [0, 1]. */
38
+ /** Frame-rate independent exponential smoothing factor in [0, 1].
39
+ * @internal
40
+ */
35
41
  export function smoothBlend(deltaSeconds, speed) {
36
42
  return 1 - Math.exp(-speed * deltaSeconds);
37
43
  }
44
+ /** @internal */
38
45
  export function resolveOrbitCameraConfig(patch) {
39
- return {
46
+ const resolved = {
40
47
  ...DEFAULT_ORBIT_CAMERA,
41
48
  ...patch,
42
49
  collision: { ...DEFAULT_ORBIT_CAMERA.collision, ...patch?.collision },
43
50
  };
51
+ if (patch?.pitchClamp !== undefined) {
52
+ const [minPitch, maxPitch] = patch.pitchClamp;
53
+ resolved.minPolarAngle = patch.minPolarAngle ?? Math.PI / 2 - maxPitch;
54
+ resolved.maxPolarAngle = patch.maxPolarAngle ?? Math.PI / 2 - minPitch;
55
+ }
56
+ return resolved;
44
57
  }
58
+ /**
59
+ * FOV that keeps a target's on-screen size constant as the spring-arm pulls the
60
+ * camera in. Widens the base FOV by the desired/pulled distance ratio; a no-op
61
+ * (returns the base) whenever the camera sits at or beyond its desired distance.
62
+ * @internal
63
+ */
64
+ export function compensatedFov(baseFovDegrees, desiredDistance, pulledDistance) {
65
+ if (pulledDistance <= 0 || desiredDistance <= 0 || pulledDistance >= desiredDistance) {
66
+ return baseFovDegrees;
67
+ }
68
+ const half = (baseFovDegrees * Math.PI) / 360;
69
+ const widened = 2 * Math.atan(Math.tan(half) * (desiredDistance / pulledDistance));
70
+ return Math.min((widened * 180) / Math.PI, 170);
71
+ }
72
+ /** @internal */
45
73
  export function resolveTargetSmoothing(config, dragging) {
46
74
  if (dragging) {
47
75
  return config.dragTargetSmoothing;
48
76
  }
49
77
  return config.targetSmoothing;
50
78
  }
79
+ /** @internal */
51
80
  export function resolveFollowTargetFromPosition(position, config) {
52
81
  const offset = config.targetOffset;
53
82
  return {
@@ -56,6 +85,7 @@ export function resolveFollowTargetFromPosition(position, config) {
56
85
  z: position[2] + (offset?.z ?? 0),
57
86
  };
58
87
  }
88
+ /** @internal */
59
89
  export function lerpVec3(from, to, blend) {
60
90
  return {
61
91
  x: from.x + (to.x - from.x) * blend,
@@ -63,14 +93,31 @@ export function lerpVec3(from, to, blend) {
63
93
  z: from.z + (to.z - from.z) * blend,
64
94
  };
65
95
  }
96
+ /** @internal */
66
97
  export function distanceBetween(a, b) {
67
98
  const dx = a.x - b.x;
68
99
  const dy = a.y - b.y;
69
100
  const dz = a.z - b.z;
70
101
  return Math.sqrt(dx * dx + dy * dy + dz * dz);
71
102
  }
103
+ /** @internal */
72
104
  export function seedOrbitFollowState(input) {
73
105
  const target = resolveFollowTargetFromPosition(input.entityPosition, input.config);
106
+ const { initialDistance, initialYaw, initialPitch } = input.config;
107
+ if (initialYaw !== undefined || initialPitch !== undefined) {
108
+ const yaw = initialYaw ?? 0;
109
+ const pitch = initialPitch ?? Math.atan2(input.config.initialHeight - input.config.targetHeight, initialDistance);
110
+ const horizontal = initialDistance * Math.cos(pitch);
111
+ return {
112
+ target,
113
+ camera: {
114
+ x: target.x - horizontal * Math.sin(yaw),
115
+ y: target.y + initialDistance * Math.sin(pitch),
116
+ z: target.z - horizontal * Math.cos(yaw),
117
+ },
118
+ lockedDistance: initialDistance,
119
+ };
120
+ }
74
121
  return {
75
122
  target,
76
123
  camera: {
@@ -85,7 +132,8 @@ export function seedOrbitFollowState(input) {
85
132
  * Pure orbit follow step — smooth target tracking, camera carries target delta
86
133
  * (OrbitControls alone keeps camera fixed when only target moves), optional
87
134
  * distance lock. Call each frame before OrbitControls.update() in the shell.
88
- */
135
+ * @internal
136
+ */
89
137
  export function orbitFollowStep(input) {
90
138
  const target = { ...input.state.target };
91
139
  const camera = { ...input.state.camera };
@@ -124,7 +172,9 @@ export function orbitFollowStep(input) {
124
172
  }
125
173
  return { target, camera, lockedDistance, distance: distanceBetween(camera, target) };
126
174
  }
127
- /** @deprecated Use orbitFollowStep — kept for older call sites. */
175
+ /** @deprecated Use orbitFollowStep — kept for older call sites.
176
+ * @internal
177
+ */
128
178
  export function cameraFollowStep(input) {
129
179
  const state = {
130
180
  target: input.previousTarget ?? input.target,
@@ -6,12 +6,19 @@ export interface CameraPose {
6
6
  lookAt: Vec3;
7
7
  fov: number;
8
8
  }
9
+ /** @internal */
9
10
  export declare function rtsPanKeysConflict(input: ActionCodesMap | undefined): boolean;
11
+ /** @internal */
10
12
  export declare function clamp(value: number, min: number, max: number): number;
13
+ /** @internal */
11
14
  export declare function lerp(from: number, to: number, blend: number): number;
15
+ /** @internal */
12
16
  export declare function smoothstep(t: number): number;
17
+ /** @internal */
13
18
  export declare function forwardVector(yaw: number): Vec3;
14
- /** Screen-right of a yaw: `forward × up` with up = +Y. */
19
+ /** Screen-right of a yaw: `forward × up` with up = +Y.
20
+ * @internal
21
+ */
15
22
  export declare function rightVector(yaw: number): Vec3;
16
23
  export interface ResolvedTopDown {
17
24
  height: number;
@@ -20,15 +27,19 @@ export interface ResolvedTopDown {
20
27
  offset: Vec3;
21
28
  followSmoothing: number;
22
29
  }
30
+ /** @internal */
23
31
  export declare function resolveTopDown(config: TopDownCameraConfig | undefined): ResolvedTopDown;
24
32
  /**
25
33
  * Camera pose for a fixed top-down / isometric rig. `pitch` is the elevation of
26
34
  * the camera→target ray above the ground (PI/2 = straight down); `yaw` is the
27
35
  * fixed azimuth (PI/4 reads isometric). Height sets zoom; horizontal boom is
28
36
  * derived so the look angle stays constant as height changes.
29
- */
37
+ * @internal
38
+ */
30
39
  export declare function topDownPose(follow: Vec3, resolved: ResolvedTopDown, fov: number): CameraPose;
31
- /** Exponential spring-arm approach toward a desired point (frame-rate independent). */
40
+ /** Exponential spring-arm approach toward a desired point (frame-rate independent).
41
+ * @internal
42
+ */
32
43
  export declare function springArmStep(current: Vec3, desired: Vec3, damping: number, dt: number): Vec3;
33
44
  export interface ResolvedSideScroll {
34
45
  axis: "x" | "z";
@@ -37,26 +48,38 @@ export interface ResolvedSideScroll {
37
48
  lookHeight: number;
38
49
  followSmoothing: number;
39
50
  }
51
+ /** @internal */
40
52
  export declare function resolveSideScroll(config: SideScrollCameraConfig | undefined): ResolvedSideScroll;
41
- /** Frame-rate independent follow blend for the side-scroll rig; `followSmoothing <= 0` hard-locks (blend 1) instead of freezing. */
53
+ /** Frame-rate independent follow blend for the side-scroll rig; `followSmoothing <= 0` hard-locks (blend 1) instead of freezing.
54
+ * @internal
55
+ */
42
56
  export declare function sideScrollFollowBlend(followSmoothing: number, dt: number): number;
43
57
  /**
44
58
  * Fixed lateral 2.5D follow pose: the camera sits perpendicular to the travel
45
59
  * axis at `distance`, above the entity by `height`, and looks at the entity
46
60
  * raised by `lookHeight`. Axis "x" watches from +z; axis "z" watches from +x.
47
- */
61
+ * @internal
62
+ */
48
63
  export declare function resolveSideScrollPose(entityPos: Vec3, resolved: ResolvedSideScroll, fov: number): CameraPose;
49
- /** Speed→FOV curve: FOV climbs from base to max as speed rises to `speedForMax`. */
64
+ /** Speed→FOV curve: FOV climbs from base to max as speed rises to `speedForMax`.
65
+ * @internal
66
+ */
50
67
  export declare function speedToFov(speed: number, curve: {
51
68
  base?: number;
52
69
  max?: number;
53
70
  speedForMax?: number;
54
71
  } | undefined): number;
55
- /** Yaw that points from `from` toward `to` on the XZ plane (matches shell forward = (sin, cos)). */
72
+ /** Yaw that points from `from` toward `to` on the XZ plane (matches shell forward = (sin, cos)).
73
+ * @internal
74
+ */
56
75
  export declare function yawTo(from: Vec3, to: Vec3): number;
57
- /** Shortest signed angular delta from `a` to `b`, wrapped to (-PI, PI]. */
76
+ /** Shortest signed angular delta from `a` to `b`, wrapped to (-PI, PI].
77
+ * @internal
78
+ */
58
79
  export declare function angleDelta(a: number, b: number): number;
59
- /** Exponential yaw smoothing that respects wrap-around. */
80
+ /** Exponential yaw smoothing that respects wrap-around.
81
+ * @internal
82
+ */
60
83
  export declare function smoothYaw(current: number, desired: number, speed: number, dt: number): number;
61
84
  export interface ResolvedShoulder {
62
85
  shoulderOffset: number;
@@ -64,20 +87,25 @@ export interface ResolvedShoulder {
64
87
  distance: number;
65
88
  fov: number;
66
89
  }
90
+ /** @internal */
67
91
  export declare function resolveShoulder(config: ShoulderCameraConfig | undefined, aiming: boolean): ResolvedShoulder;
68
- /** Blend two shoulder framings by an ADS factor in [0,1]. */
92
+ /** Blend two shoulder framings by an ADS factor in [0,1].
93
+ * @internal
94
+ */
69
95
  export declare function blendShoulder(hip: ResolvedShoulder, ads: ResolvedShoulder, t: number): ResolvedShoulder;
70
96
  /**
71
97
  * Over-the-shoulder camera pose. The boom sits behind the follow point along
72
98
  * `yaw`, raised by `heightOffset`, and pushed sideways by `shoulderOffset`
73
99
  * (sign set by `sideSign`: +1 right, -1 left). `pitch` tilts the look point.
74
- */
100
+ * @internal
101
+ */
75
102
  export declare function shoulderPose(follow: Vec3, yaw: number, pitch: number, sideSign: number, shoulder: ResolvedShoulder): CameraPose;
76
103
  /**
77
104
  * Lock-on pose: camera sits behind the player along the player→target vector so
78
105
  * the target stays framed. The look point is biased between player and target
79
106
  * by `framingBias`.
80
- */
107
+ * @internal
108
+ */
81
109
  export declare function lockOnPose(player: Vec3, target: Vec3, config: LockOnCameraConfig | undefined, fov: number): {
82
110
  pose: CameraPose;
83
111
  yaw: number;
@@ -94,10 +122,15 @@ export interface ResolvedChase {
94
122
  bankMax: number;
95
123
  bankDamping: number;
96
124
  }
125
+ /** @internal */
97
126
  export declare function resolveChase(config: ChaseCameraConfig | undefined): ResolvedChase;
98
- /** Velocity-lead the follow point (#286.9): aim `leadTime` seconds along the target's frame velocity, clamped to `leadMax`. */
127
+ /** Velocity-lead the follow point (#286.9): aim `leadTime` seconds along the target's frame velocity, clamped to `leadMax`.
128
+ * @internal
129
+ */
99
130
  export declare function leadFollowPoint(follow: Vec3, previous: Vec3, dt: number, resolved: ResolvedChase): Vec3;
100
- /** One smoothing step of the chase rig's turn-bank roll (#286.10): roll opposes yaw rate, clamped and exponentially damped. */
131
+ /** One smoothing step of the chase rig's turn-bank roll (#286.10): roll opposes yaw rate, clamped and exponentially damped.
132
+ * @internal
133
+ */
101
134
  export declare function bankRollStep(currentRoll: number, yaw: number, previousYaw: number, dt: number, resolved: ResolvedChase): number;
102
135
  export interface ResolvedObserver {
103
136
  distance: number;
@@ -105,14 +138,23 @@ export interface ResolvedObserver {
105
138
  lookHeight: number;
106
139
  orbitSpeed: number;
107
140
  }
141
+ /** @internal */
108
142
  export declare function resolveObserver(config: ObserverCameraConfig | undefined): ResolvedObserver;
109
- /** Detached spectator pose: orbits `subject` at a fixed distance/height, never reading player input. */
143
+ /** Detached spectator pose: orbits `subject` at a fixed distance/height, never reading player input.
144
+ * @internal
145
+ */
110
146
  export declare function observerPose(subject: Vec3, angle: number, resolved: ResolvedObserver, fov: number): CameraPose;
111
- /** Desired chase-camera position behind a vehicle facing `yaw` (before spring smoothing). */
147
+ /** Desired chase-camera position behind a vehicle facing `yaw` (before spring smoothing).
148
+ * @internal
149
+ */
112
150
  export declare function chaseDesiredPosition(follow: Vec3, yaw: number, resolved: ResolvedChase): Vec3;
113
- /** Look point ahead of / above a chased vehicle. */
151
+ /** Look point ahead of / above a chased vehicle.
152
+ * @internal
153
+ */
114
154
  export declare function chaseLookAt(follow: Vec3, yaw: number, resolved: ResolvedChase): Vec3;
115
- /** World-space seat pose (cockpit/hood/rear) rigidly attached to the vehicle. */
155
+ /** World-space seat pose (cockpit/hood/rear) rigidly attached to the vehicle.
156
+ * @internal
157
+ */
116
158
  export declare function seatPose(follow: Vec3, yaw: number, local: {
117
159
  x?: number;
118
160
  y?: number;
@@ -122,10 +164,15 @@ export interface TraumaState {
122
164
  trauma: number;
123
165
  time: number;
124
166
  }
167
+ /** @internal */
125
168
  export declare function createTrauma(): TraumaState;
126
- /** Add trauma (0..1) and clamp; larger hits raise the ceiling toward 1. */
169
+ /** Add trauma (0..1) and clamp; larger hits raise the ceiling toward 1.
170
+ * @internal
171
+ */
127
172
  export declare function addTrauma(state: TraumaState, amount: number): void;
128
- /** Decay trauma linearly toward 0 and advance the shake clock. */
173
+ /** Decay trauma linearly toward 0 and advance the shake clock.
174
+ * @internal
175
+ */
129
176
  export declare function stepTrauma(state: TraumaState, decayPerSecond: number, dt: number): void;
130
177
  export interface ShakeOffset {
131
178
  x: number;
@@ -136,14 +183,35 @@ export interface ShakeOffset {
136
183
  * Positional + roll shake for the current trauma. Shake magnitude is
137
184
  * `trauma^exponent` so small hits stay subtle; the oscillation is deterministic
138
185
  * per-seed pseudo-noise (no per-frame RNG, so identical inputs reproduce).
139
- */
186
+ * @internal
187
+ */
140
188
  export declare function shakeOffset(state: TraumaState, config: {
141
189
  maxOffset?: number;
142
190
  maxRoll?: number;
143
191
  exponent?: number;
144
192
  frequency?: number;
145
193
  } | undefined): ShakeOffset;
146
- /** Linear cross-fade between two full camera poses (position, lookAt, fov). */
194
+ /** Calibrated trauma decay for `traumaShake`/`impactPresets` (trauma/second). */
195
+ export declare const CALIBRATED_TRAUMA_SHAKE_DECAY_PER_SECOND = 1.4;
196
+ /** Calibrated positional shake amplitude at full trauma (world units) for `traumaShake`. */
197
+ export declare const CALIBRATED_TRAUMA_SHAKE_MAX_OFFSET = 0.55;
198
+ /** Calibrated rotational shake amplitude at full trauma (radians) for `traumaShake`. */
199
+ export declare const CALIBRATED_TRAUMA_SHAKE_MAX_ROLL = 0.1;
200
+ /** Calibrated shake noise frequency (Hz) for `traumaShake`. */
201
+ export declare const CALIBRATED_TRAUMA_SHAKE_FREQUENCY = 32;
202
+ /**
203
+ * Calibrated trauma² camera shake: offset scales with `trauma` squared using
204
+ * game-feel defaults (decay 1.4/s, max offset 0.55, max roll 0.1 rad, noise
205
+ * freq 32×t) — the curve `impactPresets` trauma values are calibrated
206
+ * against, so an impact "just looks right" without hand-tuning `shakeOffset`.
207
+ *
208
+ * @capability camera-shake calibrated trauma² camera kick with zero tuning
209
+ * @internal
210
+ */
211
+ export declare function traumaShake(trauma: number, time?: number): ShakeOffset;
212
+ /** Linear cross-fade between two full camera poses (position, lookAt, fov).
213
+ * @internal
214
+ */
147
215
  export declare function crossfadePose(from: CameraPose, to: CameraPose, t: number): CameraPose;
148
216
  export interface DirectorCameraValues {
149
217
  /** `undefined` = no runtime override (fall back to static); `null` = explicitly follow nothing. */
@@ -164,7 +232,8 @@ export interface ResolvedDirectedCamera {
164
232
  * (#196.2). `director` omitted, or its fields `undefined`/`null`, is a pure
165
233
  * passthrough to `staticConfig` so mounting a director with no active override
166
234
  * changes nothing.
167
- */
235
+ * @internal
236
+ */
168
237
  export declare function resolveDirectedCamera(director: DirectorCameraValues | undefined, staticConfig: StaticCameraValues): ResolvedDirectedCamera;
169
238
  export interface CinematicSample {
170
239
  pose: CameraPose;
@@ -175,5 +244,6 @@ export interface CinematicSample {
175
244
  * travel time from the previous keyframe into it; segment easing is per the
176
245
  * destination keyframe. Reports `done` once past the final keyframe (unless
177
246
  * looping, which wraps `elapsed` into the total path duration).
178
- */
247
+ * @internal
248
+ */
179
249
  export declare function cinematicSample(keyframes: readonly CameraKeyframe[], elapsed: number, loop: boolean, fallbackFov: number): CinematicSample;