@woosh/meep-engine 2.138.19 → 2.139.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 (496) hide show
  1. package/package.json +2 -1
  2. package/src/core/collection/PairUint32Map.d.ts +100 -0
  3. package/src/core/collection/PairUint32Map.d.ts.map +1 -0
  4. package/src/core/collection/PairUint32Map.js +321 -0
  5. package/src/core/collection/Uint32Map.d.ts +119 -0
  6. package/src/core/collection/Uint32Map.d.ts.map +1 -0
  7. package/src/core/collection/Uint32Map.js +345 -0
  8. package/src/core/collection/array/array_shuffle.d.ts +10 -3
  9. package/src/core/collection/array/array_shuffle.d.ts.map +1 -1
  10. package/src/core/collection/array/array_shuffle.js +27 -22
  11. package/src/core/collection/heap/FibonacciHeap.d.ts +195 -0
  12. package/src/core/collection/heap/FibonacciHeap.d.ts.map +1 -0
  13. package/src/core/collection/heap/FibonacciHeap.js +586 -0
  14. package/src/core/collection/heap/Uint32Heap.js +1 -1
  15. package/src/core/collection/heap/Uint32Heap4.d.ts +169 -0
  16. package/src/core/collection/heap/Uint32Heap4.d.ts.map +1 -0
  17. package/src/core/collection/heap/Uint32Heap4.js +490 -0
  18. package/src/core/geom/3d/line/line3_closest_points_segment_segment.d.ts +27 -0
  19. package/src/core/geom/3d/line/line3_closest_points_segment_segment.d.ts.map +1 -0
  20. package/src/core/geom/3d/line/line3_closest_points_segment_segment.js +88 -0
  21. package/src/core/geom/3d/shape/BoxShape3D.d.ts +61 -0
  22. package/src/core/geom/3d/shape/BoxShape3D.d.ts.map +1 -0
  23. package/src/core/geom/3d/shape/BoxShape3D.js +158 -0
  24. package/src/core/geom/3d/shape/CapsuleShape3D.d.ts +11 -0
  25. package/src/core/geom/3d/shape/CapsuleShape3D.d.ts.map +1 -1
  26. package/src/core/geom/3d/shape/CapsuleShape3D.js +12 -0
  27. package/src/core/geom/3d/shape/UnitCubeShape3D.d.ts +37 -9
  28. package/src/core/geom/3d/shape/UnitCubeShape3D.d.ts.map +1 -1
  29. package/src/core/geom/3d/shape/UnitCubeShape3D.js +45 -98
  30. package/src/core/geom/3d/shape/UnitSphereShape3D.d.ts +10 -0
  31. package/src/core/geom/3d/shape/UnitSphereShape3D.d.ts.map +1 -1
  32. package/src/core/geom/3d/shape/UnitSphereShape3D.js +11 -0
  33. package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.d.ts +61 -0
  34. package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.d.ts.map +1 -0
  35. package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.js +148 -0
  36. package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.d.ts +39 -0
  37. package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.d.ts.map +1 -0
  38. package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.js +147 -0
  39. package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.d.ts +15 -0
  40. package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.d.ts.map +1 -0
  41. package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.js +22 -0
  42. package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.d.ts +2 -0
  43. package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.d.ts.map +1 -0
  44. package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.js +673 -0
  45. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.d.ts +26 -0
  46. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.d.ts.map +1 -0
  47. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.js +222 -0
  48. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.d.ts +34 -0
  49. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.d.ts.map +1 -0
  50. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.js +146 -0
  51. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.d.ts +36 -0
  52. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.d.ts.map +1 -0
  53. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.js +232 -0
  54. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.d.ts +33 -0
  55. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.d.ts.map +1 -0
  56. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.js +255 -0
  57. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.d.ts +68 -0
  58. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.d.ts.map +1 -0
  59. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.js +365 -0
  60. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts +31 -0
  61. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts.map +1 -0
  62. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.js +112 -0
  63. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts +22 -0
  64. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts.map +1 -0
  65. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.js +55 -0
  66. package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.d.ts +32 -0
  67. package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.d.ts.map +1 -0
  68. package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.js +66 -0
  69. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts +22 -0
  70. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts.map +1 -1
  71. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.js +49 -0
  72. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts +134 -0
  73. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts.map +1 -1
  74. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +276 -3
  75. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts +17 -0
  76. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts.map +1 -0
  77. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +135 -0
  78. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.d.ts +14 -0
  79. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.d.ts.map +1 -0
  80. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.js +177 -0
  81. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.d.ts.map +1 -1
  82. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.js +20 -4
  83. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
  84. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +5 -3
  85. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.d.ts.map +1 -1
  86. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.js +9 -0
  87. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_get_or_create.d.ts.map +1 -1
  88. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_get_or_create.js +21 -45
  89. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill.d.ts.map +1 -1
  90. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill.js +7 -1
  91. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.d.ts +8 -6
  92. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.d.ts.map +1 -1
  93. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.js +8 -6
  94. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.d.ts +22 -0
  95. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.d.ts.map +1 -0
  96. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.js +73 -0
  97. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.d.ts.map +1 -1
  98. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.js +51 -1
  99. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.d.ts +10 -0
  100. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.d.ts.map +1 -0
  101. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.js +42 -0
  102. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.d.ts +28 -0
  103. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.d.ts.map +1 -0
  104. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.js +227 -0
  105. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.d.ts +13 -0
  106. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.d.ts.map +1 -0
  107. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.js +108 -0
  108. package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.d.ts +11 -0
  109. package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.d.ts.map +1 -0
  110. package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.js +20 -0
  111. package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.d.ts +20 -0
  112. package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.d.ts.map +1 -0
  113. package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.js +38 -0
  114. package/src/core/graph/csr/CSRGraph.d.ts +168 -0
  115. package/src/core/graph/csr/CSRGraph.d.ts.map +1 -0
  116. package/src/core/graph/csr/CSRGraph.js +319 -0
  117. package/src/core/graph/metis/cluster_mesh_metis.d.ts +12 -0
  118. package/src/core/graph/metis/cluster_mesh_metis.d.ts.map +1 -1
  119. package/src/core/graph/metis/cluster_mesh_metis.js +12 -0
  120. package/src/core/graph/metis/metis.d.ts +19 -0
  121. package/src/core/graph/metis/metis.d.ts.map +1 -1
  122. package/src/core/graph/metis/metis.js +20 -0
  123. package/src/core/graph/metis/metis_cluster_bs.d.ts +11 -0
  124. package/src/core/graph/metis/metis_cluster_bs.d.ts.map +1 -1
  125. package/src/core/graph/metis/metis_cluster_bs.js +11 -0
  126. package/src/core/graph/metis/metis_options.d.ts +17 -2
  127. package/src/core/graph/metis/metis_options.d.ts.map +1 -1
  128. package/src/core/graph/metis/metis_options.js +17 -2
  129. package/src/core/graph/metis/native/MetisGraph.d.ts +144 -0
  130. package/src/core/graph/metis/native/MetisGraph.d.ts.map +1 -0
  131. package/src/core/graph/metis/native/MetisGraph.js +212 -0
  132. package/src/core/graph/metis/native/bisection/BisectionScratch.d.ts +72 -0
  133. package/src/core/graph/metis/native/bisection/BisectionScratch.d.ts.map +1 -0
  134. package/src/core/graph/metis/native/bisection/BisectionScratch.js +101 -0
  135. package/src/core/graph/metis/native/bisection/bisect_graph.d.ts +37 -0
  136. package/src/core/graph/metis/native/bisection/bisect_graph.d.ts.map +1 -0
  137. package/src/core/graph/metis/native/bisection/bisect_graph.js +100 -0
  138. package/src/core/graph/metis/native/bisection/compute_2way_params.d.ts +15 -0
  139. package/src/core/graph/metis/native/bisection/compute_2way_params.d.ts.map +1 -0
  140. package/src/core/graph/metis/native/bisection/compute_2way_params.js +84 -0
  141. package/src/core/graph/metis/native/bisection/fm_2way.d.ts +30 -0
  142. package/src/core/graph/metis/native/bisection/fm_2way.d.ts.map +1 -0
  143. package/src/core/graph/metis/native/bisection/fm_2way.js +290 -0
  144. package/src/core/graph/metis/native/bisection/grow_bisection.d.ts +23 -0
  145. package/src/core/graph/metis/native/bisection/grow_bisection.d.ts.map +1 -0
  146. package/src/core/graph/metis/native/bisection/grow_bisection.js +137 -0
  147. package/src/core/graph/metis/native/bisection/split_graph_two_way.d.ts +28 -0
  148. package/src/core/graph/metis/native/bisection/split_graph_two_way.d.ts.map +1 -0
  149. package/src/core/graph/metis/native/bisection/split_graph_two_way.js +119 -0
  150. package/src/core/graph/metis/native/coarsen/coarsen_graph.d.ts +20 -0
  151. package/src/core/graph/metis/native/coarsen/coarsen_graph.d.ts.map +1 -0
  152. package/src/core/graph/metis/native/coarsen/coarsen_graph.js +94 -0
  153. package/src/core/graph/metis/native/coarsen/create_coarse_graph.d.ts +24 -0
  154. package/src/core/graph/metis/native/coarsen/create_coarse_graph.d.ts.map +1 -0
  155. package/src/core/graph/metis/native/coarsen/create_coarse_graph.js +158 -0
  156. package/src/core/graph/metis/native/coarsen/match_shem.d.ts +41 -0
  157. package/src/core/graph/metis/native/coarsen/match_shem.d.ts.map +1 -0
  158. package/src/core/graph/metis/native/coarsen/match_shem.js +175 -0
  159. package/src/core/graph/metis/native/initial/initial_kway_bfs.d.ts +24 -0
  160. package/src/core/graph/metis/native/initial/initial_kway_bfs.d.ts.map +1 -0
  161. package/src/core/graph/metis/native/initial/initial_kway_bfs.js +122 -0
  162. package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.d.ts +29 -0
  163. package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.d.ts.map +1 -0
  164. package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.js +170 -0
  165. package/src/core/graph/metis/native/metis_partition_kway.d.ts +41 -0
  166. package/src/core/graph/metis/native/metis_partition_kway.d.ts.map +1 -0
  167. package/src/core/graph/metis/native/metis_partition_kway.js +126 -0
  168. package/src/core/graph/metis/native/refine/IndexedFloatMaxHeap.d.ts +62 -0
  169. package/src/core/graph/metis/native/refine/IndexedFloatMaxHeap.d.ts.map +1 -0
  170. package/src/core/graph/metis/native/refine/IndexedFloatMaxHeap.js +261 -0
  171. package/src/core/graph/metis/native/refine/RefinementScratch.d.ts +45 -0
  172. package/src/core/graph/metis/native/refine/RefinementScratch.d.ts.map +1 -0
  173. package/src/core/graph/metis/native/refine/RefinementScratch.js +53 -0
  174. package/src/core/graph/metis/native/refine/compute_kway_params.d.ts +18 -0
  175. package/src/core/graph/metis/native/refine/compute_kway_params.d.ts.map +1 -0
  176. package/src/core/graph/metis/native/refine/compute_kway_params.js +138 -0
  177. package/src/core/graph/metis/native/refine/fm_kway.d.ts +63 -0
  178. package/src/core/graph/metis/native/refine/fm_kway.d.ts.map +1 -0
  179. package/src/core/graph/metis/native/refine/fm_kway.js +462 -0
  180. package/src/core/graph/metis/native/refine/project_kway.d.ts +22 -0
  181. package/src/core/graph/metis/native/refine/project_kway.d.ts.map +1 -0
  182. package/src/core/graph/metis/native/refine/project_kway.js +43 -0
  183. package/src/core/graph/metis/native/refine/refine_kway.d.ts +34 -0
  184. package/src/core/graph/metis/native/refine/refine_kway.d.ts.map +1 -0
  185. package/src/core/graph/metis/native/refine/refine_kway.js +43 -0
  186. package/src/core/math/linalg/eigen/matrix_householder_in_place.d.ts +2 -2
  187. package/src/core/math/linalg/eigen/matrix_householder_in_place.js +2 -2
  188. package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts +6 -4
  189. package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts.map +1 -1
  190. package/src/core/math/linalg/eigen/matrix_qr_in_place.js +69 -23
  191. package/src/engine/EngineHarness.d.ts +3 -1
  192. package/src/engine/EngineHarness.d.ts.map +1 -1
  193. package/src/engine/EngineHarness.js +6 -4
  194. package/src/engine/control/first-person/DESIGN.md +30 -6
  195. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +563 -0
  196. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +102 -9
  197. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
  198. package/src/engine/control/first-person/FirstPersonPlayerController.js +38 -3
  199. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +533 -4
  200. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
  201. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +315 -6
  202. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +220 -22
  203. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
  204. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +858 -241
  205. package/src/engine/control/first-person/TODO.md +127 -0
  206. package/src/engine/control/first-person/abilities/Ability.d.ts +101 -0
  207. package/src/engine/control/first-person/abilities/Ability.d.ts.map +1 -0
  208. package/src/engine/control/first-person/abilities/Ability.js +119 -0
  209. package/src/engine/control/first-person/abilities/AbilitySet.d.ts +86 -0
  210. package/src/engine/control/first-person/abilities/AbilitySet.d.ts.map +1 -0
  211. package/src/engine/control/first-person/abilities/AbilitySet.js +185 -0
  212. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts +62 -0
  213. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -0
  214. package/src/engine/control/first-person/abilities/LedgeGrab.js +199 -0
  215. package/src/engine/control/first-person/abilities/Mantle.d.ts +45 -0
  216. package/src/engine/control/first-person/abilities/Mantle.d.ts.map +1 -0
  217. package/src/engine/control/first-person/abilities/Mantle.js +188 -0
  218. package/src/engine/control/first-person/abilities/Slide.d.ts +33 -0
  219. package/src/engine/control/first-person/abilities/Slide.d.ts.map +1 -0
  220. package/src/engine/control/first-person/abilities/Slide.js +158 -0
  221. package/src/engine/control/first-person/abilities/WallJump.d.ts +45 -0
  222. package/src/engine/control/first-person/abilities/WallJump.d.ts.map +1 -0
  223. package/src/engine/control/first-person/abilities/WallJump.js +131 -0
  224. package/src/engine/control/first-person/abilities/WallRun.d.ts +44 -0
  225. package/src/engine/control/first-person/abilities/WallRun.d.ts.map +1 -0
  226. package/src/engine/control/first-person/abilities/WallRun.js +180 -0
  227. package/src/engine/control/first-person/composer/EyeOffsetStack.d.ts +49 -0
  228. package/src/engine/control/first-person/composer/EyeOffsetStack.d.ts.map +1 -0
  229. package/src/engine/control/first-person/composer/EyeOffsetStack.js +60 -0
  230. package/src/engine/control/first-person/mastery/BreathRhythmEvaluator.d.ts +100 -0
  231. package/src/engine/control/first-person/mastery/BreathRhythmEvaluator.d.ts.map +1 -0
  232. package/src/engine/control/first-person/mastery/BreathRhythmEvaluator.js +133 -0
  233. package/src/engine/control/first-person/mastery/DecisionPoint.d.ts +10 -0
  234. package/src/engine/control/first-person/mastery/DecisionPoint.d.ts.map +1 -0
  235. package/src/engine/control/first-person/mastery/DecisionPoint.js +30 -0
  236. package/src/engine/control/first-person/mastery/FootAsymmetryTurnEvaluator.d.ts +61 -0
  237. package/src/engine/control/first-person/mastery/FootAsymmetryTurnEvaluator.d.ts.map +1 -0
  238. package/src/engine/control/first-person/mastery/FootAsymmetryTurnEvaluator.js +109 -0
  239. package/src/engine/control/first-person/mastery/MasteryEvaluator.d.ts +40 -0
  240. package/src/engine/control/first-person/mastery/MasteryEvaluator.d.ts.map +1 -0
  241. package/src/engine/control/first-person/mastery/MasteryEvaluator.js +45 -0
  242. package/src/engine/control/first-person/mastery/MasteryScore.d.ts +68 -0
  243. package/src/engine/control/first-person/mastery/MasteryScore.d.ts.map +1 -0
  244. package/src/engine/control/first-person/mastery/MasteryScore.js +100 -0
  245. package/src/engine/control/first-person/mastery/MasterySet.d.ts +60 -0
  246. package/src/engine/control/first-person/mastery/MasterySet.d.ts.map +1 -0
  247. package/src/engine/control/first-person/mastery/MasterySet.js +86 -0
  248. package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts +58 -0
  249. package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts.map +1 -0
  250. package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.js +83 -0
  251. package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts +69 -0
  252. package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts.map +1 -0
  253. package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.js +109 -0
  254. package/src/engine/control/first-person/math/Spring.d.ts +56 -0
  255. package/src/engine/control/first-person/math/Spring.d.ts.map +1 -0
  256. package/src/engine/control/first-person/math/Spring.js +71 -0
  257. package/src/engine/control/first-person/math/computeLRCBreathRate.d.ts +26 -0
  258. package/src/engine/control/first-person/math/computeLRCBreathRate.d.ts.map +1 -0
  259. package/src/engine/control/first-person/math/computeLRCBreathRate.js +41 -0
  260. package/src/engine/control/first-person/math/computeMassRatios.d.ts +35 -0
  261. package/src/engine/control/first-person/math/computeMassRatios.d.ts.map +1 -0
  262. package/src/engine/control/first-person/math/computeMassRatios.js +44 -0
  263. package/src/engine/control/first-person/pose/FirstPersonPose.d.ts +31 -1
  264. package/src/engine/control/first-person/pose/FirstPersonPose.d.ts.map +1 -1
  265. package/src/engine/control/first-person/pose/FirstPersonPose.js +49 -3
  266. package/src/engine/control/first-person/pose/FirstPersonPosture.d.ts +7 -0
  267. package/src/engine/control/first-person/pose/FirstPersonPosture.d.ts.map +1 -0
  268. package/src/engine/control/first-person/pose/FirstPersonPosture.js +27 -0
  269. package/src/engine/control/first-person/prototype_first_person_controller.js +550 -119
  270. package/src/engine/control/first-person/sensors/FirstPersonSensors.d.ts +58 -0
  271. package/src/engine/control/first-person/sensors/FirstPersonSensors.d.ts.map +1 -0
  272. package/src/engine/control/first-person/sensors/FirstPersonSensors.js +77 -0
  273. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts +80 -0
  274. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts.map +1 -0
  275. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.js +196 -0
  276. package/src/engine/control/first-person/test/buildTestPlayer.d.ts +20 -0
  277. package/src/engine/control/first-person/test/buildTestPlayer.d.ts.map +1 -0
  278. package/src/engine/control/first-person/test/buildTestPlayer.js +28 -0
  279. package/src/engine/ecs/EntityManager.d.ts +2 -2
  280. package/src/engine/ecs/EntityManager.d.ts.map +1 -1
  281. package/src/engine/ecs/EntityManager.js +13 -8
  282. package/src/engine/ecs/System.d.ts.map +1 -1
  283. package/src/engine/ecs/System.js +2 -2
  284. package/src/engine/graphics/camera/testClippingPlaneComputation.js +0 -2
  285. package/src/engine/graphics/ecs/light/Light.d.ts.map +1 -1
  286. package/src/engine/graphics/ecs/light/Light.js +27 -0
  287. package/src/engine/graphics/ecs/light/LightSystem.js +1 -1
  288. package/src/engine/graphics/ecs/path/PathDisplaySystem.d.ts.map +1 -1
  289. package/src/engine/graphics/ecs/path/testPathDisplaySystem.js +0 -2
  290. package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +0 -2
  291. package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +0 -2
  292. package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +0 -2
  293. package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +0 -2
  294. package/src/engine/navigation/grid/find_path_on_grid_astar.d.ts.map +1 -1
  295. package/src/engine/navigation/grid/find_path_on_grid_astar.js +11 -2
  296. package/src/engine/navigation/mesh/bt_mesh_face_find_path.d.ts.map +1 -1
  297. package/src/engine/navigation/mesh/bt_mesh_face_find_path.js +11 -1
  298. package/src/engine/physics/PLAN.md +236 -0
  299. package/src/engine/physics/body/BodyStorage.d.ts +187 -0
  300. package/src/engine/physics/body/BodyStorage.d.ts.map +1 -0
  301. package/src/engine/physics/body/BodyStorage.js +427 -0
  302. package/src/engine/physics/broadphase/PairList.d.ts +62 -0
  303. package/src/engine/physics/broadphase/PairList.d.ts.map +1 -0
  304. package/src/engine/physics/broadphase/PairList.js +97 -0
  305. package/src/engine/physics/broadphase/aabb_transform_oriented.d.ts +30 -0
  306. package/src/engine/physics/broadphase/aabb_transform_oriented.d.ts.map +1 -0
  307. package/src/engine/physics/broadphase/aabb_transform_oriented.js +93 -0
  308. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts +16 -0
  309. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts.map +1 -0
  310. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +61 -0
  311. package/src/engine/physics/broadphase/generate_pairs.d.ts +38 -0
  312. package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -0
  313. package/src/engine/physics/broadphase/generate_pairs.js +101 -0
  314. package/src/engine/physics/contact/ManifoldStore.d.ts +226 -0
  315. package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -0
  316. package/src/engine/physics/contact/ManifoldStore.js +499 -0
  317. package/src/engine/physics/ecs/BodyKind.d.ts +23 -0
  318. package/src/engine/physics/ecs/BodyKind.d.ts.map +1 -0
  319. package/src/engine/physics/ecs/BodyKind.js +24 -0
  320. package/src/engine/physics/ecs/Collider.d.ts +98 -0
  321. package/src/engine/physics/ecs/Collider.d.ts.map +1 -0
  322. package/src/engine/physics/ecs/Collider.js +136 -0
  323. package/src/engine/physics/ecs/ColliderFlags.d.ts +14 -0
  324. package/src/engine/physics/ecs/ColliderFlags.d.ts.map +1 -0
  325. package/src/engine/physics/ecs/ColliderFlags.js +15 -0
  326. package/src/engine/physics/ecs/ColliderObserverSystem.d.ts +58 -0
  327. package/src/engine/physics/ecs/ColliderObserverSystem.d.ts.map +1 -0
  328. package/src/engine/physics/ecs/ColliderObserverSystem.js +103 -0
  329. package/src/engine/physics/ecs/ColliderSerializationAdapter.d.ts +25 -0
  330. package/src/engine/physics/ecs/ColliderSerializationAdapter.d.ts.map +1 -0
  331. package/src/engine/physics/ecs/ColliderSerializationAdapter.js +37 -0
  332. package/src/engine/physics/ecs/PhysicsEvents.d.ts +15 -0
  333. package/src/engine/physics/ecs/PhysicsEvents.d.ts.map +1 -0
  334. package/src/engine/physics/ecs/PhysicsEvents.js +16 -0
  335. package/src/engine/physics/ecs/PhysicsSystem.d.ts +520 -0
  336. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -0
  337. package/src/engine/physics/ecs/PhysicsSystem.js +1159 -0
  338. package/src/engine/physics/ecs/RigidBody.d.ts +197 -0
  339. package/src/engine/physics/ecs/RigidBody.d.ts.map +1 -0
  340. package/src/engine/physics/ecs/RigidBody.js +240 -0
  341. package/src/engine/physics/ecs/RigidBodyFlags.d.ts +21 -0
  342. package/src/engine/physics/ecs/RigidBodyFlags.d.ts.map +1 -0
  343. package/src/engine/physics/ecs/RigidBodyFlags.js +22 -0
  344. package/src/engine/physics/ecs/RigidBodySerializationAdapter.d.ts +28 -0
  345. package/src/engine/physics/ecs/RigidBodySerializationAdapter.d.ts.map +1 -0
  346. package/src/engine/physics/ecs/RigidBodySerializationAdapter.js +81 -0
  347. package/src/engine/physics/ecs/SleepState.d.ts +11 -0
  348. package/src/engine/physics/ecs/SleepState.d.ts.map +1 -0
  349. package/src/engine/physics/ecs/SleepState.js +12 -0
  350. package/src/engine/physics/events/ContactEventBuffer.d.ts +46 -0
  351. package/src/engine/physics/events/ContactEventBuffer.d.ts.map +1 -0
  352. package/src/engine/physics/events/ContactEventBuffer.js +83 -0
  353. package/src/engine/physics/events/diff_manifolds.d.ts +25 -0
  354. package/src/engine/physics/events/diff_manifolds.d.ts.map +1 -0
  355. package/src/engine/physics/events/diff_manifolds.js +50 -0
  356. package/src/engine/physics/fluid/FluidField.d.ts +294 -16
  357. package/src/engine/physics/fluid/FluidField.d.ts.map +1 -1
  358. package/src/engine/physics/fluid/FluidField.js +510 -66
  359. package/src/engine/physics/fluid/FluidSimulator.d.ts +188 -5
  360. package/src/engine/physics/fluid/FluidSimulator.d.ts.map +1 -1
  361. package/src/engine/physics/fluid/FluidSimulator.js +455 -95
  362. package/src/engine/physics/fluid/SliceVisualiser.d.ts +29 -6
  363. package/src/engine/physics/fluid/SliceVisualiser.d.ts.map +1 -1
  364. package/src/engine/physics/fluid/SliceVisualiser.js +190 -165
  365. package/src/engine/physics/fluid/ecs/FluidComponent.d.ts +154 -0
  366. package/src/engine/physics/fluid/ecs/FluidComponent.d.ts.map +1 -0
  367. package/src/engine/physics/fluid/ecs/FluidComponent.js +238 -0
  368. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.d.ts +45 -0
  369. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.d.ts.map +1 -0
  370. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.js +89 -0
  371. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +107 -0
  372. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts.map +1 -0
  373. package/src/engine/physics/fluid/ecs/FluidSystem.js +278 -0
  374. package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts +62 -1
  375. package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts.map +1 -1
  376. package/src/engine/physics/fluid/effector/AbstractFluidEffector.js +81 -6
  377. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts +17 -4
  378. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts.map +1 -1
  379. package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +105 -12
  380. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts +43 -0
  381. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts.map +1 -0
  382. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +210 -0
  383. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts +62 -1
  384. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts.map +1 -1
  385. package/src/engine/physics/fluid/effector/WakeFluidEffector.js +302 -8
  386. package/src/engine/physics/fluid/prototype.js +102 -91
  387. package/src/engine/physics/fluid/solver/optimal_sor_omega.d.ts +33 -0
  388. package/src/engine/physics/fluid/solver/optimal_sor_omega.d.ts.map +1 -0
  389. package/src/engine/physics/fluid/solver/optimal_sor_omega.js +41 -0
  390. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.d.ts +20 -5
  391. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.d.ts.map +1 -1
  392. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.js +60 -38
  393. package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.d.ts +25 -4
  394. package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.d.ts.map +1 -1
  395. package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.js +93 -73
  396. package/src/engine/physics/fluid/solver/v3_grid_apply_scalar_advection.d.ts +23 -0
  397. package/src/engine/physics/fluid/solver/v3_grid_apply_scalar_advection.d.ts.map +1 -0
  398. package/src/engine/physics/fluid/solver/v3_grid_apply_scalar_advection.js +60 -0
  399. package/src/engine/physics/fluid/solver/v3_grid_compute_divergence.d.ts +23 -0
  400. package/src/engine/physics/fluid/solver/v3_grid_compute_divergence.d.ts.map +1 -0
  401. package/src/engine/physics/fluid/solver/v3_grid_compute_divergence.js +68 -0
  402. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts +30 -0
  403. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts.map +1 -0
  404. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js +66 -0
  405. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.d.ts +26 -0
  406. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.d.ts.map +1 -0
  407. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.js +113 -0
  408. package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.d.ts +30 -0
  409. package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.d.ts.map +1 -0
  410. package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.js +107 -0
  411. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts +49 -0
  412. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts.map +1 -0
  413. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.js +126 -0
  414. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts +93 -0
  415. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts.map +1 -0
  416. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js +424 -0
  417. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts +20 -0
  418. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts.map +1 -0
  419. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.js +83 -0
  420. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts +26 -0
  421. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts.map +1 -0
  422. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +70 -0
  423. package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts.map +1 -1
  424. package/src/engine/physics/gjk/expanding_polytope_algorithm.js +8 -10
  425. package/src/engine/physics/inertia/world_inverse_inertia.d.ts +29 -0
  426. package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -0
  427. package/src/engine/physics/inertia/world_inverse_inertia.js +79 -0
  428. package/src/engine/physics/integration/integrate_position.d.ts +16 -0
  429. package/src/engine/physics/integration/integrate_position.d.ts.map +1 -0
  430. package/src/engine/physics/integration/integrate_position.js +48 -0
  431. package/src/engine/physics/integration/integrate_velocity.d.ts +25 -0
  432. package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -0
  433. package/src/engine/physics/integration/integrate_velocity.js +79 -0
  434. package/src/engine/physics/integration/quat_integrate.d.ts +27 -0
  435. package/src/engine/physics/integration/quat_integrate.d.ts.map +1 -0
  436. package/src/engine/physics/integration/quat_integrate.js +62 -0
  437. package/src/engine/physics/island/IslandBuilder.d.ts +167 -0
  438. package/src/engine/physics/island/IslandBuilder.d.ts.map +1 -0
  439. package/src/engine/physics/island/IslandBuilder.js +411 -0
  440. package/src/engine/physics/island/union_find.d.ts +51 -0
  441. package/src/engine/physics/island/union_find.d.ts.map +1 -0
  442. package/src/engine/physics/island/union_find.js +76 -0
  443. package/src/engine/physics/narrowphase/PosedShape.d.ts +59 -0
  444. package/src/engine/physics/narrowphase/PosedShape.d.ts.map +1 -0
  445. package/src/engine/physics/narrowphase/PosedShape.js +110 -0
  446. package/src/engine/physics/narrowphase/box_box_manifold.d.ts +32 -0
  447. package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -0
  448. package/src/engine/physics/narrowphase/box_box_manifold.js +543 -0
  449. package/src/engine/physics/narrowphase/capsule_contacts.d.ts +122 -0
  450. package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -0
  451. package/src/engine/physics/narrowphase/capsule_contacts.js +508 -0
  452. package/src/engine/physics/narrowphase/narrowphase_step.d.ts +11 -0
  453. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -0
  454. package/src/engine/physics/narrowphase/narrowphase_step.js +382 -0
  455. package/src/engine/physics/narrowphase/sphere_box_contact.d.ts +38 -0
  456. package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -0
  457. package/src/engine/physics/narrowphase/sphere_box_contact.js +130 -0
  458. package/src/engine/physics/narrowphase/sphere_sphere_contact.d.ts +26 -0
  459. package/src/engine/physics/narrowphase/sphere_sphere_contact.d.ts.map +1 -0
  460. package/src/engine/physics/narrowphase/sphere_sphere_contact.js +51 -0
  461. package/src/engine/physics/queries/PhysicsSurfacePoint.d.ts +83 -0
  462. package/src/engine/physics/queries/PhysicsSurfacePoint.d.ts.map +1 -0
  463. package/src/engine/physics/queries/PhysicsSurfacePoint.js +100 -0
  464. package/src/engine/physics/queries/raycast.d.ts +20 -0
  465. package/src/engine/physics/queries/raycast.d.ts.map +1 -0
  466. package/src/engine/physics/queries/raycast.js +249 -0
  467. package/src/engine/physics/solver/friction_cone.d.ts +16 -0
  468. package/src/engine/physics/solver/friction_cone.d.ts.map +1 -0
  469. package/src/engine/physics/solver/friction_cone.js +37 -0
  470. package/src/engine/physics/solver/solve_contacts.d.ts +36 -0
  471. package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -0
  472. package/src/engine/physics/solver/solve_contacts.js +598 -0
  473. package/src/core/geom/3d/topology/struct/binary/io/edge/OrderedEdge.d.ts +0 -34
  474. package/src/core/geom/3d/topology/struct/binary/io/edge/OrderedEdge.d.ts.map +0 -1
  475. package/src/core/geom/3d/topology/struct/binary/io/edge/OrderedEdge.js +0 -66
  476. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_calc_edges.d.ts +0 -2
  477. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_calc_edges.d.ts.map +0 -1
  478. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_calc_edges.js +0 -54
  479. package/src/core/geom/3d/topology/struct/binary/io/edge/get_or_create_edge_map.d.ts +0 -2
  480. package/src/core/geom/3d/topology/struct/binary/io/edge/get_or_create_edge_map.d.ts.map +0 -1
  481. package/src/core/geom/3d/topology/struct/binary/io/edge/get_or_create_edge_map.js +0 -26
  482. package/src/engine/ecs/components/Motion.d.ts +0 -21
  483. package/src/engine/ecs/components/Motion.d.ts.map +0 -1
  484. package/src/engine/ecs/components/Motion.js +0 -27
  485. package/src/engine/ecs/components/MotionSerializationAdapter.d.ts +0 -20
  486. package/src/engine/ecs/components/MotionSerializationAdapter.d.ts.map +0 -1
  487. package/src/engine/ecs/components/MotionSerializationAdapter.js +0 -26
  488. package/src/engine/ecs/systems/MotionSystem.d.ts +0 -9
  489. package/src/engine/ecs/systems/MotionSystem.d.ts.map +0 -1
  490. package/src/engine/ecs/systems/MotionSystem.js +0 -29
  491. package/src/engine/physics/fluid/Fluid.d.ts +0 -26
  492. package/src/engine/physics/fluid/Fluid.d.ts.map +0 -1
  493. package/src/engine/physics/fluid/Fluid.js +0 -221
  494. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_reverse.d.ts +0 -7
  495. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_reverse.d.ts.map +0 -1
  496. package/src/engine/physics/fluid/solver/v3_grid_apply_advection_reverse.js +0 -8
@@ -0,0 +1,127 @@
1
+ # First-person controller — TODO
2
+
3
+ Working notes. Things we've identified as worth doing but haven't pulled
4
+ the trigger on yet. Companion to DESIGN.md (base) and DESIGN_EXTENSIONS.md
5
+ (abilities + mastery roadmap).
6
+
7
+ ## Mastery evaluators — additional
8
+
9
+ We ship StrideTimingJump, FootAsymmetryTurn, BreathRhythm, and
10
+ SlideInitiationTiming today. The remaining ones from the
11
+ DESIGN_EXTENSIONS Phase 10 list, ordered by what would give the most
12
+ texture per unit of work:
13
+
14
+ ### WallRunEntryTimingEvaluator
15
+ Decision point: `WallRunGravity` (currently un-wired — Wall-run reads
16
+ `cfg.wallRun.gravityFactor` straight, no mastery hook). Wire it.
17
+
18
+ Input: angle-of-attack against the wall at activation. Lower angle of
19
+ attack (entering near-parallel) is the canonical "good" entry — converts
20
+ forward momentum into the run smoothly. High angle of attack (entering
21
+ near-perpendicular) is "bad" — you're crashing into the wall.
22
+
23
+ Curve shape: peak at small angle (1.0 → 0.8, less effective gravity =
24
+ more hang time); penalty at high angle (1.0 → 1.15, gravity ramped =
25
+ shorter run). Symmetric in behaviour, asymmetric in magnitude.
26
+
27
+ Estimated effort: 0.5 day. Capture entry angle in WallRun.onActivate,
28
+ stash it on the evaluator's per-instance state OR on a new
29
+ `runtime.wallRunEntryAngle` field. Curve + spec.
30
+
31
+ ### WallRunTakeoffTimingEvaluator
32
+ Decision point: `WallJumpImpulse` (already wired — base WallJump runs
33
+ mastery on it).
34
+
35
+ Input: how late in the wall-run the wall-jump is fired. Late in the
36
+ run (near the timer expiry) is the "explosive last-second push-off"
37
+ — bonus. Right at activation is "panicked early jump" — penalty.
38
+
39
+ Curve shape: time-based, normalized to [0, 1] over wall-run duration.
40
+ Peak at 0.6–0.9 (committed but not desperate). Trough near 0.0
41
+ (panicked).
42
+
43
+ Estimated effort: 0.5 day. WallJump needs to read how long WallRun was
44
+ active when it preempted. Simplest: track `runtime.wallRunElapsedAt
45
+ Takeoff` in WallRun.onDeactivate (or via a signal).
46
+
47
+ ### WallJumpEntryAngleEvaluator
48
+ Decision point: `WallJumpImpulse`.
49
+
50
+ Input: angle between the player's velocity vector and the wall normal
51
+ at the moment of jump press. A near-perpendicular push-off (velocity
52
+ along normal at impact) converts the most into the impulse — bonus.
53
+ A near-tangent push (sliding along) is "weak push-off" — penalty.
54
+
55
+ Curve shape: peak at dot(velocity, normal) approaching 1.0 (head-on);
56
+ penalty near 0 (parallel skim).
57
+
58
+ Composes multiplicatively with the takeoff-timing evaluator above —
59
+ both fire on `WallJumpImpulse`. That's the point of the multiplicative
60
+ composition rule.
61
+
62
+ Estimated effort: 0.5 day.
63
+
64
+ ### LedgeCatchTimingEvaluator
65
+ Decision point: NEW — would need `LedgeCatchExertionScale` or similar.
66
+ Currently LedgeGrab uses a flat `cfg.ledgeGrab.exertionRiseRate`.
67
+
68
+ Input: |velocityY| at the moment of catch. A gentle catch (low vy) is
69
+ forgiving — low exertion rise (longer hang). A desperate save (high
70
+ |vy|) is harder — higher exertion rise (shorter hang).
71
+
72
+ Curve shape: identity 1.0 at low |vy| (≤ 2 m/s), ramping up to ~1.5×
73
+ at high |vy| (≥ 8 m/s).
74
+
75
+ Estimated effort: 0.5 day, plus adding the new decision point.
76
+
77
+ ### MantleExitSpeedEvaluator
78
+ Decision point: `MantleExitSpeed` (currently un-wired).
79
+
80
+ Input: stride-phase at the moment of mantle completion. Landing on a
81
+ midstance push-off bonus the exit velocity (player runs off the mantle
82
+ into the next surface); landing on footfall takes a small penalty.
83
+
84
+ Currently Mantle's exit doesn't set any forward velocity — the player
85
+ lands at rest. To make this evaluator meaningful, we'd also need
86
+ Mantle to apply a small forward push on completion, which the
87
+ evaluator then scales. Two-step change.
88
+
89
+ Estimated effort: 1 day (more wiring than the others).
90
+
91
+ ## Other open notes
92
+
93
+ ### Refactor `pose.crouchAmount` away
94
+ Now redundant with `pose.postureAmount`. Leave for one or two builds so
95
+ any external consumers can migrate, then delete.
96
+
97
+ ### Stride-mastery score telemetry
98
+ `MasterySet` records EMA scores per decision point. We never surface
99
+ these to the HUD or any feedback system. A simple debug overlay
100
+ showing the running scores (a sparkline per decision point?) would be
101
+ helpful when tuning curves.
102
+
103
+ ### Tune the slide bob fade-out
104
+ `bobIntensityHalfLife` controls how fast the lateral bob fades when
105
+ posture changes to Prone. May be too slow — feels like a brief wobble
106
+ before the slide settles into "pure motion". Worth play-test tuning.
107
+
108
+ ### Posture-aware footstep audio
109
+ Surface tag is on `state.surfaceTag`. The footstep signal carries
110
+ side + speed + surfaceTag, but emission is gated on
111
+ `feetStriking` (Stand or Crouch posture). When other postures want
112
+ audio cues (a slide-along-pavement sound, a hang-grip creak), they
113
+ need their own signal channels — not piggyback on `onFootStep`.
114
+
115
+ ### WallRun direction sense (push-back behaviour)
116
+ Currently WallRun projects velocity onto the wall tangent each tick.
117
+ If the player turns AWAY from the wall mid-run, the wall-tangent
118
+ projection still keeps them pinned. Might want a "lean-away exits the
119
+ run" condition: if `intent.move` rotates more than X degrees from the
120
+ wall tangent, exit the wall-run.
121
+
122
+ ### Animation track for Hang posture
123
+ The eye stays at body height while hanging (we don't drop the eye
124
+ height in Hang because the body root is already below the ledge). But
125
+ the rig should probably show arms reaching up. That's a skeleton
126
+ concern, not a controller one — just flagging that `pose.posture =
127
+ Hang` is the signal the rig should branch on.
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Base class for movement abilities (wall-run, mantle, slide, ledge-grab,
3
+ * wall-jump, etc.). Each ability is a small state machine that:
4
+ *
5
+ * 1. Reports whether it wants to activate ({@link canActivate})
6
+ * 2. Owns the player's motion while active ({@link tick})
7
+ * 3. Reports whether it can be preempted right now ({@link canInterrupt})
8
+ * 4. Cleans up when control is released ({@link onDeactivate})
9
+ *
10
+ * Abilities are owned by an {@link AbilitySet}. At most one ability is
11
+ * active at a time. Preemption and queueing are handled by the set — see
12
+ * its docs for the hybrid policy.
13
+ *
14
+ * Subclasses should set:
15
+ * - `priority` — used to order preemption attempts
16
+ * - `name` — for telemetry / debugging
17
+ *
18
+ * @author Alex Goldring
19
+ * @copyright Company Named Limited (c) 2026
20
+ */
21
+ export class Ability {
22
+ /**
23
+ * Higher priority preempts lower. Defaults:
24
+ * slide=10, mantle=30, ledgeGrab=40, wallRun=50, wallJump=60.
25
+ * Wall-jump is highest because it's the most input-direct response
26
+ * (button press) and should fire reliably regardless of what else
27
+ * is going on.
28
+ * @type {number}
29
+ */
30
+ priority: number;
31
+ /**
32
+ * Stable string identifier for telemetry / debugging overlays.
33
+ * @type {string}
34
+ */
35
+ name: string;
36
+ /**
37
+ * Ask: do you want to take control RIGHT NOW?
38
+ *
39
+ * Read controller state and sensor data; return true iff conditions
40
+ * are met. Side-effect-free; called every tick when no ability is
41
+ * active, and once on each tick when this ability is queued behind
42
+ * another.
43
+ *
44
+ * @param {*} controller FirstPersonPlayerController
45
+ * @param {*} runtime per-entity runtime
46
+ * @param {*} sensors FirstPersonSensors (may be null in stub mode)
47
+ * @returns {boolean}
48
+ */
49
+ canActivate(controller: any, runtime: any, sensors: any): boolean;
50
+ /**
51
+ * Called once when this ability acquires control. Use for one-shot
52
+ * setup (kicking impulses, capturing entry velocity, etc.).
53
+ *
54
+ * @param {*} controller
55
+ * @param {*} runtime
56
+ */
57
+ onActivate(controller: any, runtime: any): void;
58
+ /**
59
+ * Runs each fixed step while active. The ability OWNS body motion
60
+ * during this window — writes directly to runtime.velocity*, the body
61
+ * Transform position, springs, etc. Returning false releases control
62
+ * back to the AbilitySet (which will run base locomotion or the next
63
+ * queued ability in the same tick).
64
+ *
65
+ * The `system` parameter is the {@link FirstPersonPlayerControllerSystem}
66
+ * itself, passed through so abilities can call shared helpers like
67
+ * vertical-integration-and-ground-resolution without re-implementing
68
+ * them. Use it sparingly — the cleaner the ability's tick is, the
69
+ * easier it is to reason about ownership.
70
+ *
71
+ * @param {*} controller
72
+ * @param {*} runtime
73
+ * @param {*} bodyTransform
74
+ * @param {number} dt
75
+ * @param {*} system the FirstPersonPlayerControllerSystem instance
76
+ * @returns {boolean} true = stay active; false = release control
77
+ */
78
+ tick(controller: any, runtime: any, bodyTransform: any, dt: number, system: any): boolean;
79
+ /**
80
+ * Ask: can a higher-priority ability preempt you right now?
81
+ *
82
+ * Defaults to true (interruptible). Override to declare windows where
83
+ * this ability *must* finish what it's doing — e.g. mantle returns
84
+ * false while on its scripted path; slide returns false for the
85
+ * first ~150ms after entry.
86
+ *
87
+ * @param {*} controller
88
+ * @param {*} runtime
89
+ * @returns {boolean}
90
+ */
91
+ canInterrupt(controller: any, runtime: any): boolean;
92
+ /**
93
+ * Called once when control is released (either tick returned false,
94
+ * or a higher-priority ability preempted). Clean up internal state.
95
+ *
96
+ * @param {*} controller
97
+ * @param {*} runtime
98
+ */
99
+ onDeactivate(controller: any, runtime: any): void;
100
+ }
101
+ //# sourceMappingURL=Ability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Ability.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/control/first-person/abilities/Ability.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IAEQ;;;;;;;OAOG;IACH,UAFU,MAAM,CAEC;IAEjB;;;OAGG;IACH,MAFU,MAAM,CAEK;IAGzB;;;;;;;;;;;;OAYG;IAEH,0DAHa,OAAO,CAKnB;IAED;;;;;;OAMG;IAEH,gDAAkC;IAElC;;;;;;;;;;;;;;;;;;;OAmBG;IAEH,4DALW,MAAM,gBAEJ,OAAO,CAKnB;IAED;;;;;;;;;;;OAWG;IAEH,6CAHa,OAAO,CAKnB;IAED;;;;;;OAMG;IAEH,kDAAoC;CACvC"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Base class for movement abilities (wall-run, mantle, slide, ledge-grab,
3
+ * wall-jump, etc.). Each ability is a small state machine that:
4
+ *
5
+ * 1. Reports whether it wants to activate ({@link canActivate})
6
+ * 2. Owns the player's motion while active ({@link tick})
7
+ * 3. Reports whether it can be preempted right now ({@link canInterrupt})
8
+ * 4. Cleans up when control is released ({@link onDeactivate})
9
+ *
10
+ * Abilities are owned by an {@link AbilitySet}. At most one ability is
11
+ * active at a time. Preemption and queueing are handled by the set — see
12
+ * its docs for the hybrid policy.
13
+ *
14
+ * Subclasses should set:
15
+ * - `priority` — used to order preemption attempts
16
+ * - `name` — for telemetry / debugging
17
+ *
18
+ * @author Alex Goldring
19
+ * @copyright Company Named Limited (c) 2026
20
+ */
21
+ export class Ability {
22
+ constructor() {
23
+ /**
24
+ * Higher priority preempts lower. Defaults:
25
+ * slide=10, mantle=30, ledgeGrab=40, wallRun=50, wallJump=60.
26
+ * Wall-jump is highest because it's the most input-direct response
27
+ * (button press) and should fire reliably regardless of what else
28
+ * is going on.
29
+ * @type {number}
30
+ */
31
+ this.priority = 0;
32
+
33
+ /**
34
+ * Stable string identifier for telemetry / debugging overlays.
35
+ * @type {string}
36
+ */
37
+ this.name = "Ability";
38
+ }
39
+
40
+ /**
41
+ * Ask: do you want to take control RIGHT NOW?
42
+ *
43
+ * Read controller state and sensor data; return true iff conditions
44
+ * are met. Side-effect-free; called every tick when no ability is
45
+ * active, and once on each tick when this ability is queued behind
46
+ * another.
47
+ *
48
+ * @param {*} controller FirstPersonPlayerController
49
+ * @param {*} runtime per-entity runtime
50
+ * @param {*} sensors FirstPersonSensors (may be null in stub mode)
51
+ * @returns {boolean}
52
+ */
53
+ // eslint-disable-next-line no-unused-vars
54
+ canActivate(controller, runtime, sensors) {
55
+ return false;
56
+ }
57
+
58
+ /**
59
+ * Called once when this ability acquires control. Use for one-shot
60
+ * setup (kicking impulses, capturing entry velocity, etc.).
61
+ *
62
+ * @param {*} controller
63
+ * @param {*} runtime
64
+ */
65
+ // eslint-disable-next-line no-unused-vars
66
+ onActivate(controller, runtime) {}
67
+
68
+ /**
69
+ * Runs each fixed step while active. The ability OWNS body motion
70
+ * during this window — writes directly to runtime.velocity*, the body
71
+ * Transform position, springs, etc. Returning false releases control
72
+ * back to the AbilitySet (which will run base locomotion or the next
73
+ * queued ability in the same tick).
74
+ *
75
+ * The `system` parameter is the {@link FirstPersonPlayerControllerSystem}
76
+ * itself, passed through so abilities can call shared helpers like
77
+ * vertical-integration-and-ground-resolution without re-implementing
78
+ * them. Use it sparingly — the cleaner the ability's tick is, the
79
+ * easier it is to reason about ownership.
80
+ *
81
+ * @param {*} controller
82
+ * @param {*} runtime
83
+ * @param {*} bodyTransform
84
+ * @param {number} dt
85
+ * @param {*} system the FirstPersonPlayerControllerSystem instance
86
+ * @returns {boolean} true = stay active; false = release control
87
+ */
88
+ // eslint-disable-next-line no-unused-vars
89
+ tick(controller, runtime, bodyTransform, dt, system) {
90
+ return false;
91
+ }
92
+
93
+ /**
94
+ * Ask: can a higher-priority ability preempt you right now?
95
+ *
96
+ * Defaults to true (interruptible). Override to declare windows where
97
+ * this ability *must* finish what it's doing — e.g. mantle returns
98
+ * false while on its scripted path; slide returns false for the
99
+ * first ~150ms after entry.
100
+ *
101
+ * @param {*} controller
102
+ * @param {*} runtime
103
+ * @returns {boolean}
104
+ */
105
+ // eslint-disable-next-line no-unused-vars
106
+ canInterrupt(controller, runtime) {
107
+ return true;
108
+ }
109
+
110
+ /**
111
+ * Called once when control is released (either tick returned false,
112
+ * or a higher-priority ability preempted). Clean up internal state.
113
+ *
114
+ * @param {*} controller
115
+ * @param {*} runtime
116
+ */
117
+ // eslint-disable-next-line no-unused-vars
118
+ onDeactivate(controller, runtime) {}
119
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Holds a set of {@link Ability} instances and runs the activation +
3
+ * preemption + queueing policy:
4
+ *
5
+ * 1. If an ability is active, tick it first.
6
+ * - If its tick returns false → it's done. Falls through to step 2
7
+ * in the SAME tick (no wasted frame).
8
+ *
9
+ * 2. If a queued ability exists (from a previous tick that was blocked),
10
+ * check its canActivate() again. If still wants in → activate.
11
+ *
12
+ * 3. If no ability is active, poll all abilities in DESCENDING priority.
13
+ * First that canActivate() becomes active.
14
+ *
15
+ * 4. If an active ability is still running but a higher-priority one
16
+ * wants in: check the active one's canInterrupt(). If yes → preempt
17
+ * now. If no → queue the higher-priority candidate; it will re-check
18
+ * every tick until the current ability releases (or canInterrupt
19
+ * flips to true).
20
+ *
21
+ * Returns whether base-locomotion should run this tick (true iff no
22
+ * ability owns motion).
23
+ *
24
+ * @author Alex Goldring
25
+ * @copyright Company Named Limited (c) 2026
26
+ */
27
+ export class AbilitySet {
28
+ /**
29
+ * Registered abilities. Order does not matter — sorted by priority
30
+ * on demand when polling. Set is small (typically <10) so we don't
31
+ * pre-sort.
32
+ * @type {Ability[]}
33
+ */
34
+ abilities: Ability[];
35
+ /**
36
+ * Currently-active ability, or null if base locomotion is running.
37
+ * @type {Ability|null}
38
+ */
39
+ active: Ability | null;
40
+ /**
41
+ * Ability waiting for the current one to release. Cleared when it
42
+ * activates OR when its canActivate() returns false on re-check
43
+ * (the conditions that wanted it might have passed).
44
+ * @type {Ability|null}
45
+ */
46
+ queued: Ability | null;
47
+ /**
48
+ * Add an ability.
49
+ * @param {Ability} ability
50
+ */
51
+ add(ability: Ability): void;
52
+ /**
53
+ * Remove an ability if present. If it's currently active or queued,
54
+ * deactivates / clears it first.
55
+ * @param {Ability} ability
56
+ */
57
+ remove(ability: Ability): void;
58
+ /**
59
+ * Execute one tick. Returns true if base locomotion should run this
60
+ * fixed step (no ability owns motion).
61
+ *
62
+ * @param {*} controller
63
+ * @param {*} runtime
64
+ * @param {*} bodyTransform
65
+ * @param {*} sensors
66
+ * @param {number} dt
67
+ * @param {*} [system] FirstPersonPlayerControllerSystem instance,
68
+ * passed through to ability.tick() so abilities
69
+ * can delegate to shared helpers.
70
+ * @returns {boolean} true = run base locomotion; false = ability owned
71
+ */
72
+ tick(controller: any, runtime: any, bodyTransform: any, sensors: any, dt: number, system?: any): boolean;
73
+ /**
74
+ * @private
75
+ */
76
+ private _findHighestPriorityActivatable;
77
+ /**
78
+ * @private
79
+ */
80
+ private _activate;
81
+ /**
82
+ * @private
83
+ */
84
+ private _deactivate;
85
+ }
86
+ //# sourceMappingURL=AbilitySet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbilitySet.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/control/first-person/abilities/AbilitySet.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH;IAEQ;;;;;OAKG;IACH,WAFU,SAAS,CAEA;IAEnB;;;OAGG;IACH,QAFU,UAAQ,IAAI,CAEJ;IAElB;;;;;OAKG;IACH,QAFU,UAAQ,IAAI,CAEJ;IAGtB;;;OAGG;IACH,4BAEC;IAED;;;;OAIG;IACH,+BAQC;IAED;;;;;;;;;;;;;OAaG;IACH,0EANW,MAAM,iBAIJ,OAAO,CA4DnB;IAED;;OAEG;IACH,wCAcC;IAED;;OAEG;IACH,kBAGC;IAED;;OAEG;IACH,oBAKC;CACJ"}
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Holds a set of {@link Ability} instances and runs the activation +
3
+ * preemption + queueing policy:
4
+ *
5
+ * 1. If an ability is active, tick it first.
6
+ * - If its tick returns false → it's done. Falls through to step 2
7
+ * in the SAME tick (no wasted frame).
8
+ *
9
+ * 2. If a queued ability exists (from a previous tick that was blocked),
10
+ * check its canActivate() again. If still wants in → activate.
11
+ *
12
+ * 3. If no ability is active, poll all abilities in DESCENDING priority.
13
+ * First that canActivate() becomes active.
14
+ *
15
+ * 4. If an active ability is still running but a higher-priority one
16
+ * wants in: check the active one's canInterrupt(). If yes → preempt
17
+ * now. If no → queue the higher-priority candidate; it will re-check
18
+ * every tick until the current ability releases (or canInterrupt
19
+ * flips to true).
20
+ *
21
+ * Returns whether base-locomotion should run this tick (true iff no
22
+ * ability owns motion).
23
+ *
24
+ * @author Alex Goldring
25
+ * @copyright Company Named Limited (c) 2026
26
+ */
27
+ export class AbilitySet {
28
+ constructor() {
29
+ /**
30
+ * Registered abilities. Order does not matter — sorted by priority
31
+ * on demand when polling. Set is small (typically <10) so we don't
32
+ * pre-sort.
33
+ * @type {Ability[]}
34
+ */
35
+ this.abilities = [];
36
+
37
+ /**
38
+ * Currently-active ability, or null if base locomotion is running.
39
+ * @type {Ability|null}
40
+ */
41
+ this.active = null;
42
+
43
+ /**
44
+ * Ability waiting for the current one to release. Cleared when it
45
+ * activates OR when its canActivate() returns false on re-check
46
+ * (the conditions that wanted it might have passed).
47
+ * @type {Ability|null}
48
+ */
49
+ this.queued = null;
50
+ }
51
+
52
+ /**
53
+ * Add an ability.
54
+ * @param {Ability} ability
55
+ */
56
+ add(ability) {
57
+ this.abilities.push(ability);
58
+ }
59
+
60
+ /**
61
+ * Remove an ability if present. If it's currently active or queued,
62
+ * deactivates / clears it first.
63
+ * @param {Ability} ability
64
+ */
65
+ remove(ability) {
66
+ if (this.active === ability) {
67
+ // Best-effort: caller-side cleanup is their responsibility.
68
+ this.active = null;
69
+ }
70
+ if (this.queued === ability) this.queued = null;
71
+ const i = this.abilities.indexOf(ability);
72
+ if (i !== -1) this.abilities.splice(i, 1);
73
+ }
74
+
75
+ /**
76
+ * Execute one tick. Returns true if base locomotion should run this
77
+ * fixed step (no ability owns motion).
78
+ *
79
+ * @param {*} controller
80
+ * @param {*} runtime
81
+ * @param {*} bodyTransform
82
+ * @param {*} sensors
83
+ * @param {number} dt
84
+ * @param {*} [system] FirstPersonPlayerControllerSystem instance,
85
+ * passed through to ability.tick() so abilities
86
+ * can delegate to shared helpers.
87
+ * @returns {boolean} true = run base locomotion; false = ability owned
88
+ */
89
+ tick(controller, runtime, bodyTransform, sensors, dt, system) {
90
+ // Step 1: tick the active ability if any. May release control.
91
+ if (this.active !== null) {
92
+ const stillActive = this.active.tick(controller, runtime, bodyTransform, dt, system);
93
+ if (!stillActive) {
94
+ this._deactivate(controller, runtime);
95
+ }
96
+ }
97
+
98
+ // Step 2: if something is queued, see if it can activate now (the
99
+ // current ability may have released in step 1, OR may be
100
+ // interruptible now even though it wasn't before).
101
+ if (this.queued !== null) {
102
+ if (this.active === null) {
103
+ if (this.queued.canActivate(controller, runtime, sensors)) {
104
+ this._activate(this.queued, controller, runtime);
105
+ }
106
+ this.queued = null; // cleared whether or not it activated
107
+ } else if (this.queued.priority > this.active.priority
108
+ && this.active.canInterrupt(controller, runtime)) {
109
+ if (this.queued.canActivate(controller, runtime, sensors)) {
110
+ const next = this.queued;
111
+ this.queued = null;
112
+ this._deactivate(controller, runtime);
113
+ this._activate(next, controller, runtime);
114
+ } else {
115
+ // Queued candidate no longer wants in — drop it.
116
+ this.queued = null;
117
+ }
118
+ }
119
+ // else: still waiting on a non-interruptible current ability
120
+ }
121
+
122
+ // Step 3: if nothing active, poll candidates (highest priority first).
123
+ if (this.active === null) {
124
+ const best = this._findHighestPriorityActivatable(controller, runtime, sensors, -Infinity);
125
+ if (best !== null) {
126
+ this._activate(best, controller, runtime);
127
+ }
128
+ } else {
129
+ // Step 4: existing ability active — check if a higher-priority
130
+ // candidate wants in.
131
+ const challenger = this._findHighestPriorityActivatable(
132
+ controller, runtime, sensors, this.active.priority,
133
+ );
134
+ if (challenger !== null) {
135
+ if (this.active.canInterrupt(controller, runtime)) {
136
+ this._deactivate(controller, runtime);
137
+ this._activate(challenger, controller, runtime);
138
+ } else {
139
+ // Queue it — will re-poll each tick until current releases
140
+ // or becomes interruptible.
141
+ this.queued = challenger;
142
+ }
143
+ }
144
+ }
145
+
146
+ return this.active === null;
147
+ }
148
+
149
+ /**
150
+ * @private
151
+ */
152
+ _findHighestPriorityActivatable(controller, runtime, sensors, minPriorityExclusive) {
153
+ let best = null;
154
+ let bestPriority = minPriorityExclusive;
155
+ const list = this.abilities;
156
+ for (let i = 0; i < list.length; i++) {
157
+ const a = list[i];
158
+ if (a === this.active) continue;
159
+ if (a.priority <= bestPriority) continue;
160
+ if (a.canActivate(controller, runtime, sensors)) {
161
+ best = a;
162
+ bestPriority = a.priority;
163
+ }
164
+ }
165
+ return best;
166
+ }
167
+
168
+ /**
169
+ * @private
170
+ */
171
+ _activate(ability, controller, runtime) {
172
+ this.active = ability;
173
+ ability.onActivate(controller, runtime);
174
+ }
175
+
176
+ /**
177
+ * @private
178
+ */
179
+ _deactivate(controller, runtime) {
180
+ if (this.active === null) return;
181
+ const prev = this.active;
182
+ this.active = null;
183
+ prev.onDeactivate(controller, runtime);
184
+ }
185
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Ledge-grab ability — snap to a forward ledge while descending and hang
3
+ * from it until the player chooses (or is forced) to release.
4
+ *
5
+ * Activation:
6
+ * - `sensors.ledgeAhead.hit` (a forward+up obstacle probe found a grab-
7
+ * able edge — typically the same probe mantle uses).
8
+ * - `runtime.velocityY <= 0` — the player is descending or static. We
9
+ * don't auto-catch ledges on the way UP — that would feel like the
10
+ * world is grabbing the player mid-jump.
11
+ * - `state.airborneTime >= minAirborneTime` — leaves a small window
12
+ * after takeoff where ledge-grab can't fire, even if the player is
13
+ * instantly at apex (which would otherwise satisfy `velocityY <= 0`).
14
+ * - Forward intent (`intent.move.y > 0.1`) — the player must be
15
+ * committing into the ledge. Walking backwards off an edge shouldn't
16
+ * auto-catch the lip.
17
+ *
18
+ * Behaviour:
19
+ * - Body position snaps to a "hang from edge" pose: at the ledge edge
20
+ * X/Z (with a small back-offset so the body is pulled against the
21
+ * wall below), and Y offset down by ~bodyHeight so the hands grip
22
+ * the edge with the body suspended below.
23
+ * - Velocity is zeroed each tick — the body is parked.
24
+ * - Exertion rises at `cfg.exertionRiseRate` per second, scaled by
25
+ * mass. Climbing fatigue: hang too long and the next exit is
26
+ * forced (a slip).
27
+ * - Grounded stays false (the player is hanging in air).
28
+ *
29
+ * Exit:
30
+ * - Jump pressed (rising edge) → mantle-up. Release with a small
31
+ * upward velocity so mantle's ledgeAhead probe still hits next
32
+ * tick; mantle (priority 30) then takes over and animates the
33
+ * climb-onto-surface path.
34
+ * - Back-intent (`intent.move.y < -0.1`) → drop. Release with zero
35
+ * velocity; the player falls under base gravity.
36
+ * - Crouch pressed → drop. Same as back-intent.
37
+ * - Exertion saturates (`>= 1`) → slip. Release with zero velocity.
38
+ * - `sensors.ledgeAhead.hit` becomes false → shuffled off the edge.
39
+ * Release with zero velocity.
40
+ *
41
+ * Priority 40 — above mantle (30), below wall-run (50). Mantle CAN'T
42
+ * preempt an active ledge-grab — that's the point of placing ledge
43
+ * higher. Otherwise mantle would fire mid-hang and snap the body away.
44
+ * Wall-run and wall-jump can preempt — but in practice they need lateral
45
+ * walls + speed (wall-run) or a jump press near a side wall (wall-jump),
46
+ * conditions which rarely hold while hanging.
47
+ *
48
+ * @author Alex Goldring
49
+ * @copyright Company Named Limited (c) 2026
50
+ */
51
+ export class LedgeGrab extends Ability {
52
+ /** @private World-space ledge edge position captured at onActivate. */
53
+ private _edgeX;
54
+ _edgeY: number;
55
+ _edgeZ: number;
56
+ canActivate(controller: any, runtime: any, sensors: any): boolean;
57
+ onActivate(controller: any, runtime: any): void;
58
+ canInterrupt(): boolean;
59
+ tick(controller: any, runtime: any, bodyTransform: any, dt: any, _system: any): boolean;
60
+ }
61
+ import { Ability } from "./Ability.js";
62
+ //# sourceMappingURL=LedgeGrab.d.ts.map