@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.
- package/LICENSE +21 -0
- package/README.md +283 -0
- package/dist/ai/DangerManager.d.ts +71 -0
- package/dist/ai/DangerManager.d.ts.map +1 -0
- package/dist/ai/DangerManager.js +176 -0
- package/dist/ai/DangerManager.js.map +1 -0
- package/dist/ai/GOAPAction.d.ts +45 -0
- package/dist/ai/GOAPAction.d.ts.map +1 -0
- package/dist/ai/GOAPAction.js +32 -0
- package/dist/ai/GOAPAction.js.map +1 -0
- package/dist/ai/GOAPPlanner.d.ts +80 -0
- package/dist/ai/GOAPPlanner.d.ts.map +1 -0
- package/dist/ai/GOAPPlanner.js +259 -0
- package/dist/ai/GOAPPlanner.js.map +1 -0
- package/dist/ai/IStateHandler.d.ts +8 -0
- package/dist/ai/IStateHandler.d.ts.map +1 -0
- package/dist/ai/IStateHandler.js +8 -0
- package/dist/ai/IStateHandler.js.map +1 -0
- package/dist/ai/MemorySystem.d.ts +94 -0
- package/dist/ai/MemorySystem.d.ts.map +1 -0
- package/dist/ai/MemorySystem.js +207 -0
- package/dist/ai/MemorySystem.js.map +1 -0
- package/dist/ai/StateMachine.d.ts +49 -0
- package/dist/ai/StateMachine.d.ts.map +1 -0
- package/dist/ai/StateMachine.js +83 -0
- package/dist/ai/StateMachine.js.map +1 -0
- package/dist/ai/WorldState.d.ts +48 -0
- package/dist/ai/WorldState.d.ts.map +1 -0
- package/dist/ai/WorldState.js +93 -0
- package/dist/ai/WorldState.js.map +1 -0
- package/dist/ai/index.d.ts +10 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +8 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/combat/DamageInstance.d.ts +26 -0
- package/dist/combat/DamageInstance.d.ts.map +1 -0
- package/dist/combat/DamageInstance.js +25 -0
- package/dist/combat/DamageInstance.js.map +1 -0
- package/dist/combat/MoraleStateMachine.d.ts +53 -0
- package/dist/combat/MoraleStateMachine.d.ts.map +1 -0
- package/dist/combat/MoraleStateMachine.js +84 -0
- package/dist/combat/MoraleStateMachine.js.map +1 -0
- package/dist/combat/index.d.ts +5 -0
- package/dist/combat/index.d.ts.map +1 -0
- package/dist/combat/index.js +3 -0
- package/dist/combat/index.js.map +1 -0
- package/dist/config/ALifeConfig.d.ts +131 -0
- package/dist/config/ALifeConfig.d.ts.map +1 -0
- package/dist/config/ALifeConfig.js +82 -0
- package/dist/config/ALifeConfig.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/core/ALifeKernel.d.ts +163 -0
- package/dist/core/ALifeKernel.d.ts.map +1 -0
- package/dist/core/ALifeKernel.js +542 -0
- package/dist/core/ALifeKernel.js.map +1 -0
- package/dist/core/Clock.d.ts +123 -0
- package/dist/core/Clock.d.ts.map +1 -0
- package/dist/core/Clock.js +228 -0
- package/dist/core/Clock.js.map +1 -0
- package/dist/core/DevToolsInspector.d.ts +53 -0
- package/dist/core/DevToolsInspector.d.ts.map +1 -0
- package/dist/core/DevToolsInspector.js +8 -0
- package/dist/core/DevToolsInspector.js.map +1 -0
- package/dist/core/Diagnostics.d.ts +64 -0
- package/dist/core/Diagnostics.d.ts.map +1 -0
- package/dist/core/Diagnostics.js +107 -0
- package/dist/core/Diagnostics.js.map +1 -0
- package/dist/core/ISerializable.d.ts +12 -0
- package/dist/core/ISerializable.d.ts.map +1 -0
- package/dist/core/ISerializable.js +2 -0
- package/dist/core/ISerializable.js.map +1 -0
- package/dist/core/PortRegistry.d.ts +57 -0
- package/dist/core/PortRegistry.d.ts.map +1 -0
- package/dist/core/PortRegistry.js +72 -0
- package/dist/core/PortRegistry.js.map +1 -0
- package/dist/core/PortTokens.d.ts +39 -0
- package/dist/core/PortTokens.d.ts.map +1 -0
- package/dist/core/PortTokens.js +39 -0
- package/dist/core/PortTokens.js.map +1 -0
- package/dist/core/SpatialGrid.d.ts +114 -0
- package/dist/core/SpatialGrid.d.ts.map +1 -0
- package/dist/core/SpatialGrid.js +258 -0
- package/dist/core/SpatialGrid.js.map +1 -0
- package/dist/core/Vec2.d.ts +34 -0
- package/dist/core/Vec2.d.ts.map +1 -0
- package/dist/core/Vec2.js +52 -0
- package/dist/core/Vec2.js.map +1 -0
- package/dist/core/math/CatmullRom.d.ts +20 -0
- package/dist/core/math/CatmullRom.d.ts.map +1 -0
- package/dist/core/math/CatmullRom.js +37 -0
- package/dist/core/math/CatmullRom.js.map +1 -0
- package/dist/core/math/index.d.ts +6 -0
- package/dist/core/math/index.d.ts.map +1 -0
- package/dist/core/math/index.js +5 -0
- package/dist/core/math/index.js.map +1 -0
- package/dist/core/math/intersects.d.ts +32 -0
- package/dist/core/math/intersects.d.ts.map +1 -0
- package/dist/core/math/intersects.js +92 -0
- package/dist/core/math/intersects.js.map +1 -0
- package/dist/core/math/utils.d.ts +5 -0
- package/dist/core/math/utils.d.ts.map +1 -0
- package/dist/core/math/utils.js +13 -0
- package/dist/core/math/utils.js.map +1 -0
- package/dist/entity/IComponent.d.ts +17 -0
- package/dist/entity/IComponent.d.ts.map +1 -0
- package/dist/entity/IComponent.js +2 -0
- package/dist/entity/IComponent.js.map +1 -0
- package/dist/entity/IEntity.d.ts +33 -0
- package/dist/entity/IEntity.d.ts.map +1 -0
- package/dist/entity/IEntity.js +2 -0
- package/dist/entity/IEntity.js.map +1 -0
- package/dist/entity/index.d.ts +3 -0
- package/dist/entity/index.d.ts.map +1 -0
- package/dist/entity/index.js +2 -0
- package/dist/entity/index.js.map +1 -0
- package/dist/events/ALifeEvents.d.ts +241 -0
- package/dist/events/ALifeEvents.d.ts.map +1 -0
- package/dist/events/ALifeEvents.js +53 -0
- package/dist/events/ALifeEvents.js.map +1 -0
- package/dist/events/EventBus.d.ts +52 -0
- package/dist/events/EventBus.d.ts.map +1 -0
- package/dist/events/EventBus.js +129 -0
- package/dist/events/EventBus.js.map +1 -0
- package/dist/events/index.d.ts +4 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +4 -0
- package/dist/events/index.js.map +1 -0
- package/dist/faction/Faction.d.ts +53 -0
- package/dist/faction/Faction.d.ts.map +1 -0
- package/dist/faction/Faction.js +101 -0
- package/dist/faction/Faction.js.map +1 -0
- package/dist/faction/FactionBuilder.d.ts +32 -0
- package/dist/faction/FactionBuilder.d.ts.map +1 -0
- package/dist/faction/FactionBuilder.js +80 -0
- package/dist/faction/FactionBuilder.js.map +1 -0
- package/dist/faction/ImmunityProfile.d.ts +24 -0
- package/dist/faction/ImmunityProfile.d.ts.map +1 -0
- package/dist/faction/ImmunityProfile.js +43 -0
- package/dist/faction/ImmunityProfile.js.map +1 -0
- package/dist/faction/index.d.ts +6 -0
- package/dist/faction/index.d.ts.map +1 -0
- package/dist/faction/index.js +5 -0
- package/dist/faction/index.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/ILogEntry.d.ts +16 -0
- package/dist/logger/ILogEntry.d.ts.map +1 -0
- package/dist/logger/ILogEntry.js +2 -0
- package/dist/logger/ILogEntry.js.map +1 -0
- package/dist/logger/LogChannel.d.ts +27 -0
- package/dist/logger/LogChannel.d.ts.map +1 -0
- package/dist/logger/LogChannel.js +26 -0
- package/dist/logger/LogChannel.js.map +1 -0
- package/dist/logger/LogLevel.d.ts +10 -0
- package/dist/logger/LogLevel.d.ts.map +1 -0
- package/dist/logger/LogLevel.js +9 -0
- package/dist/logger/LogLevel.js.map +1 -0
- package/dist/logger/Logger.d.ts +56 -0
- package/dist/logger/Logger.d.ts.map +1 -0
- package/dist/logger/Logger.js +106 -0
- package/dist/logger/Logger.js.map +1 -0
- package/dist/logger/index.d.ts +8 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +5 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/movement/MonsterHome.d.ts +49 -0
- package/dist/movement/MonsterHome.d.ts.map +1 -0
- package/dist/movement/MonsterHome.js +75 -0
- package/dist/movement/MonsterHome.js.map +1 -0
- package/dist/movement/PatrolRoute.d.ts +99 -0
- package/dist/movement/PatrolRoute.d.ts.map +1 -0
- package/dist/movement/PatrolRoute.js +141 -0
- package/dist/movement/PatrolRoute.js.map +1 -0
- package/dist/movement/index.d.ts +5 -0
- package/dist/movement/index.d.ts.map +1 -0
- package/dist/movement/index.js +4 -0
- package/dist/movement/index.js.map +1 -0
- package/dist/navigation/LevelGraph.d.ts +78 -0
- package/dist/navigation/LevelGraph.d.ts.map +1 -0
- package/dist/navigation/LevelGraph.js +268 -0
- package/dist/navigation/LevelGraph.js.map +1 -0
- package/dist/navigation/NPCGraphMover.d.ts +87 -0
- package/dist/navigation/NPCGraphMover.d.ts.map +1 -0
- package/dist/navigation/NPCGraphMover.js +193 -0
- package/dist/navigation/NPCGraphMover.js.map +1 -0
- package/dist/navigation/index.d.ts +5 -0
- package/dist/navigation/index.d.ts.map +1 -0
- package/dist/navigation/index.js +4 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/plugins/AnomaliesPlugin.d.ts +26 -0
- package/dist/plugins/AnomaliesPlugin.d.ts.map +1 -0
- package/dist/plugins/AnomaliesPlugin.js +30 -0
- package/dist/plugins/AnomaliesPlugin.js.map +1 -0
- package/dist/plugins/CombatSchemaPlugin.d.ts +35 -0
- package/dist/plugins/CombatSchemaPlugin.d.ts.map +1 -0
- package/dist/plugins/CombatSchemaPlugin.js +44 -0
- package/dist/plugins/CombatSchemaPlugin.js.map +1 -0
- package/dist/plugins/FactionsPlugin.d.ts +26 -0
- package/dist/plugins/FactionsPlugin.d.ts.map +1 -0
- package/dist/plugins/FactionsPlugin.js +30 -0
- package/dist/plugins/FactionsPlugin.js.map +1 -0
- package/dist/plugins/IALifePlugin.d.ts +91 -0
- package/dist/plugins/IALifePlugin.d.ts.map +1 -0
- package/dist/plugins/IALifePlugin.js +2 -0
- package/dist/plugins/IALifePlugin.js.map +1 -0
- package/dist/plugins/MonstersPlugin.d.ts +26 -0
- package/dist/plugins/MonstersPlugin.d.ts.map +1 -0
- package/dist/plugins/MonstersPlugin.js +30 -0
- package/dist/plugins/MonstersPlugin.js.map +1 -0
- package/dist/plugins/NPCTypesPlugin.d.ts +26 -0
- package/dist/plugins/NPCTypesPlugin.d.ts.map +1 -0
- package/dist/plugins/NPCTypesPlugin.js +30 -0
- package/dist/plugins/NPCTypesPlugin.js.map +1 -0
- package/dist/plugins/PluginToken.d.ts +26 -0
- package/dist/plugins/PluginToken.d.ts.map +1 -0
- package/dist/plugins/PluginToken.js +22 -0
- package/dist/plugins/PluginToken.js.map +1 -0
- package/dist/plugins/SocialPlugin.d.ts +14 -0
- package/dist/plugins/SocialPlugin.d.ts.map +1 -0
- package/dist/plugins/SocialPlugin.js +16 -0
- package/dist/plugins/SocialPlugin.js.map +1 -0
- package/dist/plugins/SpawnPlugin.d.ts +15 -0
- package/dist/plugins/SpawnPlugin.d.ts.map +1 -0
- package/dist/plugins/SpawnPlugin.js +26 -0
- package/dist/plugins/SpawnPlugin.js.map +1 -0
- package/dist/plugins/SquadPlugin.d.ts +14 -0
- package/dist/plugins/SquadPlugin.d.ts.map +1 -0
- package/dist/plugins/SquadPlugin.js +16 -0
- package/dist/plugins/SquadPlugin.js.map +1 -0
- package/dist/plugins/SurgePlugin.d.ts +20 -0
- package/dist/plugins/SurgePlugin.d.ts.map +1 -0
- package/dist/plugins/SurgePlugin.js +22 -0
- package/dist/plugins/SurgePlugin.js.map +1 -0
- package/dist/plugins/TradePlugin.d.ts +16 -0
- package/dist/plugins/TradePlugin.d.ts.map +1 -0
- package/dist/plugins/TradePlugin.js +18 -0
- package/dist/plugins/TradePlugin.js.map +1 -0
- package/dist/plugins/index.d.ts +11 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +10 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/pluginNames.d.ts +37 -0
- package/dist/plugins/pluginNames.d.ts.map +1 -0
- package/dist/plugins/pluginNames.js +28 -0
- package/dist/plugins/pluginNames.js.map +1 -0
- package/dist/plugins/presets.d.ts +31 -0
- package/dist/plugins/presets.d.ts.map +1 -0
- package/dist/plugins/presets.js +50 -0
- package/dist/plugins/presets.js.map +1 -0
- package/dist/ports/IDataLoader.d.ts +38 -0
- package/dist/ports/IDataLoader.d.ts.map +1 -0
- package/dist/ports/IDataLoader.js +12 -0
- package/dist/ports/IDataLoader.js.map +1 -0
- package/dist/ports/IEntityAdapter.d.ts +73 -0
- package/dist/ports/IEntityAdapter.d.ts.map +1 -0
- package/dist/ports/IEntityAdapter.js +36 -0
- package/dist/ports/IEntityAdapter.js.map +1 -0
- package/dist/ports/IEntityFactory.d.ts +66 -0
- package/dist/ports/IEntityFactory.d.ts.map +1 -0
- package/dist/ports/IEntityFactory.js +21 -0
- package/dist/ports/IEntityFactory.js.map +1 -0
- package/dist/ports/ILogger.d.ts +29 -0
- package/dist/ports/ILogger.d.ts.map +1 -0
- package/dist/ports/ILogger.js +2 -0
- package/dist/ports/ILogger.js.map +1 -0
- package/dist/ports/IPlayerPositionProvider.d.ts +20 -0
- package/dist/ports/IPlayerPositionProvider.d.ts.map +1 -0
- package/dist/ports/IPlayerPositionProvider.js +11 -0
- package/dist/ports/IPlayerPositionProvider.js.map +1 -0
- package/dist/ports/IRandom.d.ts +25 -0
- package/dist/ports/IRandom.d.ts.map +1 -0
- package/dist/ports/IRandom.js +39 -0
- package/dist/ports/IRandom.js.map +1 -0
- package/dist/ports/IRuntimeClock.d.ts +18 -0
- package/dist/ports/IRuntimeClock.d.ts.map +1 -0
- package/dist/ports/IRuntimeClock.js +2 -0
- package/dist/ports/IRuntimeClock.js.map +1 -0
- package/dist/ports/index.d.ts +12 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +5 -0
- package/dist/ports/index.js.map +1 -0
- package/dist/registry/AIStateRegistry.d.ts +42 -0
- package/dist/registry/AIStateRegistry.d.ts.map +1 -0
- package/dist/registry/AIStateRegistry.js +27 -0
- package/dist/registry/AIStateRegistry.js.map +1 -0
- package/dist/registry/AnomalyTypeRegistry.d.ts +21 -0
- package/dist/registry/AnomalyTypeRegistry.d.ts.map +1 -0
- package/dist/registry/AnomalyTypeRegistry.js +20 -0
- package/dist/registry/AnomalyTypeRegistry.js.map +1 -0
- package/dist/registry/BehaviorSchemeRegistry.d.ts +21 -0
- package/dist/registry/BehaviorSchemeRegistry.d.ts.map +1 -0
- package/dist/registry/BehaviorSchemeRegistry.js +24 -0
- package/dist/registry/BehaviorSchemeRegistry.js.map +1 -0
- package/dist/registry/DamageTypeRegistry.d.ts +17 -0
- package/dist/registry/DamageTypeRegistry.d.ts.map +1 -0
- package/dist/registry/DamageTypeRegistry.js +24 -0
- package/dist/registry/DamageTypeRegistry.js.map +1 -0
- package/dist/registry/FactionRegistry.d.ts +41 -0
- package/dist/registry/FactionRegistry.d.ts.map +1 -0
- package/dist/registry/FactionRegistry.js +29 -0
- package/dist/registry/FactionRegistry.js.map +1 -0
- package/dist/registry/MonsterRegistry.d.ts +44 -0
- package/dist/registry/MonsterRegistry.d.ts.map +1 -0
- package/dist/registry/MonsterRegistry.js +43 -0
- package/dist/registry/MonsterRegistry.js.map +1 -0
- package/dist/registry/NPCTypeRegistry.d.ts +34 -0
- package/dist/registry/NPCTypeRegistry.d.ts.map +1 -0
- package/dist/registry/NPCTypeRegistry.js +20 -0
- package/dist/registry/NPCTypeRegistry.js.map +1 -0
- package/dist/registry/Registry.d.ts +44 -0
- package/dist/registry/Registry.d.ts.map +1 -0
- package/dist/registry/Registry.js +80 -0
- package/dist/registry/Registry.js.map +1 -0
- package/dist/registry/TaskTypeRegistry.d.ts +17 -0
- package/dist/registry/TaskTypeRegistry.d.ts.map +1 -0
- package/dist/registry/TaskTypeRegistry.js +16 -0
- package/dist/registry/TaskTypeRegistry.js.map +1 -0
- package/dist/registry/index.d.ts +19 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +11 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/validators.d.ts +32 -0
- package/dist/schema/validators.d.ts.map +1 -0
- package/dist/schema/validators.js +249 -0
- package/dist/schema/validators.js.map +1 -0
- package/dist/spawn/SpawnRegistry.d.ts +48 -0
- package/dist/spawn/SpawnRegistry.d.ts.map +1 -0
- package/dist/spawn/SpawnRegistry.js +141 -0
- package/dist/spawn/SpawnRegistry.js.map +1 -0
- package/dist/spawn/index.d.ts +3 -0
- package/dist/spawn/index.d.ts.map +1 -0
- package/dist/spawn/index.js +3 -0
- package/dist/spawn/index.js.map +1 -0
- package/dist/terrain/SmartTerrain.d.ts +119 -0
- package/dist/terrain/SmartTerrain.d.ts.map +1 -0
- package/dist/terrain/SmartTerrain.js +124 -0
- package/dist/terrain/SmartTerrain.js.map +1 -0
- package/dist/terrain/TerrainBuilder.d.ts +44 -0
- package/dist/terrain/TerrainBuilder.d.ts.map +1 -0
- package/dist/terrain/TerrainBuilder.js +112 -0
- package/dist/terrain/TerrainBuilder.js.map +1 -0
- package/dist/terrain/Zone.d.ts +25 -0
- package/dist/terrain/Zone.d.ts.map +1 -0
- package/dist/terrain/Zone.js +29 -0
- package/dist/terrain/Zone.js.map +1 -0
- package/dist/terrain/index.d.ts +6 -0
- package/dist/terrain/index.d.ts.map +1 -0
- package/dist/terrain/index.js +5 -0
- package/dist/terrain/index.js.map +1 -0
- package/dist/time/TimeManager.d.ts +21 -0
- package/dist/time/TimeManager.d.ts.map +1 -0
- package/dist/time/TimeManager.js +41 -0
- package/dist/time/TimeManager.js.map +1 -0
- package/dist/time/index.d.ts +3 -0
- package/dist/time/index.d.ts.map +1 -0
- package/dist/time/index.js +2 -0
- package/dist/time/index.js.map +1 -0
- 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"}
|
package/dist/ai/index.js
ADDED
|
@@ -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
|