@jgengine/core 0.10.0 → 0.12.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 (727) hide show
  1. package/CHANGELOG.md +39 -2
  2. package/LICENSE +203 -661
  3. package/README.md +1 -1
  4. package/dist/ai/crowd.d.ts +55 -0
  5. package/dist/ai/crowd.js +114 -0
  6. package/dist/ai/flock.d.ts +5 -2
  7. package/dist/ai/flock.js +5 -2
  8. package/dist/ai/groupAssist.d.ts +1 -0
  9. package/dist/ai/groupAssist.js +1 -0
  10. package/dist/ai/heatSystem.d.ts +76 -0
  11. package/dist/ai/heatSystem.js +97 -0
  12. package/dist/ai/interestScheduler.d.ts +107 -0
  13. package/dist/ai/interestScheduler.js +118 -0
  14. package/dist/ai/jobBoard.d.ts +1 -0
  15. package/dist/ai/jobBoard.js +1 -0
  16. package/dist/ai/laneSelect.d.ts +5 -2
  17. package/dist/ai/laneSelect.js +5 -2
  18. package/dist/ai/mobBrain.d.ts +1 -0
  19. package/dist/ai/mobBrain.js +1 -0
  20. package/dist/ai/populationDirector.d.ts +103 -0
  21. package/dist/ai/populationDirector.js +190 -0
  22. package/dist/ai/pursuit.d.ts +56 -0
  23. package/dist/ai/pursuit.js +53 -0
  24. package/dist/ai/spawnDirector.d.ts +7 -2
  25. package/dist/ai/spawnDirector.js +18 -15
  26. package/dist/ai/spawnPoint.d.ts +3 -1
  27. package/dist/ai/spawnPoint.js +3 -1
  28. package/dist/ai/targetAcquisition.d.ts +84 -0
  29. package/dist/ai/targetAcquisition.js +92 -0
  30. package/dist/anim/easing.d.ts +19 -0
  31. package/dist/anim/easing.js +19 -0
  32. package/dist/anim/oscillator.d.ts +12 -0
  33. package/dist/anim/oscillator.js +25 -0
  34. package/dist/area/areaEffectField.d.ts +127 -0
  35. package/dist/area/areaEffectField.js +175 -0
  36. package/dist/area/stackPolicy.d.ts +47 -0
  37. package/dist/area/stackPolicy.js +99 -0
  38. package/dist/authoring.d.ts +2 -1
  39. package/dist/authoring.js +2 -1
  40. package/dist/board/laneBoard.d.ts +13 -0
  41. package/dist/board/laneBoard.js +13 -0
  42. package/dist/board/timelineBoard.d.ts +10 -0
  43. package/dist/board/timelineBoard.js +10 -0
  44. package/dist/combat/abilityKit.d.ts +18 -0
  45. package/dist/combat/abilityKit.js +24 -9
  46. package/dist/combat/animationState.d.ts +5 -0
  47. package/dist/combat/animationState.js +5 -0
  48. package/dist/combat/breakMeters.d.ts +10 -0
  49. package/dist/combat/breakMeters.js +10 -0
  50. package/dist/combat/castRunner.d.ts +5 -0
  51. package/dist/combat/castRunner.js +5 -0
  52. package/dist/combat/comboPoints.d.ts +5 -0
  53. package/dist/combat/comboPoints.js +5 -0
  54. package/dist/combat/comboString.d.ts +5 -0
  55. package/dist/combat/comboString.js +5 -0
  56. package/dist/combat/damageInterceptors.d.ts +192 -0
  57. package/dist/combat/damageInterceptors.js +251 -0
  58. package/dist/combat/damageMatchup.d.ts +68 -0
  59. package/dist/combat/damageMatchup.js +42 -0
  60. package/dist/combat/damageResolution.d.ts +63 -0
  61. package/dist/combat/damageResolution.js +50 -0
  62. package/dist/combat/death.d.ts +7 -1
  63. package/dist/combat/death.js +5 -0
  64. package/dist/combat/deathReason.d.ts +14 -0
  65. package/dist/combat/deathReason.js +1 -0
  66. package/dist/combat/defensiveWindow.d.ts +5 -0
  67. package/dist/combat/defensiveWindow.js +5 -0
  68. package/dist/combat/dotField.d.ts +5 -1
  69. package/dist/combat/dotField.js +5 -1
  70. package/dist/combat/downed.d.ts +5 -0
  71. package/dist/combat/downed.js +5 -0
  72. package/dist/combat/effects.d.ts +5 -0
  73. package/dist/combat/effects.js +5 -0
  74. package/dist/combat/encounterSequence.d.ts +258 -0
  75. package/dist/combat/encounterSequence.js +426 -0
  76. package/dist/combat/hitReaction.d.ts +57 -1
  77. package/dist/combat/hitReaction.js +45 -5
  78. package/dist/combat/magazine.d.ts +54 -0
  79. package/dist/combat/magazine.js +96 -0
  80. package/dist/combat/projectiles.d.ts +5 -0
  81. package/dist/combat/projectiles.js +32 -14
  82. package/dist/combat/receivedDamage.d.ts +117 -0
  83. package/dist/combat/receivedDamage.js +92 -0
  84. package/dist/combat/regenShield.d.ts +5 -1
  85. package/dist/combat/regenShield.js +5 -1
  86. package/dist/combat/renderCues.d.ts +51 -0
  87. package/dist/combat/renderCues.js +44 -0
  88. package/dist/combat/resourcePool.d.ts +5 -0
  89. package/dist/combat/resourcePool.js +5 -0
  90. package/dist/combat/rewardAllocation.d.ts +121 -0
  91. package/dist/combat/rewardAllocation.js +251 -0
  92. package/dist/combat/shotOrigin.d.ts +18 -1
  93. package/dist/combat/shotOrigin.js +39 -0
  94. package/dist/combat/statusApplication.d.ts +96 -0
  95. package/dist/combat/statusApplication.js +81 -0
  96. package/dist/combat/telegraph.d.ts +11 -2
  97. package/dist/combat/telegraph.js +11 -2
  98. package/dist/combat/thresholdCrossings.d.ts +85 -0
  99. package/dist/combat/thresholdCrossings.js +116 -0
  100. package/dist/combat.d.ts +35 -0
  101. package/dist/combat.js +35 -0
  102. package/dist/commands/commandRegistry.d.ts +11 -0
  103. package/dist/commands/commandRegistry.js +9 -2
  104. package/dist/crafting/crop.d.ts +18 -0
  105. package/dist/crafting/crop.js +18 -0
  106. package/dist/crafting/production.d.ts +5 -0
  107. package/dist/crafting/production.js +5 -0
  108. package/dist/devtools/controls.d.ts +38 -0
  109. package/dist/devtools/controls.js +181 -0
  110. package/dist/devtools/devtools.d.ts +5 -197
  111. package/dist/devtools/devtools.js +38 -774
  112. package/dist/devtools/discover.d.ts +32 -0
  113. package/dist/devtools/discover.js +240 -0
  114. package/dist/devtools/fallbackSeams.d.ts +50 -0
  115. package/dist/devtools/fallbackSeams.js +111 -0
  116. package/dist/devtools/frame.d.ts +15 -0
  117. package/dist/devtools/frame.js +247 -0
  118. package/dist/devtools/logs.d.ts +15 -0
  119. package/dist/devtools/logs.js +86 -0
  120. package/dist/devtools/overrides.d.ts +16 -0
  121. package/dist/devtools/overrides.js +66 -0
  122. package/dist/devtools/rewriteTunables.d.ts +17 -0
  123. package/dist/devtools/rewriteTunables.js +276 -0
  124. package/dist/devtools/saveEndpoint.d.ts +46 -0
  125. package/dist/devtools/saveEndpoint.js +48 -0
  126. package/dist/devtools/transformTunables.d.ts +3 -0
  127. package/dist/devtools/transformTunables.js +3 -0
  128. package/dist/devtools/tunableSchema.d.ts +31 -0
  129. package/dist/devtools/tunableSchema.js +31 -0
  130. package/dist/devtools/types.d.ts +212 -0
  131. package/dist/devtools/types.js +1 -0
  132. package/dist/economy/auctionBook.d.ts +122 -0
  133. package/dist/economy/auctionBook.js +213 -0
  134. package/dist/economy/currency.d.ts +12 -1
  135. package/dist/economy/currency.js +12 -1
  136. package/dist/economy/listingBook.d.ts +91 -0
  137. package/dist/economy/listingBook.js +144 -0
  138. package/dist/economy/priceHistory.d.ts +44 -0
  139. package/dist/economy/priceHistory.js +89 -0
  140. package/dist/economy/resourceLedger.d.ts +222 -0
  141. package/dist/economy/resourceLedger.js +353 -0
  142. package/dist/economy/sharedWallet.d.ts +14 -0
  143. package/dist/economy/sharedWallet.js +14 -0
  144. package/dist/economy/techTree.d.ts +12 -0
  145. package/dist/economy/techTree.js +12 -0
  146. package/dist/economy/unlockPoints.d.ts +92 -0
  147. package/dist/economy/unlockPoints.js +103 -0
  148. package/dist/economy/wallet.d.ts +26 -2
  149. package/dist/economy/wallet.js +35 -6
  150. package/dist/editor/commandApply.d.ts +5 -0
  151. package/dist/editor/commandApply.js +755 -0
  152. package/dist/editor/commands.d.ts +235 -7
  153. package/dist/editor/commands.js +82 -124
  154. package/dist/editor/directives.d.ts +94 -0
  155. package/dist/editor/directives.js +206 -0
  156. package/dist/editor/document.d.ts +194 -13
  157. package/dist/editor/document.js +1166 -19
  158. package/dist/editor/entityCatalog.d.ts +42 -0
  159. package/dist/editor/entityCatalog.js +101 -0
  160. package/dist/editor/environment.d.ts +74 -0
  161. package/dist/editor/environment.js +169 -0
  162. package/dist/editor/grid.d.ts +229 -0
  163. package/dist/editor/grid.js +366 -0
  164. package/dist/editor/gridAdapters.d.ts +80 -0
  165. package/dist/editor/gridAdapters.js +134 -0
  166. package/dist/editor/index.d.ts +98 -6
  167. package/dist/editor/index.js +13 -2
  168. package/dist/editor/liveSync.d.ts +127 -0
  169. package/dist/editor/liveSync.js +249 -0
  170. package/dist/editor/minimap.d.ts +31 -0
  171. package/dist/editor/minimap.js +73 -0
  172. package/dist/editor/runtimeInspector.d.ts +88 -0
  173. package/dist/editor/runtimeInspector.js +239 -0
  174. package/dist/editor/streamer.d.ts +66 -0
  175. package/dist/editor/streamer.js +68 -0
  176. package/dist/editor/types.d.ts +250 -1
  177. package/dist/editor/world.d.ts +136 -0
  178. package/dist/editor/world.js +303 -0
  179. package/dist/faction/reputation.d.ts +5 -0
  180. package/dist/faction/reputation.js +5 -0
  181. package/dist/format/distance.d.ts +17 -0
  182. package/dist/format/distance.js +18 -0
  183. package/dist/format/duration.d.ts +27 -0
  184. package/dist/format/duration.js +45 -0
  185. package/dist/format/speed.d.ts +17 -0
  186. package/dist/format/speed.js +25 -0
  187. package/dist/game/breeding.d.ts +161 -0
  188. package/dist/game/breeding.js +181 -0
  189. package/dist/game/cameraConfig.d.ts +451 -0
  190. package/dist/game/cameraConfig.js +1 -0
  191. package/dist/game/connectedPlayers.d.ts +6 -4
  192. package/dist/game/connectedPlayers.js +2 -2
  193. package/dist/game/cosmetics.d.ts +9 -0
  194. package/dist/game/cosmetics.js +16 -0
  195. package/dist/game/defineGame.d.ts +110 -5
  196. package/dist/game/defineGame.js +49 -4
  197. package/dist/game/defineSystem.d.ts +90 -0
  198. package/dist/game/defineSystem.js +47 -0
  199. package/dist/game/dialogue.d.ts +33 -0
  200. package/dist/game/dialogue.js +21 -0
  201. package/dist/game/events.d.ts +63 -13
  202. package/dist/game/events.js +5 -0
  203. package/dist/game/feed.d.ts +33 -0
  204. package/dist/game/feed.js +35 -2
  205. package/dist/game/gamePhase.d.ts +11 -0
  206. package/dist/game/gamePhase.js +16 -0
  207. package/dist/game/leaderboard.d.ts +5 -0
  208. package/dist/game/leaderboard.js +5 -0
  209. package/dist/game/loadout.d.ts +5 -0
  210. package/dist/game/loadout.js +5 -0
  211. package/dist/game/lootFilter.d.ts +2 -0
  212. package/dist/game/lootFilter.js +2 -0
  213. package/dist/game/lootPipeline.d.ts +164 -0
  214. package/dist/game/lootPipeline.js +216 -0
  215. package/dist/game/lootTable.d.ts +19 -2
  216. package/dist/game/lootTable.js +15 -5
  217. package/dist/game/objectives.d.ts +43 -0
  218. package/dist/game/objectives.js +36 -0
  219. package/dist/game/paramLayers.d.ts +148 -0
  220. package/dist/game/paramLayers.js +185 -0
  221. package/dist/game/ping.d.ts +5 -0
  222. package/dist/game/ping.js +5 -0
  223. package/dist/game/playableGame.d.ts +116 -432
  224. package/dist/game/playableGame.js +1 -1
  225. package/dist/game/progression.d.ts +35 -0
  226. package/dist/game/progression.js +19 -0
  227. package/dist/game/quest.d.ts +8 -0
  228. package/dist/game/quest.js +30 -3
  229. package/dist/game/race.d.ts +141 -0
  230. package/dist/game/race.js +169 -0
  231. package/dist/game/recordBook.d.ts +3 -1
  232. package/dist/game/recordBook.js +4 -1
  233. package/dist/game/ruleSelection.d.ts +75 -0
  234. package/dist/game/ruleSelection.js +127 -0
  235. package/dist/game/runDraft.d.ts +5 -0
  236. package/dist/game/runDraft.js +5 -0
  237. package/dist/game/saveStore.d.ts +111 -0
  238. package/dist/game/saveStore.js +312 -0
  239. package/dist/game/snapshotHistory.d.ts +67 -0
  240. package/dist/game/snapshotHistory.js +95 -0
  241. package/dist/game/social.d.ts +38 -1
  242. package/dist/game/social.js +71 -0
  243. package/dist/game/spawnPoints.d.ts +5 -0
  244. package/dist/game/spawnPoints.js +5 -0
  245. package/dist/game/systemRuntime.d.ts +50 -0
  246. package/dist/game/systemRuntime.js +157 -0
  247. package/dist/game/systemSchedule.d.ts +72 -0
  248. package/dist/game/systemSchedule.js +242 -0
  249. package/dist/game/toasts.d.ts +43 -0
  250. package/dist/game/toasts.js +44 -0
  251. package/dist/game/trade.d.ts +10 -0
  252. package/dist/game/trade.js +10 -0
  253. package/dist/game/tribe.d.ts +184 -0
  254. package/dist/game/tribe.js +432 -0
  255. package/dist/game/unlocks.d.ts +8 -0
  256. package/dist/game/unlocks.js +16 -0
  257. package/dist/game/vfxInstance.d.ts +138 -0
  258. package/dist/game/vfxInstance.js +96 -0
  259. package/dist/game/worldItem.d.ts +17 -4
  260. package/dist/game/worldItem.js +17 -4
  261. package/dist/gameplay.d.ts +93 -0
  262. package/dist/gameplay.js +93 -0
  263. package/dist/index.d.ts +5 -14
  264. package/dist/index.js +5 -14
  265. package/dist/input/actionBindings.d.ts +23 -6
  266. package/dist/input/actionBindings.js +23 -6
  267. package/dist/input/axisInput.d.ts +7 -2
  268. package/dist/input/axisInput.js +7 -2
  269. package/dist/input/controlGroups.d.ts +67 -0
  270. package/dist/input/controlGroups.js +41 -0
  271. package/dist/input/touchScheme.d.ts +82 -6
  272. package/dist/input/touchScheme.js +123 -10
  273. package/dist/interaction/lockpick.d.ts +61 -0
  274. package/dist/interaction/lockpick.js +168 -0
  275. package/dist/interaction/proximityPrompt.d.ts +2 -0
  276. package/dist/interaction/proximityPrompt.js +2 -0
  277. package/dist/interaction/qte.d.ts +5 -0
  278. package/dist/interaction/qte.js +5 -0
  279. package/dist/interaction/skillCheck.d.ts +5 -0
  280. package/dist/interaction/skillCheck.js +5 -0
  281. package/dist/inventory/encumbrance.d.ts +69 -0
  282. package/dist/inventory/encumbrance.js +68 -0
  283. package/dist/inventory/inventoryModel.d.ts +12 -0
  284. package/dist/inventory/inventoryModel.js +12 -0
  285. package/dist/inventory/shapedGrid.d.ts +16 -0
  286. package/dist/inventory/shapedGrid.js +16 -0
  287. package/dist/inventory/slotModel.d.ts +10 -0
  288. package/dist/inventory/slotModel.js +10 -0
  289. package/dist/item/durability.d.ts +5 -0
  290. package/dist/item/durability.js +6 -3
  291. package/dist/item/itemIdentity.d.ts +171 -0
  292. package/dist/item/itemIdentity.js +138 -0
  293. package/dist/item/itemInstanceRegistry.d.ts +32 -0
  294. package/dist/item/itemInstanceRegistry.js +34 -0
  295. package/dist/item/itemgen.d.ts +163 -0
  296. package/dist/item/itemgen.js +151 -0
  297. package/dist/item/modularItem.d.ts +5 -0
  298. package/dist/item/modularItem.js +5 -0
  299. package/dist/item/use.d.ts +5 -0
  300. package/dist/item/use.js +5 -0
  301. package/dist/item/useBehavior.d.ts +142 -0
  302. package/dist/item/useBehavior.js +105 -0
  303. package/dist/item/weapon.d.ts +5 -0
  304. package/dist/item/weapon.js +5 -0
  305. package/dist/math/scalar.d.ts +25 -0
  306. package/dist/math/scalar.js +47 -0
  307. package/dist/meta/changelog.d.ts +4 -1
  308. package/dist/meta/changelog.js +39 -2
  309. package/dist/movement/avoidance.d.ts +45 -0
  310. package/dist/movement/avoidance.js +123 -0
  311. package/dist/movement/cameraRig.d.ts +8 -0
  312. package/dist/movement/cameraRig.js +8 -0
  313. package/dist/movement/dash.d.ts +11 -0
  314. package/dist/movement/dash.js +11 -0
  315. package/dist/movement/formation.d.ts +135 -0
  316. package/dist/movement/formation.js +194 -0
  317. package/dist/movement/glideModel.d.ts +5 -0
  318. package/dist/movement/glideModel.js +5 -0
  319. package/dist/movement/grappleSwing.d.ts +5 -0
  320. package/dist/movement/grappleSwing.js +5 -0
  321. package/dist/movement/leaderTrail.d.ts +5 -0
  322. package/dist/movement/leaderTrail.js +5 -0
  323. package/dist/movement/movementModel.d.ts +50 -9
  324. package/dist/movement/movementModel.js +75 -29
  325. package/dist/movement/playerMovement.js +167 -12
  326. package/dist/movement/poseState.d.ts +13 -0
  327. package/dist/movement/poseState.js +16 -0
  328. package/dist/movement/steering.d.ts +8 -0
  329. package/dist/movement/steering.js +18 -0
  330. package/dist/multiplayer/combatSnapshot.d.ts +3 -0
  331. package/dist/multiplayer/combatSnapshot.js +16 -8
  332. package/dist/multiplayer/lagCompensation.d.ts +5 -0
  333. package/dist/multiplayer/lagCompensation.js +5 -0
  334. package/dist/multiplayer/presenceModel.d.ts +11 -1
  335. package/dist/multiplayer/presenceModel.js +17 -1
  336. package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
  337. package/dist/multiplayer/simultaneousCommit.js +3 -0
  338. package/dist/multiplayer.d.ts +11 -0
  339. package/dist/multiplayer.js +11 -0
  340. package/dist/nav/pathFollow.d.ts +57 -0
  341. package/dist/nav/pathFollow.js +109 -0
  342. package/dist/orders/orderKinds.d.ts +156 -0
  343. package/dist/orders/orderKinds.js +197 -0
  344. package/dist/orders/orderQueue.d.ts +208 -0
  345. package/dist/orders/orderQueue.js +211 -0
  346. package/dist/physics/drivableVehicle.d.ts +31 -0
  347. package/dist/physics/drivableVehicle.js +16 -0
  348. package/dist/physics/flightDynamics.d.ts +82 -0
  349. package/dist/physics/flightDynamics.js +165 -0
  350. package/dist/physics/gravityField.d.ts +25 -0
  351. package/dist/physics/gravityField.js +41 -0
  352. package/dist/physics/kinematicVehicle.d.ts +108 -1
  353. package/dist/physics/kinematicVehicle.js +212 -15
  354. package/dist/physics/physicsWorld.d.ts +50 -12
  355. package/dist/physics/physicsWorld.js +120 -122
  356. package/dist/physics/radialImpulse.d.ts +25 -0
  357. package/dist/physics/radialImpulse.js +27 -0
  358. package/dist/physics/vehicleObstacles.d.ts +44 -0
  359. package/dist/physics/vehicleObstacles.js +115 -0
  360. package/dist/procedural.d.ts +3 -0
  361. package/dist/procedural.js +3 -0
  362. package/dist/progression/statGraph.d.ts +116 -0
  363. package/dist/progression/statGraph.js +318 -0
  364. package/dist/puzzle/cellGrid.d.ts +9 -0
  365. package/dist/puzzle/cellGrid.js +9 -0
  366. package/dist/puzzle/fallingPiece.d.ts +9 -0
  367. package/dist/puzzle/fallingPiece.js +9 -0
  368. package/dist/puzzle/nonogram.d.ts +39 -0
  369. package/dist/puzzle/nonogram.js +136 -0
  370. package/dist/random/nameGen.d.ts +5 -0
  371. package/dist/random/nameGen.js +5 -0
  372. package/dist/random/pick.d.ts +8 -0
  373. package/dist/random/pick.js +31 -0
  374. package/dist/random/rng.d.ts +26 -1
  375. package/dist/random/rng.js +32 -9
  376. package/dist/random/seedLink.d.ts +4 -0
  377. package/dist/random/seedLink.js +4 -0
  378. package/dist/relation/keyedValues.d.ts +54 -0
  379. package/dist/relation/keyedValues.js +115 -0
  380. package/dist/relation/thresholds.d.ts +62 -0
  381. package/dist/relation/thresholds.js +62 -0
  382. package/dist/render/color.d.ts +12 -0
  383. package/dist/render/color.js +26 -0
  384. package/dist/render/lookPreset.d.ts +41 -0
  385. package/dist/render/lookPreset.js +29 -0
  386. package/dist/render/postProcessing.d.ts +20 -0
  387. package/dist/render/postProcessing.js +21 -1
  388. package/dist/rules/predicate.d.ts +53 -0
  389. package/dist/rules/predicate.js +64 -0
  390. package/dist/rules/ruleEffects.d.ts +38 -0
  391. package/dist/rules/ruleEffects.js +37 -0
  392. package/dist/rules/triggeredRules.d.ts +160 -0
  393. package/dist/rules/triggeredRules.js +241 -0
  394. package/dist/runtime/adapter.d.ts +55 -3
  395. package/dist/runtime/adapter.js +57 -1
  396. package/dist/runtime/cameraDirector.d.ts +1 -0
  397. package/dist/runtime/cameraDirector.js +1 -0
  398. package/dist/runtime/commandRunner.d.ts +1 -0
  399. package/dist/runtime/commandRunner.js +1 -0
  400. package/dist/runtime/context/combat.d.ts +51 -0
  401. package/dist/runtime/context/combat.js +130 -0
  402. package/dist/runtime/context/combatFx.d.ts +23 -0
  403. package/dist/runtime/context/combatFx.js +161 -0
  404. package/dist/runtime/context/deathLoot.d.ts +30 -0
  405. package/dist/runtime/context/deathLoot.js +39 -0
  406. package/dist/runtime/context/player.d.ts +48 -0
  407. package/dist/runtime/context/player.js +125 -0
  408. package/dist/runtime/context/registries.d.ts +13 -0
  409. package/dist/runtime/context/registries.js +84 -0
  410. package/dist/runtime/context/scene.d.ts +59 -0
  411. package/dist/runtime/context/scene.js +291 -0
  412. package/dist/runtime/context/snapshotCodecs.d.ts +12 -0
  413. package/dist/runtime/context/snapshotCodecs.js +26 -0
  414. package/dist/runtime/context/worldItems.d.ts +21 -0
  415. package/dist/runtime/context/worldItems.js +37 -0
  416. package/dist/runtime/descriptors/baseline.d.ts +48 -0
  417. package/dist/runtime/descriptors/baseline.js +157 -0
  418. package/dist/runtime/descriptors/features.d.ts +79 -0
  419. package/dist/runtime/descriptors/features.js +299 -0
  420. package/dist/runtime/gameContext.d.ts +2 -327
  421. package/dist/runtime/gameContext.js +273 -778
  422. package/dist/runtime/gameContextTypes.d.ts +467 -0
  423. package/dist/runtime/gameContextTypes.js +1 -0
  424. package/dist/runtime/gameRuntime.d.ts +1 -0
  425. package/dist/runtime/gameRuntime.js +1 -0
  426. package/dist/runtime/headlessRunner.d.ts +62 -0
  427. package/dist/runtime/headlessRunner.js +45 -0
  428. package/dist/runtime/hostPersistence.d.ts +12 -0
  429. package/dist/runtime/hostPersistence.js +12 -0
  430. package/dist/runtime/hostPolicy.d.ts +51 -0
  431. package/dist/runtime/hostPolicy.js +68 -0
  432. package/dist/runtime/hostedGameRunner.d.ts +11 -4
  433. package/dist/runtime/hostedGameRunner.js +27 -3
  434. package/dist/runtime/hostedWorldSession.d.ts +15 -5
  435. package/dist/runtime/hostedWorldSession.js +12 -4
  436. package/dist/runtime/inputSnapshot.d.ts +8 -3
  437. package/dist/runtime/inputSnapshot.js +6 -2
  438. package/dist/runtime/motionIntents.d.ts +11 -2
  439. package/dist/runtime/motionIntents.js +16 -2
  440. package/dist/runtime/perContext.d.ts +15 -0
  441. package/dist/runtime/perContext.js +21 -0
  442. package/dist/runtime/runtimeSave.d.ts +79 -0
  443. package/dist/runtime/runtimeSave.js +105 -0
  444. package/dist/runtime/save.d.ts +4 -0
  445. package/dist/runtime/save.js +4 -0
  446. package/dist/runtime/snapshot.d.ts +7 -0
  447. package/dist/runtime/snapshot.js +7 -0
  448. package/dist/runtime/visibility.d.ts +2 -1
  449. package/dist/runtime/visibility.js +2 -1
  450. package/dist/runtime/worldChannel.d.ts +7 -3
  451. package/dist/runtime/worldChannel.js +51 -6
  452. package/dist/runtime/worldMirror.d.ts +14 -2
  453. package/dist/runtime/worldMirror.js +15 -2
  454. package/dist/runtime/worldProjection.d.ts +47 -0
  455. package/dist/runtime/worldProjection.js +52 -0
  456. package/dist/runtime/worldReplication.d.ts +30 -7
  457. package/dist/runtime/worldReplication.js +41 -9
  458. package/dist/runtime/worldSnapshot.d.ts +42 -3
  459. package/dist/runtime/worldSnapshot.js +34 -7
  460. package/dist/scene/assetCatalog.d.ts +26 -0
  461. package/dist/scene/assetCatalog.js +4 -0
  462. package/dist/scene/assetDiagnostics.d.ts +69 -0
  463. package/dist/scene/assetDiagnostics.js +110 -0
  464. package/dist/scene/assetGenerator.d.ts +65 -0
  465. package/dist/scene/assetGenerator.js +64 -0
  466. package/dist/scene/assetSpace.d.ts +137 -0
  467. package/dist/scene/assetSpace.js +257 -0
  468. package/dist/scene/authoredTriggers.d.ts +219 -0
  469. package/dist/scene/authoredTriggers.js +454 -0
  470. package/dist/scene/behaviorRuntime.d.ts +75 -0
  471. package/dist/scene/behaviorRuntime.js +217 -0
  472. package/dist/scene/behaviors.d.ts +14 -2
  473. package/dist/scene/behaviors.js +7 -2
  474. package/dist/scene/bodyBind.d.ts +60 -0
  475. package/dist/scene/bodyBind.js +51 -0
  476. package/dist/scene/builtinSceneKinds.d.ts +5 -0
  477. package/dist/scene/builtinSceneKinds.js +67 -0
  478. package/dist/scene/colliders.d.ts +71 -1
  479. package/dist/scene/colliders.js +145 -1
  480. package/dist/scene/collisionMesh.d.ts +94 -0
  481. package/dist/scene/collisionMesh.js +699 -0
  482. package/dist/scene/companion.d.ts +147 -0
  483. package/dist/scene/companion.js +193 -0
  484. package/dist/scene/entityStats.d.ts +18 -11
  485. package/dist/scene/entityStats.js +21 -16
  486. package/dist/scene/entityStore.d.ts +12 -1
  487. package/dist/scene/entityStore.js +15 -0
  488. package/dist/scene/facing.d.ts +18 -0
  489. package/dist/scene/facing.js +26 -0
  490. package/dist/scene/modelSockets.d.ts +33 -0
  491. package/dist/scene/modelSockets.js +29 -0
  492. package/dist/scene/objectQuery.d.ts +2 -0
  493. package/dist/scene/objectQuery.js +2 -0
  494. package/dist/scene/objectStore.d.ts +4 -0
  495. package/dist/scene/objectStore.js +6 -0
  496. package/dist/scene/possession.d.ts +8 -0
  497. package/dist/scene/possession.js +14 -0
  498. package/dist/scene/roster.d.ts +3 -0
  499. package/dist/scene/roster.js +12 -0
  500. package/dist/scene/sceneKinds.d.ts +256 -0
  501. package/dist/scene/sceneKinds.js +218 -0
  502. package/dist/scene/sceneOwnership.d.ts +169 -0
  503. package/dist/scene/sceneOwnership.js +179 -0
  504. package/dist/scene/sceneRaycast.js +15 -0
  505. package/dist/scene/selectionBookmarks.d.ts +93 -0
  506. package/dist/scene/selectionBookmarks.js +122 -0
  507. package/dist/scene/vehicleSeat.d.ts +68 -0
  508. package/dist/scene/vehicleSeat.js +59 -0
  509. package/dist/sensor/concealment.d.ts +3 -0
  510. package/dist/sensor/concealment.js +3 -0
  511. package/dist/sensor/freezeMonitor.d.ts +1 -0
  512. package/dist/sensor/freezeMonitor.js +1 -0
  513. package/dist/sensor/frustumSensor.d.ts +7 -3
  514. package/dist/sensor/frustumSensor.js +7 -3
  515. package/dist/sensor/hiddenStateProbe.d.ts +5 -2
  516. package/dist/sensor/hiddenStateProbe.js +5 -2
  517. package/dist/sensor/recordingBuffer.d.ts +2 -1
  518. package/dist/sensor/recordingBuffer.js +2 -1
  519. package/dist/sensor/replayLoop.d.ts +6 -2
  520. package/dist/sensor/replayLoop.js +6 -2
  521. package/dist/sensor/revealQuery.d.ts +2 -1
  522. package/dist/sensor/revealQuery.js +2 -1
  523. package/dist/sensor/visionCone.d.ts +10 -3
  524. package/dist/sensor/visionCone.js +10 -3
  525. package/dist/session/contestedChannel.d.ts +1 -0
  526. package/dist/session/contestedChannel.js +1 -0
  527. package/dist/session/extraction.d.ts +1 -0
  528. package/dist/session/extraction.js +1 -0
  529. package/dist/session/roles.d.ts +6 -0
  530. package/dist/session/roles.js +6 -0
  531. package/dist/session/roundState.d.ts +8 -0
  532. package/dist/session/roundState.js +2 -0
  533. package/dist/settings/settingsModel.d.ts +1 -0
  534. package/dist/settings/settingsModel.js +1 -0
  535. package/dist/stats/accumulatorMeter.d.ts +6 -0
  536. package/dist/stats/accumulatorMeter.js +6 -0
  537. package/dist/stats/eventMeter.d.ts +5 -0
  538. package/dist/stats/eventMeter.js +5 -0
  539. package/dist/stats/rollCheck.d.ts +5 -0
  540. package/dist/stats/rollCheck.js +5 -0
  541. package/dist/stats/spawnLevelStats.d.ts +110 -0
  542. package/dist/stats/spawnLevelStats.js +140 -0
  543. package/dist/stats/statModifiers.d.ts +5 -0
  544. package/dist/stats/statModifiers.js +5 -0
  545. package/dist/stats/statPool.d.ts +70 -0
  546. package/dist/stats/statPool.js +59 -0
  547. package/dist/store/changeSignal.d.ts +3 -0
  548. package/dist/store/changeSignal.js +2 -0
  549. package/dist/store/defineKeyedStore.d.ts +38 -0
  550. package/dist/store/defineKeyedStore.js +42 -0
  551. package/dist/store/defineStore.d.ts +33 -0
  552. package/dist/store/defineStore.js +35 -0
  553. package/dist/store/observableKeyedStore.d.ts +7 -0
  554. package/dist/store/observableKeyedStore.js +35 -2
  555. package/dist/survival/decayMeter.d.ts +55 -0
  556. package/dist/survival/decayMeter.js +130 -57
  557. package/dist/survival/moodle.d.ts +2 -0
  558. package/dist/survival/regionHealth.d.ts +6 -0
  559. package/dist/survival/regionHealth.js +6 -3
  560. package/dist/tactics/fallingGrid.d.ts +4 -2
  561. package/dist/tactics/fallingGrid.js +4 -2
  562. package/dist/tactics/predictiveQuery.d.ts +3 -0
  563. package/dist/tactics/predictiveQuery.js +3 -0
  564. package/dist/tactics/snapshot.d.ts +2 -0
  565. package/dist/tactics/snapshot.js +2 -0
  566. package/dist/tactics/surface.d.ts +1 -0
  567. package/dist/tactics/surface.js +1 -0
  568. package/dist/tactics/tacticalGrid.d.ts +1 -0
  569. package/dist/tactics/tacticalGrid.js +1 -0
  570. package/dist/time/beatClock.d.ts +14 -4
  571. package/dist/time/beatClock.js +14 -4
  572. package/dist/time/calendarClock.d.ts +3 -0
  573. package/dist/time/calendarClock.js +3 -0
  574. package/dist/time/idleProgress.d.ts +4 -0
  575. package/dist/time/idleProgress.js +4 -0
  576. package/dist/time/simClock.d.ts +2 -0
  577. package/dist/time/simClock.js +20 -5
  578. package/dist/ui/actionModel.d.ts +110 -0
  579. package/dist/ui/actionModel.js +159 -0
  580. package/dist/ui/gameLayout.d.ts +30 -11
  581. package/dist/ui/gameLayout.js +30 -11
  582. package/dist/ui/hudDocument.d.ts +114 -0
  583. package/dist/ui/hudDocument.js +220 -0
  584. package/dist/ui/hudLayout.d.ts +38 -1
  585. package/dist/ui/hudLayout.js +220 -17
  586. package/dist/ui/selectionModel.d.ts +92 -0
  587. package/dist/ui/selectionModel.js +88 -0
  588. package/dist/ui/tooltipModel.d.ts +63 -0
  589. package/dist/ui/tooltipModel.js +82 -0
  590. package/dist/ui.d.ts +15 -0
  591. package/dist/ui.js +15 -0
  592. package/dist/visibility/bounds.d.ts +8 -1
  593. package/dist/visibility/bounds.js +8 -1
  594. package/dist/visibility/frustum.d.ts +12 -3
  595. package/dist/visibility/frustum.js +12 -3
  596. package/dist/work/jobQueue.d.ts +201 -0
  597. package/dist/work/jobQueue.js +253 -0
  598. package/dist/work/unitTraining.d.ts +58 -0
  599. package/dist/work/unitTraining.js +52 -0
  600. package/dist/world/authoredEntities.d.ts +29 -0
  601. package/dist/world/authoredEntities.js +29 -0
  602. package/dist/world/authoredObjects.d.ts +72 -0
  603. package/dist/world/authoredObjects.js +81 -0
  604. package/dist/world/authoredSpawn.d.ts +39 -0
  605. package/dist/world/authoredSpawn.js +37 -0
  606. package/dist/world/buildSockets.d.ts +152 -0
  607. package/dist/world/buildSockets.js +188 -0
  608. package/dist/world/buildingGenerator.d.ts +18 -0
  609. package/dist/world/buildingGenerator.js +62 -0
  610. package/dist/world/buildings.d.ts +5 -0
  611. package/dist/world/buildings.js +5 -0
  612. package/dist/world/catenary.d.ts +22 -0
  613. package/dist/world/catenary.js +69 -0
  614. package/dist/world/cityBlocks.d.ts +152 -0
  615. package/dist/world/cityBlocks.js +670 -0
  616. package/dist/world/cityContent.d.ts +77 -0
  617. package/dist/world/cityContent.js +261 -0
  618. package/dist/world/cityGeometry.d.ts +114 -0
  619. package/dist/world/cityGeometry.js +573 -0
  620. package/dist/world/cityKind.d.ts +314 -0
  621. package/dist/world/cityKind.js +1578 -0
  622. package/dist/world/features.d.ts +133 -10
  623. package/dist/world/features.js +66 -6
  624. package/dist/world/footprintGrid.d.ts +59 -0
  625. package/dist/world/footprintGrid.js +141 -0
  626. package/dist/world/geometry.d.ts +64 -0
  627. package/dist/world/geometry.js +94 -0
  628. package/dist/world/grassKind.d.ts +51 -0
  629. package/dist/world/grassKind.js +101 -0
  630. package/dist/world/markers.d.ts +50 -4
  631. package/dist/world/markers.js +49 -0
  632. package/dist/world/massing.js +1 -1
  633. package/dist/world/minimapBake.d.ts +78 -0
  634. package/dist/world/minimapBake.js +208 -0
  635. package/dist/world/minimapTrack.d.ts +17 -0
  636. package/dist/world/minimapTrack.js +22 -0
  637. package/dist/world/pathInstances.d.ts +27 -0
  638. package/dist/world/pathInstances.js +27 -0
  639. package/dist/world/pathNetwork.d.ts +159 -0
  640. package/dist/world/pathNetwork.js +684 -0
  641. package/dist/world/pathTerrain.d.ts +80 -0
  642. package/dist/world/pathTerrain.js +142 -0
  643. package/dist/world/place.d.ts +166 -0
  644. package/dist/world/place.js +96 -0
  645. package/dist/world/placeAsset.d.ts +81 -0
  646. package/dist/world/placeAsset.js +79 -0
  647. package/dist/world/placement.d.ts +4 -0
  648. package/dist/world/placement.js +4 -0
  649. package/dist/world/placementController.d.ts +6 -0
  650. package/dist/world/placementController.js +6 -0
  651. package/dist/world/poleLineKind.d.ts +40 -0
  652. package/dist/world/poleLineKind.js +97 -0
  653. package/dist/world/polyline.d.ts +34 -0
  654. package/dist/world/polyline.js +88 -0
  655. package/dist/world/resourceNode.d.ts +109 -0
  656. package/dist/world/resourceNode.js +140 -0
  657. package/dist/world/roads.d.ts +8 -0
  658. package/dist/world/roads.js +38 -0
  659. package/dist/world/scatter.js +2 -20
  660. package/dist/world/scatterRegion.d.ts +164 -0
  661. package/dist/world/scatterRegion.js +409 -0
  662. package/dist/world/sceneShapes.d.ts +43 -0
  663. package/dist/world/sceneShapes.js +1 -0
  664. package/dist/world/segment.d.ts +27 -0
  665. package/dist/world/segment.js +43 -0
  666. package/dist/world/soilKind.d.ts +48 -0
  667. package/dist/world/soilKind.js +92 -0
  668. package/dist/world/spatialSample.d.ts +241 -0
  669. package/dist/world/spatialSample.js +465 -0
  670. package/dist/world/streets.d.ts +29 -0
  671. package/dist/world/streets.js +55 -0
  672. package/dist/world/terraform.d.ts +213 -1
  673. package/dist/world/terraform.js +627 -22
  674. package/dist/world/terrain.d.ts +164 -20
  675. package/dist/world/terrain.js +325 -41
  676. package/dist/world/terrainGuides.d.ts +182 -0
  677. package/dist/world/terrainGuides.js +343 -0
  678. package/dist/world/vec2.d.ts +81 -0
  679. package/dist/world/vec2.js +128 -0
  680. package/dist/world/vec3.d.ts +49 -0
  681. package/dist/world/vec3.js +76 -0
  682. package/dist/world/vegetation.d.ts +71 -0
  683. package/dist/world/vegetation.js +151 -0
  684. package/dist/world/visibilityField.d.ts +154 -0
  685. package/dist/world/visibilityField.js +271 -0
  686. package/dist/world/volumetricClouds.d.ts +52 -0
  687. package/dist/world/volumetricClouds.js +43 -0
  688. package/dist/world/walls.d.ts +9 -0
  689. package/dist/world/walls.js +9 -0
  690. package/dist/world/waterKind.d.ts +55 -0
  691. package/dist/world/waterKind.js +99 -0
  692. package/dist/world.d.ts +141 -0
  693. package/dist/world.js +141 -0
  694. package/package.json +32 -8
  695. package/skills/game-design/SKILL.md +28 -0
  696. package/skills/game-design/agents/openai.yaml +4 -0
  697. package/skills/game-design/references/application-playbook.md +170 -0
  698. package/skills/game-design/references/field-guide.md +288 -0
  699. package/skills/jgengine/SKILL.md +54 -0
  700. package/skills/jgengine/api.md +527 -0
  701. package/skills/jgengine/capabilities.md +131 -0
  702. package/skills/jgengine/recipes/minimal-game.md +88 -0
  703. package/skills/jgengine-combat/SKILL.md +38 -0
  704. package/skills/jgengine-combat/api.md +585 -0
  705. package/skills/jgengine-combat/capabilities.md +213 -0
  706. package/skills/jgengine-combat/recipes/portable-stat-pools.md +122 -0
  707. package/skills/jgengine-combat/reference.md +108 -0
  708. package/skills/jgengine-gameplay/SKILL.md +39 -0
  709. package/skills/jgengine-gameplay/api.md +1920 -0
  710. package/skills/jgengine-gameplay/capabilities.md +454 -0
  711. package/skills/jgengine-gameplay/reference-systems.md +56 -0
  712. package/skills/jgengine-world/SKILL.md +51 -0
  713. package/skills/jgengine-world/api.md +3056 -0
  714. package/skills/jgengine-world/capabilities.md +476 -0
  715. package/skills/jgengine-world/recipes/commanding-entities.md +128 -0
  716. package/skills/jgengine-world/reference.md +261 -0
  717. package/dist/cartridge/runtime.d.ts +0 -15
  718. package/dist/cartridge/runtime.js +0 -556
  719. package/dist/cartridge/spec.d.ts +0 -188
  720. package/dist/cartridge/spec.js +0 -19
  721. package/dist/cartridge/validate.d.ts +0 -2
  722. package/dist/cartridge/validate.js +0 -78
  723. package/dist/store/engineStore.d.ts +0 -22
  724. package/dist/store/engineStore.js +0 -50
  725. package/dist/store/features.d.ts +0 -10
  726. package/dist/store/features.js +0 -23
  727. package/llms.txt +0 -5389
@@ -2,34 +2,129 @@ import { steerYaw } from "../movement/steering.js";
2
2
  import { DEFAULT_GRIP_CURVE, sampleGripCurve } from "./vehicleBody.js";
3
3
  export function createKinematicVehicle(tuning, options = {}) {
4
4
  const grip = tuning.grip ?? DEFAULT_GRIP_CURVE;
5
+ const chassis = tuning.chassis;
5
6
  const rollingResistance = tuning.rollingResistance ?? 0;
6
7
  const surfaceFriction = options.surfaceFriction ?? (() => 1);
7
8
  const dragAt = options.dragAt ?? (() => 0);
9
+ const clampMove = options.clampMove;
8
10
  let x = options.position?.[0] ?? 0;
9
11
  let y = options.position?.[1] ?? 0;
10
12
  let z = options.position?.[2] ?? 0;
11
13
  let heading = options.heading ?? 0;
12
14
  let vx = 0;
13
15
  let vz = 0;
16
+ let gearIndex = 0;
17
+ let rpm = tuning.powertrain?.idleRpm ?? 0;
18
+ let shiftRemaining = 0;
19
+ let steerAngle = 0;
20
+ let yawRate = 0;
21
+ let previousForwardSpeed = 0;
22
+ let bodyPitch = 0;
23
+ let bodyRoll = 0;
14
24
  function forward() {
15
25
  return [Math.sin(heading), Math.cos(heading)];
16
26
  }
17
27
  return {
18
- tick(dt, axis) {
28
+ tick(dt, axis, modifiers) {
29
+ const topSpeed = tuning.topSpeed * (modifiers?.topSpeedScale ?? 1);
30
+ const engineAccel = tuning.engineAccel * (modifiers?.accelScale ?? 1);
31
+ const turnRate = tuning.turnRate * (modifiers?.turnRateScale ?? 1);
19
32
  const [fx0, fz0] = forward();
20
33
  const speed = vx * fx0 + vz * fz0;
21
- const steerScale = Math.min(1, Math.abs(speed) / tuning.turnSpeedRef);
22
- const direction = speed >= 0 ? 1 : -1;
23
- heading = steerYaw(heading, axis.steer * steerScale * direction, tuning.turnRate, dt);
34
+ if (tuning.steering === undefined) {
35
+ const steerScale = Math.min(1, Math.abs(speed) / tuning.turnSpeedRef);
36
+ const direction = speed >= 0 ? 1 : -1;
37
+ heading = steerYaw(heading, axis.steer * steerScale * direction, turnRate, dt);
38
+ yawRate = dt > 0 ? -axis.steer * steerScale * direction * turnRate : 0;
39
+ steerAngle = axis.steer;
40
+ }
41
+ else {
42
+ const steering = tuning.steering;
43
+ const speedBlend = Math.min(1, Math.abs(speed) / Math.max(0.001, steering.highSpeedAt));
44
+ const lock = steering.maxAngle + (steering.highSpeedAngle - steering.maxAngle) * speedBlend;
45
+ const targetAngle = axis.steer * lock * (modifiers?.turnRateScale ?? 1);
46
+ const response = 1 - Math.exp(-Math.max(0, steering.response) * Math.max(0, dt));
47
+ steerAngle += (targetAngle - steerAngle) * response;
48
+ const targetYaw = Math.abs(speed) < 0.05 ? 0 : -(speed / Math.max(0.1, steering.wheelbase)) * Math.tan(steerAngle);
49
+ const yawResponse = 1 - Math.exp(-Math.max(0, steering.yawDamping ?? 10) * Math.max(0, dt));
50
+ yawRate += (targetYaw - yawRate) * yawResponse;
51
+ heading += yawRate * dt;
52
+ }
24
53
  const [fx, fz] = forward();
25
54
  let accel = 0;
26
- if (axis.throttle > 0 && speed < tuning.topSpeed)
27
- accel += axis.throttle * tuning.engineAccel;
55
+ let tractionLimited = false;
56
+ let absActive = false;
57
+ let wheelspin = false;
58
+ // Powertrain state tracks wheel speed EVERY tick (not just under throttle): the engine keeps
59
+ // spinning with the wheels, so rpm, gear and downshifts stay live while coasting or braking. That
60
+ // is what makes engine braking below gear-dependent. Drive torque itself is still applied only on
61
+ // throttle; `gearLeverage` (current ratio / top-gear ratio) is `1` in top gear and grows in the
62
+ // low gears the car downshifts into as it slows.
63
+ let torqueFactor = 1;
64
+ let gearLeverage = 1;
65
+ if (tuning.powertrain !== undefined) {
66
+ const powertrain = tuning.powertrain;
67
+ shiftRemaining = Math.max(0, shiftRemaining - dt);
68
+ const ratio = powertrain.gears[Math.min(gearIndex, powertrain.gears.length - 1)] ?? 1;
69
+ const topGearRatio = powertrain.gears[powertrain.gears.length - 1] ?? ratio;
70
+ gearLeverage = topGearRatio > 0 ? Math.min(ENGINE_BRAKE_MAX_LEVERAGE, ratio / topGearRatio) : 1;
71
+ const wheelRpm = Math.abs(speed) / Math.max(0.01, powertrain.wheelRadius) * 60 / (Math.PI * 2);
72
+ rpm = Math.max(powertrain.idleRpm, Math.min(powertrain.redlineRpm, wheelRpm * ratio * powertrain.finalDrive));
73
+ if (shiftRemaining <= 0 && rpm >= powertrain.shiftUpRpm && gearIndex < powertrain.gears.length - 1) {
74
+ gearIndex += 1;
75
+ shiftRemaining = powertrain.shiftSeconds;
76
+ }
77
+ else if (shiftRemaining <= 0 && rpm <= powertrain.shiftDownRpm && gearIndex > 0) {
78
+ gearIndex -= 1;
79
+ shiftRemaining = powertrain.shiftSeconds;
80
+ }
81
+ const normalizedRpm = (rpm - powertrain.idleRpm) / Math.max(1, powertrain.redlineRpm - powertrain.idleRpm);
82
+ const torque = sampleGripCurve(powertrain.torqueCurve, normalizedRpm);
83
+ torqueFactor = torque * (shiftRemaining > 0 ? 0.32 : 1);
84
+ }
85
+ if (axis.throttle > 0 && speed < topSpeed) {
86
+ accel += chassis === undefined
87
+ ? axis.throttle * engineAccel * torqueFactor
88
+ : (axis.throttle * chassis.engineForce * (modifiers?.accelScale ?? 1) * torqueFactor) / chassis.massKg;
89
+ }
28
90
  if (axis.brake > 0) {
29
- if (speed > 0.2)
30
- accel -= axis.brake * tuning.brakeAccel;
31
- else if (speed > -tuning.reverseSpeed)
32
- accel -= axis.brake * tuning.engineAccel;
91
+ if (speed > 0.2) {
92
+ const abs = tuning.dynamics?.abs ?? 0;
93
+ const brakeScale = Math.max(0.15, 1 - abs * Math.max(0, Math.abs(speed) / Math.max(1, topSpeed) - 0.72));
94
+ absActive = brakeScale < 0.999;
95
+ accel -= chassis === undefined
96
+ ? axis.brake * tuning.brakeAccel * brakeScale
97
+ : (axis.brake * chassis.brakeForce * brakeScale) / chassis.massKg;
98
+ }
99
+ else if (speed > -tuning.reverseSpeed) {
100
+ accel -= chassis === undefined
101
+ ? axis.brake * engineAccel
102
+ : (axis.brake * chassis.engineForce * (modifiers?.accelScale ?? 1)) / chassis.massKg;
103
+ }
104
+ }
105
+ const traction = tuning.dynamics?.tractionControl ?? 0;
106
+ if (traction > 0 && Math.abs(speed) > 0.5) {
107
+ const lateral = Math.abs(-vx * fz + vz * fx);
108
+ const excess = Math.max(0, lateral / (Math.abs(speed) + 1) - 0.18);
109
+ if (excess > 0) {
110
+ accel *= Math.max(0.2, 1 - excess * traction * 3);
111
+ tractionLimited = true;
112
+ }
113
+ }
114
+ // Coast resistance for the mass-and-force chassis (#1051) — derived from the vehicle's own weight,
115
+ // gravity, and gearing, never a flat "brake force" constant. Two weight-based terms:
116
+ // • rolling resistance F = μ_rr · m · g (always, the road-load floor)
117
+ // • engine braking F = μ_eb · m · g · gearLeverage (throttle lifted, in gear)
118
+ // Engine braking is routed through the CURRENT gear, so it strengthens as the car downshifts toward
119
+ // a stop — exactly like lifting off in a real drivetrain. Both are forces (∝ m·g) whose per-mass
120
+ // deceleration is weight-independent and gear-scaled; the per-tick decel is capped so coasting can
121
+ // never push the car backwards.
122
+ if (chassis !== undefined && dt > 0 && Math.abs(speed) > 1e-4) {
123
+ let resistDecel = ROLLING_RESISTANCE_COEFFICIENT * GRAVITY;
124
+ if (axis.throttle <= 0 && tuning.powertrain !== undefined) {
125
+ resistDecel += ENGINE_BRAKE_COEFFICIENT * GRAVITY * gearLeverage;
126
+ }
127
+ accel -= Math.sign(speed) * Math.min(resistDecel, Math.abs(speed) / dt);
33
128
  }
34
129
  vx += fx * accel * dt;
35
130
  vz += fz * accel * dt;
@@ -38,11 +133,41 @@ export function createKinematicVehicle(tuning, options = {}) {
38
133
  const surface = surfaceFriction(x, z);
39
134
  const slip = Math.abs(lateralSpeed) / (Math.abs(forwardSpeed) + 1);
40
135
  const handbrakeFactor = 1 - axis.handbrake * (1 - tuning.handbrakeGrip);
41
- const gripValue = sampleGripCurve(grip, slip) * surface * handbrakeFactor;
136
+ const downforce = 1 + (tuning.dynamics?.downforce ?? 0) * Math.min(1, Math.abs(forwardSpeed) / Math.max(1, topSpeed));
137
+ const gripValue = sampleGripCurve(grip, slip) * surface * handbrakeFactor * downforce;
42
138
  const keep = Math.max(0, 1 - gripValue * tuning.gripStrength * dt);
43
- const keptLateral = lateralSpeed * keep;
139
+ const stability = tuning.dynamics?.stabilityControl ?? 0;
140
+ let keptLateral = lateralSpeed * keep * Math.max(0, 1 - stability * Math.abs(axis.steer) * dt);
141
+ if (chassis !== undefined) {
142
+ // Friction budget (#1051): total tire force F = μeff * m * g, with μeff = tireGrip * gripValue
143
+ // (grip curve * surface * handbrake * downforce). Lateral load transfer (|centripetal accel| *
144
+ // comHeight / (trackWidth * g), capped ~0.6) shrinks the lateral share so tall/narrow chassis wash
145
+ // out earlier. Lateral consumes its capped share first; only the remainder feeds drive/brake.
146
+ const capacity = chassis.tireGrip * gripValue * chassis.massKg * GRAVITY;
147
+ const transfer = Math.min(0.6, (Math.abs(yawRate * forwardSpeed) * chassis.comHeight) / (Math.max(0.1, chassis.trackWidth) * GRAVITY));
148
+ const lateralCapacity = capacity * (1 - 0.5 * transfer);
149
+ const reductionWanted = lateralSpeed - keptLateral;
150
+ const maxReduction = dt > 0 ? (lateralCapacity * dt) / chassis.massKg : 0;
151
+ let reductionActual = reductionWanted;
152
+ if (Math.abs(reductionWanted) > maxReduction) {
153
+ reductionActual = Math.sign(reductionWanted) * maxReduction;
154
+ keptLateral = lateralSpeed - reductionActual;
155
+ }
156
+ const lateralForceUsed = dt > 0 ? (chassis.massKg * Math.abs(reductionActual)) / dt : 0;
157
+ const remainingLong = Math.max(0, capacity - lateralForceUsed);
158
+ if (chassis.massKg * Math.abs(accel) > remainingLong) {
159
+ const actualAccel = (Math.sign(accel) * remainingLong) / chassis.massKg;
160
+ forwardSpeed -= (accel - actualAccel) * dt;
161
+ if (accel > 0 && axis.throttle > 0)
162
+ wheelspin = true;
163
+ }
164
+ }
44
165
  if (rollingResistance > 0)
45
166
  forwardSpeed *= Math.max(0, 1 - rollingResistance * dt);
167
+ const aerodynamicDrag = tuning.dynamics?.aerodynamicDrag ?? 0;
168
+ if (aerodynamicDrag > 0) {
169
+ forwardSpeed *= 1 / (1 + aerodynamicDrag * Math.abs(forwardSpeed) * dt);
170
+ }
46
171
  vx = fx * forwardSpeed - fz * keptLateral;
47
172
  vz = fz * forwardSpeed + fx * keptLateral;
48
173
  const drag = dragAt(x, z);
@@ -52,15 +177,58 @@ export function createKinematicVehicle(tuning, options = {}) {
52
177
  vx *= dragDamp;
53
178
  vz *= dragDamp;
54
179
  }
55
- x += vx * dt;
56
- z += vz * dt;
180
+ const toX = x + vx * dt;
181
+ const toZ = z + vz * dt;
182
+ if (clampMove !== undefined && dt > 0) {
183
+ const allowed = clampMove([x, z], [toX, toZ]);
184
+ vx = (allowed[0] - x) / dt;
185
+ vz = (allowed[1] - z) / dt;
186
+ x = allowed[0];
187
+ z = allowed[1];
188
+ }
189
+ else {
190
+ x = toX;
191
+ z = toZ;
192
+ }
193
+ // Rest snap (#1051): parked with no throttle/brake/handbrake and sub-threshold motion → exact zero,
194
+ // killing residual creep and jitter. Zeroing previousForwardSpeed keeps the stop free of a pitch spike.
195
+ if (chassis !== undefined &&
196
+ axis.throttle <= 0 &&
197
+ axis.brake <= 0 &&
198
+ axis.handbrake <= 0 &&
199
+ Math.abs(vx * fx + vz * fz) < 0.2 &&
200
+ Math.abs(-vx * fz + vz * fx) < 0.2) {
201
+ vx = 0;
202
+ vz = 0;
203
+ forwardSpeed = 0;
204
+ previousForwardSpeed = 0;
205
+ }
206
+ const longitudinalAcceleration = dt > 0 ? (forwardSpeed - previousForwardSpeed) / dt : 0;
207
+ previousForwardSpeed = forwardSpeed;
208
+ const attitudeResponse = 1 - Math.exp(-Math.max(0, tuning.dynamics?.attitudeResponse ?? 7) * Math.max(0, dt));
209
+ // comHeight scales brake dive / throttle squat and cornering lean (#1051); `1` without a chassis.
210
+ const comScale = chassis !== undefined ? chassis.comHeight : 1;
211
+ const targetPitch = clampSigned(-longitudinalAcceleration * (tuning.dynamics?.bodyPitchFactor ?? 0) * comScale, tuning.dynamics?.maxBodyPitch ?? 0.12);
212
+ const targetRoll = clampSigned(-yawRate * forwardSpeed * (tuning.dynamics?.bodyRollFactor ?? 0) * comScale, tuning.dynamics?.maxBodyRoll ?? 0.16);
213
+ bodyPitch += (targetPitch - bodyPitch) * attitudeResponse;
214
+ bodyRoll += (targetRoll - bodyRoll) * attitudeResponse;
57
215
  return {
58
216
  position: [x, y, z],
59
217
  heading,
60
218
  forwardSpeed: vx * fx + vz * fz,
61
- lateralSpeed: keptLateral * dragDamp,
219
+ lateralSpeed: -vx * fz + vz * fx,
62
220
  slip,
63
221
  surface,
222
+ gear: speed < -0.2 ? 0 : gearIndex + 1,
223
+ rpm,
224
+ steerAngle,
225
+ yawRate,
226
+ longitudinalAcceleration,
227
+ tractionLimited,
228
+ absActive,
229
+ wheelspin,
230
+ bodyPitch,
231
+ bodyRoll,
64
232
  };
65
233
  },
66
234
  pose: () => ({ position: [x, y, z], heading }),
@@ -76,6 +244,35 @@ export function createKinematicVehicle(tuning, options = {}) {
76
244
  heading = nextHeading;
77
245
  vx = 0;
78
246
  vz = 0;
247
+ gearIndex = 0;
248
+ rpm = tuning.powertrain?.idleRpm ?? 0;
249
+ shiftRemaining = 0;
250
+ steerAngle = 0;
251
+ yawRate = 0;
252
+ previousForwardSpeed = 0;
253
+ bodyPitch = 0;
254
+ bodyRoll = 0;
79
255
  },
80
256
  };
81
257
  }
258
+ /** Gravitational acceleration, m/s², for the chassis friction budget and weight-transfer ratio (#1051). */
259
+ const GRAVITY = 9.81;
260
+ /**
261
+ * Tyre rolling-resistance coefficient μ_rr (#1051). The always-present coast force is `μ_rr · m · g`
262
+ * (the road-load floor) — a little high vs. a real ~0.013 tyre so a lifted-off car settles to a stop
263
+ * in a game-reasonable distance rather than gliding for tens of seconds.
264
+ */
265
+ const ROLLING_RESISTANCE_COEFFICIENT = 0.03;
266
+ /**
267
+ * Engine-braking drag as a weight fraction (#1051): the lift-off force is `μ_eb · m · g` routed through
268
+ * the current gear (`ratio / top-gear ratio`, capped by {@link ENGINE_BRAKE_MAX_LEVERAGE}). Like rolling
269
+ * resistance it scales with the vehicle's own weight and gravity — not a per-car constant — so every car
270
+ * settles with a consistent, firm lift-off deceleration that grows as it downshifts toward a stop, while
271
+ * always staying well short of the service brakes.
272
+ */
273
+ const ENGINE_BRAKE_COEFFICIENT = 0.11;
274
+ /** Cap on low-gear engine-braking leverage so lifting off never bites as hard as the brake pedal. */
275
+ const ENGINE_BRAKE_MAX_LEVERAGE = 2.5;
276
+ function clampSigned(value, magnitude) {
277
+ return Math.max(-Math.abs(magnitude), Math.min(Math.abs(magnitude), value));
278
+ }
@@ -2,6 +2,12 @@ export interface PhysicsBounds {
2
2
  min: readonly [number, number, number];
3
3
  max: readonly [number, number, number];
4
4
  }
5
+ /**
6
+ * Simulation fidelity intent: `low` (cheap — many bodies, loose stacks, forgiving sleep), `standard`
7
+ * (default), `high` (tight stacks, accurate joints, worth the extra solver work). Sets the solver
8
+ * knobs below to a matched preset; an individual knob left explicit always wins over the preset.
9
+ */
10
+ export type PhysicsPrecision = "low" | "standard" | "high";
5
11
  export interface PhysicsWorldConfig {
6
12
  /** Maximum bodies the SoA buffers can hold. Fixed at construction; no reallocation later. */
7
13
  capacity: number;
@@ -9,8 +15,8 @@ export interface PhysicsWorldConfig {
9
15
  bounds: PhysicsBounds;
10
16
  /** Downward acceleration applied to awake bodies each substep. Default -20. */
11
17
  gravity?: number;
12
- /** Broadphase cell edge; tune to ≈ small-body diameter. Default 1. */
13
- cellSize?: number;
18
+ /** Simulation fidelity intent. Default "standard" — see {@link PhysicsPrecision}. */
19
+ precision?: PhysicsPrecision;
14
20
  /** Fixed substep length in seconds. Default 1/60. */
15
21
  fixedDt?: number;
16
22
  /** Cap on substeps per `step()` — bounds catch-up work, drops the rest. Default 4. */
@@ -23,21 +29,27 @@ export interface PhysicsWorldConfig {
23
29
  friction?: number;
24
30
  /** Per-second linear velocity damping (physical energy bleed so piles settle and sleep). Default 0.2. */
25
31
  linearDamping?: number;
26
- /** Sequential-impulse velocity iterations per substep (higher = more stable stacks). Default 4. */
32
+ /** Speed at or below which a body counts as still. Default 0.08. */
33
+ sleepLinearVelocity?: number;
34
+ /** Maximum simultaneous joints the constraint buffers can hold. Default 256. */
35
+ jointCapacity?: number;
36
+ /**
37
+ * @deprecated Advanced escape hatch — tune only when profiling shows the broadphase grid is the
38
+ * bottleneck; most games never set this. Broadphase cell edge; ideally ≈ small-body diameter.
39
+ * Default 1.
40
+ */
41
+ cellSize?: number;
42
+ /** @deprecated Advanced escape hatch — prefer `precision`. Sequential-impulse velocity iterations per substep (higher = more stable stacks). */
27
43
  solverIterations?: number;
28
- /** Baumgarte positional-correction fraction per substep, 0..1. Default 0.2. */
44
+ /** @deprecated Advanced escape hatch — prefer `precision`. Baumgarte positional-correction fraction per substep, 0..1. */
29
45
  correctionFactor?: number;
30
- /** Penetration tolerated before correction kicks in. Default 0.005. */
46
+ /** @deprecated Advanced escape hatch — prefer `precision`. Penetration tolerated before correction kicks in. Default 0.005. */
31
47
  slop?: number;
32
- /** Speed at or below which a body counts as still. Default 0.08. */
33
- sleepLinearVelocity?: number;
34
- /** Consecutive still substeps before a body sleeps. Default 30. */
48
+ /** @deprecated Advanced escape hatch — prefer `precision`. Consecutive still substeps before a body sleeps. */
35
49
  sleepThresholdSteps?: number;
36
- /** Approach speed a contact must exceed to wake a sleeping body (resting contacts don't). Default 0.5. */
50
+ /** @deprecated Advanced escape hatch — prefer `precision`. Approach speed a contact must exceed to wake a sleeping body (resting contacts don't). */
37
51
  wakeThreshold?: number;
38
- /** Maximum simultaneous joints the constraint buffers can hold. Default 256. */
39
- jointCapacity?: number;
40
- /** Baumgarte fraction applied to hard-joint positional error per iteration, 0..1. Default 0.5. */
52
+ /** @deprecated Advanced escape hatch — prefer `precision`. Baumgarte fraction applied to hard-joint positional error per iteration, 0..1. */
41
53
  jointCorrection?: number;
42
54
  }
43
55
  export interface PhysicsStats {
@@ -187,6 +199,7 @@ export declare class PhysicsWorld {
187
199
  private jFreeCount;
188
200
  private jointHigh;
189
201
  private jointActiveCount;
202
+ private readonly anchorScratch;
190
203
  private readonly bodyFree;
191
204
  private bodyFreeCount;
192
205
  private bodyHigh;
@@ -226,6 +239,13 @@ export declare class PhysicsWorld {
226
239
  /** Move a joint's local anchor offset on A (world axes, no rotation applied by the solver). */
227
240
  setJointAnchorA(id: number, x: number, y: number, z: number): void;
228
241
  setJointRest(id: number, restLength: number): void;
242
+ /**
243
+ * Gather joint `id`'s two world anchor points into {@link anchorScratch} as [ax,ay,az,bx,by,bz]
244
+ * (A's local offset added to body A's centre, or world-origin when A is unset; B likewise, treating
245
+ * `anchorB` as a world point when B is unset). The single definition shared by {@link jointDistance},
246
+ * {@link readJointSegments}, and {@link solveJoints}.
247
+ */
248
+ private anchorWorld;
229
249
  private jointDistance;
230
250
  /** Write [ax,ay,az,bx,by,bz] world endpoints per active joint into `out`; returns the joint count. */
231
251
  readJointSegments(out: Float32Array): number;
@@ -256,10 +276,28 @@ export declare class PhysicsWorld {
256
276
  getStats(): PhysicsStats;
257
277
  private substep;
258
278
  private constrainBounds;
279
+ /**
280
+ * Walk every broadphase cell body `i`'s AABB overlaps, invoking `visit(cell)` once per cell. The
281
+ * cell-range math (six `cellCoord` calls plus the row-major triple loop) lives here so the count
282
+ * and scatter passes of {@link buildGrid} share one definition. `visit` is a caller-hoisted closure
283
+ * (created once per `buildGrid`, not per body) so the hot loop stays allocation-free.
284
+ */
285
+ private forEachBodyCell;
259
286
  private buildGrid;
260
287
  private cellOf;
261
288
  private solve;
262
289
  private resolve;
290
+ /**
291
+ * Apply an axial velocity impulse `jn` along unit axis (nX,nY,nZ) to a joint's two bodies: body A
292
+ * recoils (−) and body B advances (+), each scaled by its inverse mass. A world anchor (body index
293
+ * < 0) is skipped. Scalar args only — no allocation on the joint hot path.
294
+ */
295
+ private applyAxialImpulse;
296
+ /**
297
+ * Positional (Baumgarte) twin of {@link applyAxialImpulse}: nudge the joint's two bodies along
298
+ * (nX,nY,nZ) by `corr` — body A advances (+), body B recoils (−), each scaled by its inverse mass.
299
+ */
300
+ private applyAxialCorrection;
263
301
  private solveJoints;
264
302
  private updateSleep;
265
303
  }