@alife-sdk/core 0.1.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 (367) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +283 -0
  3. package/dist/ai/DangerManager.d.ts +71 -0
  4. package/dist/ai/DangerManager.d.ts.map +1 -0
  5. package/dist/ai/DangerManager.js +176 -0
  6. package/dist/ai/DangerManager.js.map +1 -0
  7. package/dist/ai/GOAPAction.d.ts +45 -0
  8. package/dist/ai/GOAPAction.d.ts.map +1 -0
  9. package/dist/ai/GOAPAction.js +32 -0
  10. package/dist/ai/GOAPAction.js.map +1 -0
  11. package/dist/ai/GOAPPlanner.d.ts +80 -0
  12. package/dist/ai/GOAPPlanner.d.ts.map +1 -0
  13. package/dist/ai/GOAPPlanner.js +259 -0
  14. package/dist/ai/GOAPPlanner.js.map +1 -0
  15. package/dist/ai/IStateHandler.d.ts +8 -0
  16. package/dist/ai/IStateHandler.d.ts.map +1 -0
  17. package/dist/ai/IStateHandler.js +8 -0
  18. package/dist/ai/IStateHandler.js.map +1 -0
  19. package/dist/ai/MemorySystem.d.ts +94 -0
  20. package/dist/ai/MemorySystem.d.ts.map +1 -0
  21. package/dist/ai/MemorySystem.js +207 -0
  22. package/dist/ai/MemorySystem.js.map +1 -0
  23. package/dist/ai/StateMachine.d.ts +49 -0
  24. package/dist/ai/StateMachine.d.ts.map +1 -0
  25. package/dist/ai/StateMachine.js +83 -0
  26. package/dist/ai/StateMachine.js.map +1 -0
  27. package/dist/ai/WorldState.d.ts +48 -0
  28. package/dist/ai/WorldState.d.ts.map +1 -0
  29. package/dist/ai/WorldState.js +93 -0
  30. package/dist/ai/WorldState.js.map +1 -0
  31. package/dist/ai/index.d.ts +10 -0
  32. package/dist/ai/index.d.ts.map +1 -0
  33. package/dist/ai/index.js +8 -0
  34. package/dist/ai/index.js.map +1 -0
  35. package/dist/combat/DamageInstance.d.ts +26 -0
  36. package/dist/combat/DamageInstance.d.ts.map +1 -0
  37. package/dist/combat/DamageInstance.js +25 -0
  38. package/dist/combat/DamageInstance.js.map +1 -0
  39. package/dist/combat/MoraleStateMachine.d.ts +53 -0
  40. package/dist/combat/MoraleStateMachine.d.ts.map +1 -0
  41. package/dist/combat/MoraleStateMachine.js +84 -0
  42. package/dist/combat/MoraleStateMachine.js.map +1 -0
  43. package/dist/combat/index.d.ts +5 -0
  44. package/dist/combat/index.d.ts.map +1 -0
  45. package/dist/combat/index.js +3 -0
  46. package/dist/combat/index.js.map +1 -0
  47. package/dist/config/ALifeConfig.d.ts +131 -0
  48. package/dist/config/ALifeConfig.d.ts.map +1 -0
  49. package/dist/config/ALifeConfig.js +82 -0
  50. package/dist/config/ALifeConfig.js.map +1 -0
  51. package/dist/config/index.d.ts +3 -0
  52. package/dist/config/index.d.ts.map +1 -0
  53. package/dist/config/index.js +2 -0
  54. package/dist/config/index.js.map +1 -0
  55. package/dist/core/ALifeKernel.d.ts +163 -0
  56. package/dist/core/ALifeKernel.d.ts.map +1 -0
  57. package/dist/core/ALifeKernel.js +542 -0
  58. package/dist/core/ALifeKernel.js.map +1 -0
  59. package/dist/core/Clock.d.ts +123 -0
  60. package/dist/core/Clock.d.ts.map +1 -0
  61. package/dist/core/Clock.js +228 -0
  62. package/dist/core/Clock.js.map +1 -0
  63. package/dist/core/DevToolsInspector.d.ts +53 -0
  64. package/dist/core/DevToolsInspector.d.ts.map +1 -0
  65. package/dist/core/DevToolsInspector.js +8 -0
  66. package/dist/core/DevToolsInspector.js.map +1 -0
  67. package/dist/core/Diagnostics.d.ts +64 -0
  68. package/dist/core/Diagnostics.d.ts.map +1 -0
  69. package/dist/core/Diagnostics.js +107 -0
  70. package/dist/core/Diagnostics.js.map +1 -0
  71. package/dist/core/ISerializable.d.ts +12 -0
  72. package/dist/core/ISerializable.d.ts.map +1 -0
  73. package/dist/core/ISerializable.js +2 -0
  74. package/dist/core/ISerializable.js.map +1 -0
  75. package/dist/core/PortRegistry.d.ts +57 -0
  76. package/dist/core/PortRegistry.d.ts.map +1 -0
  77. package/dist/core/PortRegistry.js +72 -0
  78. package/dist/core/PortRegistry.js.map +1 -0
  79. package/dist/core/PortTokens.d.ts +39 -0
  80. package/dist/core/PortTokens.d.ts.map +1 -0
  81. package/dist/core/PortTokens.js +39 -0
  82. package/dist/core/PortTokens.js.map +1 -0
  83. package/dist/core/SpatialGrid.d.ts +114 -0
  84. package/dist/core/SpatialGrid.d.ts.map +1 -0
  85. package/dist/core/SpatialGrid.js +258 -0
  86. package/dist/core/SpatialGrid.js.map +1 -0
  87. package/dist/core/Vec2.d.ts +34 -0
  88. package/dist/core/Vec2.d.ts.map +1 -0
  89. package/dist/core/Vec2.js +52 -0
  90. package/dist/core/Vec2.js.map +1 -0
  91. package/dist/core/math/CatmullRom.d.ts +20 -0
  92. package/dist/core/math/CatmullRom.d.ts.map +1 -0
  93. package/dist/core/math/CatmullRom.js +37 -0
  94. package/dist/core/math/CatmullRom.js.map +1 -0
  95. package/dist/core/math/index.d.ts +6 -0
  96. package/dist/core/math/index.d.ts.map +1 -0
  97. package/dist/core/math/index.js +5 -0
  98. package/dist/core/math/index.js.map +1 -0
  99. package/dist/core/math/intersects.d.ts +32 -0
  100. package/dist/core/math/intersects.d.ts.map +1 -0
  101. package/dist/core/math/intersects.js +92 -0
  102. package/dist/core/math/intersects.js.map +1 -0
  103. package/dist/core/math/utils.d.ts +5 -0
  104. package/dist/core/math/utils.d.ts.map +1 -0
  105. package/dist/core/math/utils.js +13 -0
  106. package/dist/core/math/utils.js.map +1 -0
  107. package/dist/entity/IComponent.d.ts +17 -0
  108. package/dist/entity/IComponent.d.ts.map +1 -0
  109. package/dist/entity/IComponent.js +2 -0
  110. package/dist/entity/IComponent.js.map +1 -0
  111. package/dist/entity/IEntity.d.ts +33 -0
  112. package/dist/entity/IEntity.d.ts.map +1 -0
  113. package/dist/entity/IEntity.js +2 -0
  114. package/dist/entity/IEntity.js.map +1 -0
  115. package/dist/entity/index.d.ts +3 -0
  116. package/dist/entity/index.d.ts.map +1 -0
  117. package/dist/entity/index.js +2 -0
  118. package/dist/entity/index.js.map +1 -0
  119. package/dist/events/ALifeEvents.d.ts +241 -0
  120. package/dist/events/ALifeEvents.d.ts.map +1 -0
  121. package/dist/events/ALifeEvents.js +53 -0
  122. package/dist/events/ALifeEvents.js.map +1 -0
  123. package/dist/events/EventBus.d.ts +52 -0
  124. package/dist/events/EventBus.d.ts.map +1 -0
  125. package/dist/events/EventBus.js +129 -0
  126. package/dist/events/EventBus.js.map +1 -0
  127. package/dist/events/index.d.ts +4 -0
  128. package/dist/events/index.d.ts.map +1 -0
  129. package/dist/events/index.js +4 -0
  130. package/dist/events/index.js.map +1 -0
  131. package/dist/faction/Faction.d.ts +53 -0
  132. package/dist/faction/Faction.d.ts.map +1 -0
  133. package/dist/faction/Faction.js +101 -0
  134. package/dist/faction/Faction.js.map +1 -0
  135. package/dist/faction/FactionBuilder.d.ts +32 -0
  136. package/dist/faction/FactionBuilder.d.ts.map +1 -0
  137. package/dist/faction/FactionBuilder.js +80 -0
  138. package/dist/faction/FactionBuilder.js.map +1 -0
  139. package/dist/faction/ImmunityProfile.d.ts +24 -0
  140. package/dist/faction/ImmunityProfile.d.ts.map +1 -0
  141. package/dist/faction/ImmunityProfile.js +43 -0
  142. package/dist/faction/ImmunityProfile.js.map +1 -0
  143. package/dist/faction/index.d.ts +6 -0
  144. package/dist/faction/index.d.ts.map +1 -0
  145. package/dist/faction/index.js +5 -0
  146. package/dist/faction/index.js.map +1 -0
  147. package/dist/index.d.ts +32 -0
  148. package/dist/index.d.ts.map +1 -0
  149. package/dist/index.js +34 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/logger/ILogEntry.d.ts +16 -0
  152. package/dist/logger/ILogEntry.d.ts.map +1 -0
  153. package/dist/logger/ILogEntry.js +2 -0
  154. package/dist/logger/ILogEntry.js.map +1 -0
  155. package/dist/logger/LogChannel.d.ts +27 -0
  156. package/dist/logger/LogChannel.d.ts.map +1 -0
  157. package/dist/logger/LogChannel.js +26 -0
  158. package/dist/logger/LogChannel.js.map +1 -0
  159. package/dist/logger/LogLevel.d.ts +10 -0
  160. package/dist/logger/LogLevel.d.ts.map +1 -0
  161. package/dist/logger/LogLevel.js +9 -0
  162. package/dist/logger/LogLevel.js.map +1 -0
  163. package/dist/logger/Logger.d.ts +56 -0
  164. package/dist/logger/Logger.d.ts.map +1 -0
  165. package/dist/logger/Logger.js +106 -0
  166. package/dist/logger/Logger.js.map +1 -0
  167. package/dist/logger/index.d.ts +8 -0
  168. package/dist/logger/index.d.ts.map +1 -0
  169. package/dist/logger/index.js +5 -0
  170. package/dist/logger/index.js.map +1 -0
  171. package/dist/movement/MonsterHome.d.ts +49 -0
  172. package/dist/movement/MonsterHome.d.ts.map +1 -0
  173. package/dist/movement/MonsterHome.js +75 -0
  174. package/dist/movement/MonsterHome.js.map +1 -0
  175. package/dist/movement/PatrolRoute.d.ts +99 -0
  176. package/dist/movement/PatrolRoute.d.ts.map +1 -0
  177. package/dist/movement/PatrolRoute.js +141 -0
  178. package/dist/movement/PatrolRoute.js.map +1 -0
  179. package/dist/movement/index.d.ts +5 -0
  180. package/dist/movement/index.d.ts.map +1 -0
  181. package/dist/movement/index.js +4 -0
  182. package/dist/movement/index.js.map +1 -0
  183. package/dist/navigation/LevelGraph.d.ts +78 -0
  184. package/dist/navigation/LevelGraph.d.ts.map +1 -0
  185. package/dist/navigation/LevelGraph.js +268 -0
  186. package/dist/navigation/LevelGraph.js.map +1 -0
  187. package/dist/navigation/NPCGraphMover.d.ts +87 -0
  188. package/dist/navigation/NPCGraphMover.d.ts.map +1 -0
  189. package/dist/navigation/NPCGraphMover.js +193 -0
  190. package/dist/navigation/NPCGraphMover.js.map +1 -0
  191. package/dist/navigation/index.d.ts +5 -0
  192. package/dist/navigation/index.d.ts.map +1 -0
  193. package/dist/navigation/index.js +4 -0
  194. package/dist/navigation/index.js.map +1 -0
  195. package/dist/plugins/AnomaliesPlugin.d.ts +26 -0
  196. package/dist/plugins/AnomaliesPlugin.d.ts.map +1 -0
  197. package/dist/plugins/AnomaliesPlugin.js +30 -0
  198. package/dist/plugins/AnomaliesPlugin.js.map +1 -0
  199. package/dist/plugins/CombatSchemaPlugin.d.ts +35 -0
  200. package/dist/plugins/CombatSchemaPlugin.d.ts.map +1 -0
  201. package/dist/plugins/CombatSchemaPlugin.js +44 -0
  202. package/dist/plugins/CombatSchemaPlugin.js.map +1 -0
  203. package/dist/plugins/FactionsPlugin.d.ts +26 -0
  204. package/dist/plugins/FactionsPlugin.d.ts.map +1 -0
  205. package/dist/plugins/FactionsPlugin.js +30 -0
  206. package/dist/plugins/FactionsPlugin.js.map +1 -0
  207. package/dist/plugins/IALifePlugin.d.ts +91 -0
  208. package/dist/plugins/IALifePlugin.d.ts.map +1 -0
  209. package/dist/plugins/IALifePlugin.js +2 -0
  210. package/dist/plugins/IALifePlugin.js.map +1 -0
  211. package/dist/plugins/MonstersPlugin.d.ts +26 -0
  212. package/dist/plugins/MonstersPlugin.d.ts.map +1 -0
  213. package/dist/plugins/MonstersPlugin.js +30 -0
  214. package/dist/plugins/MonstersPlugin.js.map +1 -0
  215. package/dist/plugins/NPCTypesPlugin.d.ts +26 -0
  216. package/dist/plugins/NPCTypesPlugin.d.ts.map +1 -0
  217. package/dist/plugins/NPCTypesPlugin.js +30 -0
  218. package/dist/plugins/NPCTypesPlugin.js.map +1 -0
  219. package/dist/plugins/PluginToken.d.ts +26 -0
  220. package/dist/plugins/PluginToken.d.ts.map +1 -0
  221. package/dist/plugins/PluginToken.js +22 -0
  222. package/dist/plugins/PluginToken.js.map +1 -0
  223. package/dist/plugins/SocialPlugin.d.ts +14 -0
  224. package/dist/plugins/SocialPlugin.d.ts.map +1 -0
  225. package/dist/plugins/SocialPlugin.js +16 -0
  226. package/dist/plugins/SocialPlugin.js.map +1 -0
  227. package/dist/plugins/SpawnPlugin.d.ts +15 -0
  228. package/dist/plugins/SpawnPlugin.d.ts.map +1 -0
  229. package/dist/plugins/SpawnPlugin.js +26 -0
  230. package/dist/plugins/SpawnPlugin.js.map +1 -0
  231. package/dist/plugins/SquadPlugin.d.ts +14 -0
  232. package/dist/plugins/SquadPlugin.d.ts.map +1 -0
  233. package/dist/plugins/SquadPlugin.js +16 -0
  234. package/dist/plugins/SquadPlugin.js.map +1 -0
  235. package/dist/plugins/SurgePlugin.d.ts +20 -0
  236. package/dist/plugins/SurgePlugin.d.ts.map +1 -0
  237. package/dist/plugins/SurgePlugin.js +22 -0
  238. package/dist/plugins/SurgePlugin.js.map +1 -0
  239. package/dist/plugins/TradePlugin.d.ts +16 -0
  240. package/dist/plugins/TradePlugin.d.ts.map +1 -0
  241. package/dist/plugins/TradePlugin.js +18 -0
  242. package/dist/plugins/TradePlugin.js.map +1 -0
  243. package/dist/plugins/index.d.ts +11 -0
  244. package/dist/plugins/index.d.ts.map +1 -0
  245. package/dist/plugins/index.js +10 -0
  246. package/dist/plugins/index.js.map +1 -0
  247. package/dist/plugins/pluginNames.d.ts +37 -0
  248. package/dist/plugins/pluginNames.d.ts.map +1 -0
  249. package/dist/plugins/pluginNames.js +28 -0
  250. package/dist/plugins/pluginNames.js.map +1 -0
  251. package/dist/plugins/presets.d.ts +31 -0
  252. package/dist/plugins/presets.d.ts.map +1 -0
  253. package/dist/plugins/presets.js +50 -0
  254. package/dist/plugins/presets.js.map +1 -0
  255. package/dist/ports/IDataLoader.d.ts +38 -0
  256. package/dist/ports/IDataLoader.d.ts.map +1 -0
  257. package/dist/ports/IDataLoader.js +12 -0
  258. package/dist/ports/IDataLoader.js.map +1 -0
  259. package/dist/ports/IEntityAdapter.d.ts +73 -0
  260. package/dist/ports/IEntityAdapter.d.ts.map +1 -0
  261. package/dist/ports/IEntityAdapter.js +36 -0
  262. package/dist/ports/IEntityAdapter.js.map +1 -0
  263. package/dist/ports/IEntityFactory.d.ts +66 -0
  264. package/dist/ports/IEntityFactory.d.ts.map +1 -0
  265. package/dist/ports/IEntityFactory.js +21 -0
  266. package/dist/ports/IEntityFactory.js.map +1 -0
  267. package/dist/ports/ILogger.d.ts +29 -0
  268. package/dist/ports/ILogger.d.ts.map +1 -0
  269. package/dist/ports/ILogger.js +2 -0
  270. package/dist/ports/ILogger.js.map +1 -0
  271. package/dist/ports/IPlayerPositionProvider.d.ts +20 -0
  272. package/dist/ports/IPlayerPositionProvider.d.ts.map +1 -0
  273. package/dist/ports/IPlayerPositionProvider.js +11 -0
  274. package/dist/ports/IPlayerPositionProvider.js.map +1 -0
  275. package/dist/ports/IRandom.d.ts +25 -0
  276. package/dist/ports/IRandom.d.ts.map +1 -0
  277. package/dist/ports/IRandom.js +39 -0
  278. package/dist/ports/IRandom.js.map +1 -0
  279. package/dist/ports/IRuntimeClock.d.ts +18 -0
  280. package/dist/ports/IRuntimeClock.d.ts.map +1 -0
  281. package/dist/ports/IRuntimeClock.js +2 -0
  282. package/dist/ports/IRuntimeClock.js.map +1 -0
  283. package/dist/ports/index.d.ts +12 -0
  284. package/dist/ports/index.d.ts.map +1 -0
  285. package/dist/ports/index.js +5 -0
  286. package/dist/ports/index.js.map +1 -0
  287. package/dist/registry/AIStateRegistry.d.ts +42 -0
  288. package/dist/registry/AIStateRegistry.d.ts.map +1 -0
  289. package/dist/registry/AIStateRegistry.js +27 -0
  290. package/dist/registry/AIStateRegistry.js.map +1 -0
  291. package/dist/registry/AnomalyTypeRegistry.d.ts +21 -0
  292. package/dist/registry/AnomalyTypeRegistry.d.ts.map +1 -0
  293. package/dist/registry/AnomalyTypeRegistry.js +20 -0
  294. package/dist/registry/AnomalyTypeRegistry.js.map +1 -0
  295. package/dist/registry/BehaviorSchemeRegistry.d.ts +21 -0
  296. package/dist/registry/BehaviorSchemeRegistry.d.ts.map +1 -0
  297. package/dist/registry/BehaviorSchemeRegistry.js +24 -0
  298. package/dist/registry/BehaviorSchemeRegistry.js.map +1 -0
  299. package/dist/registry/DamageTypeRegistry.d.ts +17 -0
  300. package/dist/registry/DamageTypeRegistry.d.ts.map +1 -0
  301. package/dist/registry/DamageTypeRegistry.js +24 -0
  302. package/dist/registry/DamageTypeRegistry.js.map +1 -0
  303. package/dist/registry/FactionRegistry.d.ts +41 -0
  304. package/dist/registry/FactionRegistry.d.ts.map +1 -0
  305. package/dist/registry/FactionRegistry.js +29 -0
  306. package/dist/registry/FactionRegistry.js.map +1 -0
  307. package/dist/registry/MonsterRegistry.d.ts +44 -0
  308. package/dist/registry/MonsterRegistry.d.ts.map +1 -0
  309. package/dist/registry/MonsterRegistry.js +43 -0
  310. package/dist/registry/MonsterRegistry.js.map +1 -0
  311. package/dist/registry/NPCTypeRegistry.d.ts +34 -0
  312. package/dist/registry/NPCTypeRegistry.d.ts.map +1 -0
  313. package/dist/registry/NPCTypeRegistry.js +20 -0
  314. package/dist/registry/NPCTypeRegistry.js.map +1 -0
  315. package/dist/registry/Registry.d.ts +44 -0
  316. package/dist/registry/Registry.d.ts.map +1 -0
  317. package/dist/registry/Registry.js +80 -0
  318. package/dist/registry/Registry.js.map +1 -0
  319. package/dist/registry/TaskTypeRegistry.d.ts +17 -0
  320. package/dist/registry/TaskTypeRegistry.d.ts.map +1 -0
  321. package/dist/registry/TaskTypeRegistry.js +16 -0
  322. package/dist/registry/TaskTypeRegistry.js.map +1 -0
  323. package/dist/registry/index.d.ts +19 -0
  324. package/dist/registry/index.d.ts.map +1 -0
  325. package/dist/registry/index.js +11 -0
  326. package/dist/registry/index.js.map +1 -0
  327. package/dist/schema/index.d.ts +3 -0
  328. package/dist/schema/index.d.ts.map +1 -0
  329. package/dist/schema/index.js +3 -0
  330. package/dist/schema/index.js.map +1 -0
  331. package/dist/schema/validators.d.ts +32 -0
  332. package/dist/schema/validators.d.ts.map +1 -0
  333. package/dist/schema/validators.js +249 -0
  334. package/dist/schema/validators.js.map +1 -0
  335. package/dist/spawn/SpawnRegistry.d.ts +48 -0
  336. package/dist/spawn/SpawnRegistry.d.ts.map +1 -0
  337. package/dist/spawn/SpawnRegistry.js +141 -0
  338. package/dist/spawn/SpawnRegistry.js.map +1 -0
  339. package/dist/spawn/index.d.ts +3 -0
  340. package/dist/spawn/index.d.ts.map +1 -0
  341. package/dist/spawn/index.js +3 -0
  342. package/dist/spawn/index.js.map +1 -0
  343. package/dist/terrain/SmartTerrain.d.ts +119 -0
  344. package/dist/terrain/SmartTerrain.d.ts.map +1 -0
  345. package/dist/terrain/SmartTerrain.js +124 -0
  346. package/dist/terrain/SmartTerrain.js.map +1 -0
  347. package/dist/terrain/TerrainBuilder.d.ts +44 -0
  348. package/dist/terrain/TerrainBuilder.d.ts.map +1 -0
  349. package/dist/terrain/TerrainBuilder.js +112 -0
  350. package/dist/terrain/TerrainBuilder.js.map +1 -0
  351. package/dist/terrain/Zone.d.ts +25 -0
  352. package/dist/terrain/Zone.d.ts.map +1 -0
  353. package/dist/terrain/Zone.js +29 -0
  354. package/dist/terrain/Zone.js.map +1 -0
  355. package/dist/terrain/index.d.ts +6 -0
  356. package/dist/terrain/index.d.ts.map +1 -0
  357. package/dist/terrain/index.js +5 -0
  358. package/dist/terrain/index.js.map +1 -0
  359. package/dist/time/TimeManager.d.ts +21 -0
  360. package/dist/time/TimeManager.d.ts.map +1 -0
  361. package/dist/time/TimeManager.js +41 -0
  362. package/dist/time/TimeManager.js.map +1 -0
  363. package/dist/time/index.d.ts +3 -0
  364. package/dist/time/index.d.ts.map +1 -0
  365. package/dist/time/index.js +2 -0
  366. package/dist/time/index.js.map +1 -0
  367. package/package.json +119 -0
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Multi-channel memory bank with confidence decay.
3
+ *
4
+ * MemoryBank provides per-NPC episodic memory storage. Memories are
5
+ * categorised by channel (visual, sound, hit, danger) and decay over time.
6
+ * Records below the minimum confidence threshold are pruned automatically
7
+ * during update().
8
+ *
9
+ * Storage layout: Map keyed by sourceId for O(1) read/write per entry.
10
+ * A single entity may have at most one record per sourceId; newer
11
+ * observations overwrite older ones.
12
+ */
13
+ // ---------------------------------------------------------------------------
14
+ // Memory channel
15
+ // ---------------------------------------------------------------------------
16
+ export const MemoryChannel = {
17
+ VISUAL: 'visual',
18
+ SOUND: 'sound',
19
+ HIT: 'hit',
20
+ DANGER: 'danger',
21
+ };
22
+ // ---------------------------------------------------------------------------
23
+ // Constants
24
+ // ---------------------------------------------------------------------------
25
+ const DEFAULT_MAX_RECORDS = 32;
26
+ const DEFAULT_DECAY_RATE = 0.1; // confidence per second
27
+ const DEFAULT_MIN_CONFIDENCE = 0.05;
28
+ // ---------------------------------------------------------------------------
29
+ // MemoryBank
30
+ // ---------------------------------------------------------------------------
31
+ export class MemoryBank {
32
+ constructor(config) {
33
+ this.records = new Map();
34
+ this.byChannel = new Map();
35
+ this._toDelete = [];
36
+ this.timeFn = config.timeFn;
37
+ this.maxRecords = config.maxRecords ?? DEFAULT_MAX_RECORDS;
38
+ this.decayRate = config.decayRate ?? DEFAULT_DECAY_RATE;
39
+ this.minConfidence = config.minConfidence ?? DEFAULT_MIN_CONFIDENCE;
40
+ this.channelDecayRates = config.channelDecayRates;
41
+ }
42
+ // -----------------------------------------------------------------------
43
+ // Mutation
44
+ // -----------------------------------------------------------------------
45
+ /**
46
+ * Add or update a memory record.
47
+ *
48
+ * If a record for this sourceId already exists, its position and timestamp
49
+ * are updated and confidence is reset to the provided value (default 1.0).
50
+ * If the bank is at capacity, the lowest-confidence record is evicted.
51
+ */
52
+ remember(input) {
53
+ const { sourceId, channel, position, confidence = 1.0 } = input;
54
+ const existing = this.records.get(sourceId);
55
+ if (existing) {
56
+ // If channel changed, migrate between index sets.
57
+ if (existing.channel !== channel) {
58
+ this.removeFromChannelIndex(existing);
59
+ existing.channel = channel;
60
+ this.addToChannelIndex(existing);
61
+ }
62
+ existing.position = position;
63
+ existing.confidence = Math.max(0, Math.min(1, confidence));
64
+ existing.timestamp = this.timeFn();
65
+ return;
66
+ }
67
+ if (this.records.size >= this.maxRecords) {
68
+ this.evictLowestConfidence();
69
+ }
70
+ const record = {
71
+ sourceId,
72
+ channel,
73
+ position,
74
+ confidence: Math.max(0, Math.min(1, confidence)),
75
+ timestamp: this.timeFn(),
76
+ };
77
+ this.records.set(sourceId, record);
78
+ this.addToChannelIndex(record);
79
+ }
80
+ // -----------------------------------------------------------------------
81
+ // Queries
82
+ // -----------------------------------------------------------------------
83
+ /** Get memory of a specific source. */
84
+ recall(sourceId) {
85
+ return this.records.get(sourceId);
86
+ }
87
+ /** Get all records on a specific channel. */
88
+ getByChannel(channel) {
89
+ const set = this.byChannel.get(channel);
90
+ if (!set || set.size === 0)
91
+ return [];
92
+ return Array.from(set);
93
+ }
94
+ /** Get the highest-confidence record, or undefined if the bank is empty. */
95
+ getMostConfident() {
96
+ let best;
97
+ for (const record of this.records.values()) {
98
+ if (!best || record.confidence > best.confidence) {
99
+ best = record;
100
+ }
101
+ }
102
+ return best;
103
+ }
104
+ // -----------------------------------------------------------------------
105
+ // Decay and housekeeping
106
+ // -----------------------------------------------------------------------
107
+ /**
108
+ * Decay all records and remove those below the minimum confidence threshold.
109
+ *
110
+ * @param deltaSec - Seconds elapsed since the last update.
111
+ * @param minConfidence - Records below this threshold are pruned.
112
+ */
113
+ update(deltaSec) {
114
+ this._toDelete.length = 0;
115
+ for (const [id, record] of this.records) {
116
+ const rate = this.channelDecayRates?.[record.channel] ?? this.decayRate;
117
+ const decay = rate * deltaSec;
118
+ record.confidence = Math.max(0, record.confidence - decay);
119
+ if (record.confidence < this.minConfidence) {
120
+ this._toDelete.push(id);
121
+ }
122
+ }
123
+ for (let i = 0; i < this._toDelete.length; i++) {
124
+ const id = this._toDelete[i];
125
+ const record = this.records.get(id);
126
+ if (record) {
127
+ this.removeFromChannelIndex(record);
128
+ this.records.delete(id);
129
+ }
130
+ }
131
+ }
132
+ /** Forget a specific source. */
133
+ forget(sourceId) {
134
+ const record = this.records.get(sourceId);
135
+ if (record) {
136
+ this.removeFromChannelIndex(record);
137
+ this.records.delete(sourceId);
138
+ }
139
+ }
140
+ /** Clear all memories. */
141
+ clear() {
142
+ this.records.clear();
143
+ this.byChannel.clear();
144
+ }
145
+ get size() {
146
+ return this.records.size;
147
+ }
148
+ // -----------------------------------------------------------------------
149
+ // Serialisation
150
+ // -----------------------------------------------------------------------
151
+ serialize() {
152
+ return [...this.records.values()].map((r) => ({
153
+ sourceId: r.sourceId,
154
+ channel: r.channel,
155
+ position: r.position,
156
+ confidence: r.confidence,
157
+ timestamp: r.timestamp,
158
+ }));
159
+ }
160
+ restore(records) {
161
+ this.records.clear();
162
+ this.byChannel.clear();
163
+ for (const r of records) {
164
+ const mutable = { ...r };
165
+ this.records.set(r.sourceId, mutable);
166
+ this.addToChannelIndex(mutable);
167
+ }
168
+ }
169
+ // -----------------------------------------------------------------------
170
+ // Private
171
+ // -----------------------------------------------------------------------
172
+ /** Evict the record with the lowest confidence to make room. */
173
+ evictLowestConfidence() {
174
+ let lowestId;
175
+ let lowestConfidence = Infinity;
176
+ for (const [id, record] of this.records) {
177
+ if (record.confidence < lowestConfidence) {
178
+ lowestConfidence = record.confidence;
179
+ lowestId = id;
180
+ }
181
+ }
182
+ if (lowestId !== undefined) {
183
+ const record = this.records.get(lowestId);
184
+ if (record) {
185
+ this.removeFromChannelIndex(record);
186
+ }
187
+ this.records.delete(lowestId);
188
+ }
189
+ }
190
+ /** Add a record to the byChannel secondary index. */
191
+ addToChannelIndex(record) {
192
+ let set = this.byChannel.get(record.channel);
193
+ if (!set) {
194
+ set = new Set();
195
+ this.byChannel.set(record.channel, set);
196
+ }
197
+ set.add(record);
198
+ }
199
+ /** Remove a record from the byChannel secondary index. */
200
+ removeFromChannelIndex(record) {
201
+ const set = this.byChannel.get(record.channel);
202
+ if (set) {
203
+ set.delete(record);
204
+ }
205
+ }
206
+ }
207
+ //# sourceMappingURL=MemorySystem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemorySystem.js","sourceRoot":"","sources":["../../src/ai/MemorySystem.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Generic finite state machine that works with the AIStateRegistry plugin system.
3
+ *
4
+ * The FSM delegates state behaviour to IStateHandler instances registered
5
+ * in the AIStateRegistry. Each update tick runs the current handler's
6
+ * update() method and then evaluates auto-transition conditions.
7
+ *
8
+ * Lifecycle per state:
9
+ * 1. enter() -- called once when transitioning into the state
10
+ * 2. update() -- called every tick while the state is active
11
+ * 3. exit() -- called once when transitioning out of the state
12
+ */
13
+ import type { IEntity } from '../entity/IEntity';
14
+ import type { AIStateRegistry } from '../registry/AIStateRegistry';
15
+ export type TransitionResult = {
16
+ readonly success: true;
17
+ } | {
18
+ readonly success: false;
19
+ readonly reason: 'not_allowed' | 'exit_guard' | 'enter_guard';
20
+ };
21
+ export declare class StateMachine {
22
+ private currentStateId;
23
+ private readonly registry;
24
+ private readonly entity;
25
+ constructor(entity: IEntity, registry: AIStateRegistry, initialState: string);
26
+ /** Current active state identifier. */
27
+ get state(): string;
28
+ /**
29
+ * Force transition to a new state.
30
+ *
31
+ * Calls exit() on the current state handler, then enter() on the new one.
32
+ * If the target state is the same as the current state, the transition
33
+ * is still performed (exit + enter) to allow state reset semantics.
34
+ */
35
+ transition(newState: string): TransitionResult;
36
+ /**
37
+ * Run one tick of the FSM.
38
+ *
39
+ * First, the current handler's update() is called. Then the registry's
40
+ * auto-transition conditions are evaluated. If any condition fires,
41
+ * the FSM transitions to the target state automatically.
42
+ *
43
+ * @param delta - Seconds elapsed since the last update.
44
+ */
45
+ update(delta: number): void;
46
+ /** Exit the current state. Call when the entity is destroyed. */
47
+ destroy(): void;
48
+ }
49
+ //# sourceMappingURL=StateMachine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StateMachine.d.ts","sourceRoot":"","sources":["../../src/ai/StateMachine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,YAAY,GAAG,aAAa,CAAA;CAAE,CAAC;AAE/F,qBAAa,YAAY;IACvB,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;gBAErB,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM;IAa5E,uCAAuC;IACvC,IAAI,KAAK,IAAI,MAAM,CAElB;IAMD;;;;;;OAMG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB;IAsB9C;;;;;;;;OAQG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAkB3B,iEAAiE;IACjE,OAAO,IAAI,IAAI;CAIhB"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Generic finite state machine that works with the AIStateRegistry plugin system.
3
+ *
4
+ * The FSM delegates state behaviour to IStateHandler instances registered
5
+ * in the AIStateRegistry. Each update tick runs the current handler's
6
+ * update() method and then evaluates auto-transition conditions.
7
+ *
8
+ * Lifecycle per state:
9
+ * 1. enter() -- called once when transitioning into the state
10
+ * 2. update() -- called every tick while the state is active
11
+ * 3. exit() -- called once when transitioning out of the state
12
+ */
13
+ export class StateMachine {
14
+ constructor(entity, registry, initialState) {
15
+ this.entity = entity;
16
+ this.registry = registry;
17
+ this.currentStateId = initialState;
18
+ const definition = this.registry.get(this.currentStateId);
19
+ definition.handler.enter(this.entity);
20
+ }
21
+ // -----------------------------------------------------------------------
22
+ // Accessors
23
+ // -----------------------------------------------------------------------
24
+ /** Current active state identifier. */
25
+ get state() {
26
+ return this.currentStateId;
27
+ }
28
+ // -----------------------------------------------------------------------
29
+ // Transitions
30
+ // -----------------------------------------------------------------------
31
+ /**
32
+ * Force transition to a new state.
33
+ *
34
+ * Calls exit() on the current state handler, then enter() on the new one.
35
+ * If the target state is the same as the current state, the transition
36
+ * is still performed (exit + enter) to allow state reset semantics.
37
+ */
38
+ transition(newState) {
39
+ const oldDefinition = this.registry.get(this.currentStateId);
40
+ const newDefinition = this.registry.get(newState);
41
+ // Whitelist check: if allowedTransitions is set, only listed targets are permitted.
42
+ if (oldDefinition.allowedTransitions && !oldDefinition.allowedTransitions.includes(newState)) {
43
+ return { success: false, reason: 'not_allowed' };
44
+ }
45
+ if (oldDefinition.canExit?.(this.entity, newState) === false)
46
+ return { success: false, reason: 'exit_guard' };
47
+ if (newDefinition.canEnter?.(this.entity, this.currentStateId) === false)
48
+ return { success: false, reason: 'enter_guard' };
49
+ oldDefinition.handler.exit(this.entity);
50
+ this.currentStateId = newState;
51
+ newDefinition.handler.enter(this.entity);
52
+ return { success: true };
53
+ }
54
+ // -----------------------------------------------------------------------
55
+ // Update
56
+ // -----------------------------------------------------------------------
57
+ /**
58
+ * Run one tick of the FSM.
59
+ *
60
+ * First, the current handler's update() is called. Then the registry's
61
+ * auto-transition conditions are evaluated. If any condition fires,
62
+ * the FSM transitions to the target state automatically.
63
+ *
64
+ * @param delta - Seconds elapsed since the last update.
65
+ */
66
+ update(delta) {
67
+ const definition = this.registry.get(this.currentStateId);
68
+ definition.handler.update(this.entity, delta);
69
+ const nextState = this.registry.evaluateTransitions(this.currentStateId, this.entity);
70
+ if (nextState !== null) {
71
+ this.transition(nextState);
72
+ }
73
+ }
74
+ // -----------------------------------------------------------------------
75
+ // Cleanup
76
+ // -----------------------------------------------------------------------
77
+ /** Exit the current state. Call when the entity is destroyed. */
78
+ destroy() {
79
+ const definition = this.registry.get(this.currentStateId);
80
+ definition.handler.exit(this.entity);
81
+ }
82
+ }
83
+ //# sourceMappingURL=StateMachine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StateMachine.js","sourceRoot":"","sources":["../../src/ai/StateMachine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,MAAM,OAAO,YAAY;IAKvB,YAAY,MAAe,EAAE,QAAyB,EAAE,YAAoB;QAC1E,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,YAAY,CAAC;QAEnC,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1D,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,0EAA0E;IAC1E,YAAY;IACZ,0EAA0E;IAE1E,uCAAuC;IACvC,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,0EAA0E;IAC1E,cAAc;IACd,0EAA0E;IAE1E;;;;;;OAMG;IACH,UAAU,CAAC,QAAgB;QACzB,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC7D,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAElD,oFAAoF;QACpF,IAAI,aAAa,CAAC,kBAAkB,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7F,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;QACnD,CAAC;QAED,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,KAAK;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;QAC9G,IAAI,aAAa,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,KAAK;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;QAE3H,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC;QAC/B,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,0EAA0E;IAC1E,SAAS;IACT,0EAA0E;IAE1E;;;;;;;;OAQG;IACH,MAAM,CAAC,KAAa;QAClB,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1D,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAE9C,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CACjD,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,MAAM,CACZ,CAAC;QAEF,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,UAAU;IACV,0EAA0E;IAE1E,iEAAiE;IACjE,OAAO;QACL,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1D,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * GOAP world state -- a key-value map of planning properties.
3
+ *
4
+ * Used both as the "current world state" fed to the planner and as
5
+ * goal/precondition/effect descriptors on GOAPActions.
6
+ *
7
+ * Only properties that have been explicitly set() are considered active.
8
+ * Unset properties are treated as absent (not false/0/""). This distinction
9
+ * matters for satisfies(): a goal that only specifies { alive: true }
10
+ * matches any world state where "alive" is true, regardless of all other
11
+ * properties.
12
+ *
13
+ * Property values are polymorphic (boolean | number | string) to support
14
+ * both boolean flags and numeric planning properties (e.g., ammo count).
15
+ */
16
+ export type WorldStateValue = boolean | number | string;
17
+ export declare class WorldState {
18
+ private readonly properties;
19
+ set(key: string, value: WorldStateValue): void;
20
+ get(key: string): WorldStateValue | undefined;
21
+ has(key: string): boolean;
22
+ /**
23
+ * Check if this state satisfies all conditions in the goal.
24
+ *
25
+ * Returns true when every property defined in the goal has the same
26
+ * value in this state. Properties present in this state but absent
27
+ * in the goal are irrelevant.
28
+ */
29
+ satisfies(goal: WorldState): boolean;
30
+ /** Create a deep copy. */
31
+ clone(): WorldState;
32
+ /**
33
+ * Distance heuristic: count of differing properties.
34
+ *
35
+ * For A* planning, this counts properties in `other` that do not match
36
+ * this state. This is an admissible heuristic because each action can
37
+ * satisfy at most one property per step in the worst case.
38
+ */
39
+ distanceTo(other: WorldState): number;
40
+ /**
41
+ * Apply another state's properties as effects, returning a new WorldState.
42
+ * Does not mutate the original.
43
+ */
44
+ applyEffects(effects: WorldState): WorldState;
45
+ /** Return all property keys. Used by the planner for state fingerprinting. */
46
+ keys(): IterableIterator<string>;
47
+ }
48
+ //# sourceMappingURL=WorldState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorldState.d.ts","sourceRoot":"","sources":["../../src/ai/WorldState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAExD,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsC;IAMjE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI;IAQ9C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI7C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAQzB;;;;;;OAMG;IACH,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO;IAQpC,0BAA0B;IAC1B,KAAK,IAAI,UAAU;IAQnB;;;;;;OAMG;IACH,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM;IAUrC;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU;IAQ7C,8EAA8E;IAC9E,IAAI,IAAI,gBAAgB,CAAC,MAAM,CAAC;CAGjC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * GOAP world state -- a key-value map of planning properties.
3
+ *
4
+ * Used both as the "current world state" fed to the planner and as
5
+ * goal/precondition/effect descriptors on GOAPActions.
6
+ *
7
+ * Only properties that have been explicitly set() are considered active.
8
+ * Unset properties are treated as absent (not false/0/""). This distinction
9
+ * matters for satisfies(): a goal that only specifies { alive: true }
10
+ * matches any world state where "alive" is true, regardless of all other
11
+ * properties.
12
+ *
13
+ * Property values are polymorphic (boolean | number | string) to support
14
+ * both boolean flags and numeric planning properties (e.g., ammo count).
15
+ */
16
+ export class WorldState {
17
+ constructor() {
18
+ this.properties = new Map();
19
+ }
20
+ // -----------------------------------------------------------------------
21
+ // Mutators
22
+ // -----------------------------------------------------------------------
23
+ set(key, value) {
24
+ this.properties.set(key, value);
25
+ }
26
+ // -----------------------------------------------------------------------
27
+ // Accessors
28
+ // -----------------------------------------------------------------------
29
+ get(key) {
30
+ return this.properties.get(key);
31
+ }
32
+ has(key) {
33
+ return this.properties.has(key);
34
+ }
35
+ // -----------------------------------------------------------------------
36
+ // Planning utilities
37
+ // -----------------------------------------------------------------------
38
+ /**
39
+ * Check if this state satisfies all conditions in the goal.
40
+ *
41
+ * Returns true when every property defined in the goal has the same
42
+ * value in this state. Properties present in this state but absent
43
+ * in the goal are irrelevant.
44
+ */
45
+ satisfies(goal) {
46
+ for (const [key, goalValue] of goal.properties) {
47
+ const currentValue = this.properties.get(key);
48
+ if (currentValue !== goalValue)
49
+ return false;
50
+ }
51
+ return true;
52
+ }
53
+ /** Create a deep copy. */
54
+ clone() {
55
+ const copy = new WorldState();
56
+ for (const [key, value] of this.properties) {
57
+ copy.properties.set(key, value);
58
+ }
59
+ return copy;
60
+ }
61
+ /**
62
+ * Distance heuristic: count of differing properties.
63
+ *
64
+ * For A* planning, this counts properties in `other` that do not match
65
+ * this state. This is an admissible heuristic because each action can
66
+ * satisfy at most one property per step in the worst case.
67
+ */
68
+ distanceTo(other) {
69
+ let count = 0;
70
+ for (const [key, value] of other.properties) {
71
+ if (this.properties.get(key) !== value) {
72
+ count++;
73
+ }
74
+ }
75
+ return count;
76
+ }
77
+ /**
78
+ * Apply another state's properties as effects, returning a new WorldState.
79
+ * Does not mutate the original.
80
+ */
81
+ applyEffects(effects) {
82
+ const next = this.clone();
83
+ for (const [key, value] of effects.properties) {
84
+ next.properties.set(key, value);
85
+ }
86
+ return next;
87
+ }
88
+ /** Return all property keys. Used by the planner for state fingerprinting. */
89
+ keys() {
90
+ return this.properties.keys();
91
+ }
92
+ }
93
+ //# sourceMappingURL=WorldState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorldState.js","sourceRoot":"","sources":["../../src/ai/WorldState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,OAAO,UAAU;IAAvB;QACmB,eAAU,GAAG,IAAI,GAAG,EAA2B,CAAC;IAmFnE,CAAC;IAjFC,0EAA0E;IAC1E,WAAW;IACX,0EAA0E;IAE1E,GAAG,CAAC,GAAW,EAAE,KAAsB;QACrC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,0EAA0E;IAC1E,YAAY;IACZ,0EAA0E;IAE1E,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,0EAA0E;IAC1E,qBAAqB;IACrB,0EAA0E;IAE1E;;;;;;OAMG;IACH,SAAS,CAAC,IAAgB;QACxB,KAAK,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC9C,IAAI,YAAY,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;QAC/C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0BAA0B;IAC1B,KAAK;QACH,MAAM,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,KAAiB;QAC1B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YAC5C,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC;gBACvC,KAAK,EAAE,CAAC;YACV,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,OAAmB;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YAC9C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8EAA8E;IAC9E,IAAI;QACF,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ export { StateMachine } from './StateMachine';
2
+ export type { TransitionResult } from './StateMachine';
3
+ export { MemoryBank, MemoryChannel } from './MemorySystem';
4
+ export type { MemoryRecord, IMemoryBankConfig, IMemoryInput } from './MemorySystem';
5
+ export { DangerManager, DangerType } from './DangerManager';
6
+ export type { IDangerEntry } from './DangerManager';
7
+ export { WorldState } from './WorldState';
8
+ export { GOAPPlanner } from './GOAPPlanner';
9
+ export { GOAPAction, ActionStatus } from './GOAPAction';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,8 @@
1
+ // ai sub-path barrel
2
+ export { StateMachine } from './StateMachine';
3
+ export { MemoryBank, MemoryChannel } from './MemorySystem';
4
+ export { DangerManager, DangerType } from './DangerManager';
5
+ export { WorldState } from './WorldState';
6
+ export { GOAPPlanner } from './GOAPPlanner';
7
+ export { GOAPAction, ActionStatus } from './GOAPAction';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Value object representing a single damage event.
3
+ *
4
+ * Immutable by convention (all fields are readonly).
5
+ * Created exclusively through the {@link createDamageInstance} factory
6
+ * which validates that the amount is positive.
7
+ */
8
+ export interface IDamageInstance {
9
+ readonly amount: number;
10
+ readonly damageTypeId: string;
11
+ readonly sourceId: string;
12
+ readonly sourceType: 'entity' | 'anomaly' | 'surge';
13
+ }
14
+ export interface IDamageInstanceParams {
15
+ readonly amount: number;
16
+ readonly damageTypeId: string;
17
+ readonly sourceId: string;
18
+ readonly sourceType: IDamageInstance['sourceType'];
19
+ }
20
+ /**
21
+ * Factory that creates a validated IDamageInstance.
22
+ *
23
+ * @throws if amount is not positive
24
+ */
25
+ export declare function createDamageInstance(params: IDamageInstanceParams): IDamageInstance;
26
+ //# sourceMappingURL=DamageInstance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DamageInstance.d.ts","sourceRoot":"","sources":["../../src/combat/DamageInstance.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;CACrD;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;CACpD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe,CAenF"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Value object representing a single damage event.
3
+ *
4
+ * Immutable by convention (all fields are readonly).
5
+ * Created exclusively through the {@link createDamageInstance} factory
6
+ * which validates that the amount is positive.
7
+ */
8
+ /**
9
+ * Factory that creates a validated IDamageInstance.
10
+ *
11
+ * @throws if amount is not positive
12
+ */
13
+ export function createDamageInstance(params) {
14
+ const { amount, damageTypeId, sourceId, sourceType } = params;
15
+ if (amount <= 0) {
16
+ throw new Error(`[DamageInstance] amount must be positive, got ${amount}`);
17
+ }
18
+ return {
19
+ amount,
20
+ damageTypeId,
21
+ sourceId,
22
+ sourceType,
23
+ };
24
+ }
25
+ //# sourceMappingURL=DamageInstance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DamageInstance.js","sourceRoot":"","sources":["../../src/combat/DamageInstance.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAA6B;IAChE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAE9D,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,iDAAiD,MAAM,EAAE,CAC1D,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM;QACN,YAAY;QACZ,QAAQ;QACR,UAAU;KACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * 3-state morale system: STABLE / SHAKEN / PANICKED.
3
+ *
4
+ * Morale is a value in [-1, 1] that determines the NPC's psychological state:
5
+ * - STABLE: morale > shakenThreshold (-0.3 by default), recovery +0.005/s toward 0
6
+ * - SHAKEN: morale between shaken and panicked thresholds, recovery +0.01/s toward 0
7
+ * - PANICKED: morale <= panicThreshold (-0.7 by default), no recovery
8
+ *
9
+ * External systems call {@link adjust} to apply morale hits/boosts
10
+ * and {@link update} each frame to apply recovery.
11
+ */
12
+ export declare const MoraleState: {
13
+ readonly STABLE: "stable";
14
+ readonly SHAKEN: "shaken";
15
+ readonly PANICKED: "panicked";
16
+ };
17
+ export type MoraleState = (typeof MoraleState)[keyof typeof MoraleState];
18
+ export interface IMoraleConfig {
19
+ /** Threshold below which the NPC becomes SHAKEN. Default -0.3. */
20
+ shakenThreshold: number;
21
+ /** Threshold at or below which the NPC becomes PANICKED. Default -0.7. */
22
+ panicThreshold: number;
23
+ /** Recovery rate (per second) while STABLE. Default 0.005. */
24
+ stableRecoveryRate: number;
25
+ /** Recovery rate (per second) while SHAKEN. Default 0.01. */
26
+ shakenRecoveryRate: number;
27
+ }
28
+ export declare class MoraleTracker {
29
+ private currentMorale;
30
+ private _cachedState;
31
+ private readonly config;
32
+ constructor(config?: Partial<IMoraleConfig>);
33
+ /** Current morale value in [-1, 1]. */
34
+ get morale(): number;
35
+ /** Derived morale state based on current value and thresholds. */
36
+ get state(): MoraleState;
37
+ /**
38
+ * Apply a morale adjustment (positive = boost, negative = hit).
39
+ * Result is clamped to [-1, 1].
40
+ */
41
+ adjust(delta: number): void;
42
+ /**
43
+ * Tick recovery. Should be called each frame with the elapsed seconds.
44
+ *
45
+ * - STABLE: recovers toward 0 at stableRecoveryRate per second.
46
+ * - SHAKEN: recovers toward 0 at shakenRecoveryRate per second.
47
+ * - PANICKED: no recovery.
48
+ */
49
+ update(deltaSec: number): void;
50
+ /** Reset morale to 0 (STABLE). */
51
+ reset(): void;
52
+ }
53
+ //# sourceMappingURL=MoraleStateMachine.d.ts.map