@ai-rpg-engine/modules 1.0.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/dist/belief-provenance.d.ts +41 -0
- package/dist/belief-provenance.d.ts.map +1 -0
- package/dist/belief-provenance.js +254 -0
- package/dist/belief-provenance.js.map +1 -0
- package/dist/belief-provenance.test.d.ts +2 -0
- package/dist/belief-provenance.test.d.ts.map +1 -0
- package/dist/belief-provenance.test.js +139 -0
- package/dist/belief-provenance.test.js.map +1 -0
- package/dist/cognition-core.d.ts +89 -0
- package/dist/cognition-core.d.ts.map +1 -0
- package/dist/cognition-core.js +370 -0
- package/dist/cognition-core.js.map +1 -0
- package/dist/cognition-core.test.d.ts +2 -0
- package/dist/cognition-core.test.d.ts.map +1 -0
- package/dist/cognition-core.test.js +215 -0
- package/dist/cognition-core.test.js.map +1 -0
- package/dist/combat-core.d.ts +11 -0
- package/dist/combat-core.d.ts.map +1 -0
- package/dist/combat-core.js +152 -0
- package/dist/combat-core.js.map +1 -0
- package/dist/dialogue-core.d.ts +10 -0
- package/dist/dialogue-core.d.ts.map +1 -0
- package/dist/dialogue-core.js +172 -0
- package/dist/dialogue-core.js.map +1 -0
- package/dist/district-core.d.ts +59 -0
- package/dist/district-core.d.ts.map +1 -0
- package/dist/district-core.js +224 -0
- package/dist/district-core.js.map +1 -0
- package/dist/district-core.test.d.ts +2 -0
- package/dist/district-core.test.d.ts.map +1 -0
- package/dist/district-core.test.js +157 -0
- package/dist/district-core.test.js.map +1 -0
- package/dist/environment-core.d.ts +78 -0
- package/dist/environment-core.d.ts.map +1 -0
- package/dist/environment-core.js +229 -0
- package/dist/environment-core.js.map +1 -0
- package/dist/environment-core.test.d.ts +2 -0
- package/dist/environment-core.test.d.ts.map +1 -0
- package/dist/environment-core.test.js +252 -0
- package/dist/environment-core.test.js.map +1 -0
- package/dist/faction-cognition.d.ts +39 -0
- package/dist/faction-cognition.d.ts.map +1 -0
- package/dist/faction-cognition.js +139 -0
- package/dist/faction-cognition.js.map +1 -0
- package/dist/faction-cognition.test.d.ts +2 -0
- package/dist/faction-cognition.test.d.ts.map +1 -0
- package/dist/faction-cognition.test.js +166 -0
- package/dist/faction-cognition.test.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/inventory-core.d.ts +10 -0
- package/dist/inventory-core.d.ts.map +1 -0
- package/dist/inventory-core.js +69 -0
- package/dist/inventory-core.js.map +1 -0
- package/dist/knowledge-decay.test.d.ts +2 -0
- package/dist/knowledge-decay.test.d.ts.map +1 -0
- package/dist/knowledge-decay.test.js +143 -0
- package/dist/knowledge-decay.test.js.map +1 -0
- package/dist/narrative-authority.d.ts +40 -0
- package/dist/narrative-authority.d.ts.map +1 -0
- package/dist/narrative-authority.js +89 -0
- package/dist/narrative-authority.js.map +1 -0
- package/dist/narrative-authority.test.d.ts +2 -0
- package/dist/narrative-authority.test.d.ts.map +1 -0
- package/dist/narrative-authority.test.js +237 -0
- package/dist/narrative-authority.test.js.map +1 -0
- package/dist/observer-presentation.d.ts +74 -0
- package/dist/observer-presentation.d.ts.map +1 -0
- package/dist/observer-presentation.js +277 -0
- package/dist/observer-presentation.js.map +1 -0
- package/dist/observer-presentation.test.d.ts +2 -0
- package/dist/observer-presentation.test.d.ts.map +1 -0
- package/dist/observer-presentation.test.js +156 -0
- package/dist/observer-presentation.test.js.map +1 -0
- package/dist/perception-filter.d.ts +46 -0
- package/dist/perception-filter.d.ts.map +1 -0
- package/dist/perception-filter.js +281 -0
- package/dist/perception-filter.js.map +1 -0
- package/dist/perception-filter.test.d.ts +2 -0
- package/dist/perception-filter.test.d.ts.map +1 -0
- package/dist/perception-filter.test.js +308 -0
- package/dist/perception-filter.test.js.map +1 -0
- package/dist/progression-core.d.ts +63 -0
- package/dist/progression-core.d.ts.map +1 -0
- package/dist/progression-core.js +232 -0
- package/dist/progression-core.js.map +1 -0
- package/dist/progression-core.test.d.ts +2 -0
- package/dist/progression-core.test.d.ts.map +1 -0
- package/dist/progression-core.test.js +328 -0
- package/dist/progression-core.test.js.map +1 -0
- package/dist/rumor-propagation.d.ts +31 -0
- package/dist/rumor-propagation.d.ts.map +1 -0
- package/dist/rumor-propagation.js +180 -0
- package/dist/rumor-propagation.js.map +1 -0
- package/dist/rumor-propagation.test.d.ts +2 -0
- package/dist/rumor-propagation.test.d.ts.map +1 -0
- package/dist/rumor-propagation.test.js +176 -0
- package/dist/rumor-propagation.test.js.map +1 -0
- package/dist/simulation-inspector.d.ts +78 -0
- package/dist/simulation-inspector.d.ts.map +1 -0
- package/dist/simulation-inspector.js +263 -0
- package/dist/simulation-inspector.js.map +1 -0
- package/dist/simulation-inspector.test.d.ts +2 -0
- package/dist/simulation-inspector.test.d.ts.map +1 -0
- package/dist/simulation-inspector.test.js +152 -0
- package/dist/simulation-inspector.test.js.map +1 -0
- package/dist/status-core.d.ts +17 -0
- package/dist/status-core.d.ts.map +1 -0
- package/dist/status-core.js +106 -0
- package/dist/status-core.js.map +1 -0
- package/dist/traversal-core.d.ts +3 -0
- package/dist/traversal-core.d.ts.map +1 -0
- package/dist/traversal-core.js +93 -0
- package/dist/traversal-core.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { Engine } from '@ai-rpg-engine/core';
|
|
3
|
+
import { traversalCore, combatCore, createCognitionCore, createPerceptionFilter, createEnvironmentCore, createFactionCognition, createRumorPropagation, createObserverPresentation, presentForObserver, presentForAllObservers, getDivergences, getEventDivergences, setBelief, getCognition, } from './index.js';
|
|
4
|
+
const manifest = {
|
|
5
|
+
id: 'observer-test', title: '', version: '0.1.0',
|
|
6
|
+
engineVersion: '0.1.0', ruleset: 'test', modules: [], contentPacks: [],
|
|
7
|
+
};
|
|
8
|
+
const zones = [
|
|
9
|
+
{ id: 'clearing', roomId: 'r1', name: 'Clearing', tags: [], neighbors: ['cave'], light: 7, stability: 5 },
|
|
10
|
+
{ id: 'cave', roomId: 'r1', name: 'Dark Cave', tags: [], neighbors: ['clearing'], light: 1, stability: 2 },
|
|
11
|
+
];
|
|
12
|
+
const player = {
|
|
13
|
+
id: 'player', blueprintId: 'p', type: 'player', name: 'Hero',
|
|
14
|
+
tags: ['player'], stats: { vigor: 5, instinct: 5 }, resources: { hp: 20 },
|
|
15
|
+
statuses: [], zoneId: 'clearing',
|
|
16
|
+
};
|
|
17
|
+
const friendlyNpc = {
|
|
18
|
+
id: 'ally', blueprintId: 'a', type: 'npc', name: 'Ally',
|
|
19
|
+
tags: ['npc', 'friendly'], stats: { vigor: 3, instinct: 4 }, resources: { hp: 10 },
|
|
20
|
+
statuses: [], zoneId: 'cave',
|
|
21
|
+
ai: { profileId: 'cautious', goals: [], fears: [], alertLevel: 0, knowledge: {} },
|
|
22
|
+
};
|
|
23
|
+
const hostileGuard = {
|
|
24
|
+
id: 'guard', blueprintId: 'g', type: 'enemy', name: 'Guard',
|
|
25
|
+
tags: ['enemy', 'undead'], stats: { vigor: 4, instinct: 3 }, resources: { hp: 15 },
|
|
26
|
+
statuses: [], zoneId: 'cave',
|
|
27
|
+
ai: { profileId: 'aggressive', goals: [], fears: [], alertLevel: 0, knowledge: {} },
|
|
28
|
+
};
|
|
29
|
+
// Custom presentation rule: undead tag frames all entry as "intrusion"
|
|
30
|
+
const undeadRule = {
|
|
31
|
+
id: 'undead-intrusion',
|
|
32
|
+
eventPatterns: ['world.zone.entered'],
|
|
33
|
+
priority: 10,
|
|
34
|
+
condition: (_event, ctx) => ctx.observer.tags.includes('undead'),
|
|
35
|
+
transform: (event, _ctx) => ({
|
|
36
|
+
...event,
|
|
37
|
+
payload: {
|
|
38
|
+
...event.payload,
|
|
39
|
+
_subjectiveDescription: 'the living dare to trespass',
|
|
40
|
+
_undeadView: true,
|
|
41
|
+
},
|
|
42
|
+
}),
|
|
43
|
+
};
|
|
44
|
+
function createTestEngine(rules) {
|
|
45
|
+
const engine = new Engine({
|
|
46
|
+
manifest,
|
|
47
|
+
seed: 42,
|
|
48
|
+
modules: [
|
|
49
|
+
traversalCore,
|
|
50
|
+
combatCore,
|
|
51
|
+
createCognitionCore(),
|
|
52
|
+
createPerceptionFilter(),
|
|
53
|
+
createEnvironmentCore(),
|
|
54
|
+
createFactionCognition({
|
|
55
|
+
factions: [
|
|
56
|
+
{ factionId: 'crypt-guard', entityIds: ['guard'], cohesion: 0.8 },
|
|
57
|
+
],
|
|
58
|
+
}),
|
|
59
|
+
createRumorPropagation(),
|
|
60
|
+
createObserverPresentation({ rules }),
|
|
61
|
+
],
|
|
62
|
+
});
|
|
63
|
+
for (const zone of zones)
|
|
64
|
+
engine.store.addZone(zone);
|
|
65
|
+
engine.store.addEntity({ ...player });
|
|
66
|
+
engine.store.addEntity({ ...friendlyNpc });
|
|
67
|
+
engine.store.addEntity({ ...hostileGuard });
|
|
68
|
+
engine.store.state.playerId = 'player';
|
|
69
|
+
engine.store.state.locationId = 'clearing';
|
|
70
|
+
return engine;
|
|
71
|
+
}
|
|
72
|
+
describe('Observer Presentation', () => {
|
|
73
|
+
it('presents event without rules applied when no conditions match', () => {
|
|
74
|
+
const engine = createTestEngine();
|
|
75
|
+
const events = engine.submitAction('move', { targetIds: ['cave'] });
|
|
76
|
+
const moveEvent = engine.world.eventLog.find((e) => e.type === 'world.zone.entered');
|
|
77
|
+
expect(moveEvent).toBeDefined();
|
|
78
|
+
// The ally in cave has no undead tag, no hostile belief → should get basic presentation
|
|
79
|
+
const presented = presentForObserver(moveEvent, 'ally', engine.world);
|
|
80
|
+
expect(presented._observerId).toBe('ally');
|
|
81
|
+
// No custom rule matched for ally
|
|
82
|
+
expect(presented._appliedRules.includes('undead-intrusion')).toBe(false);
|
|
83
|
+
});
|
|
84
|
+
it('applies custom rules based on observer tags', () => {
|
|
85
|
+
const engine = createTestEngine([undeadRule]);
|
|
86
|
+
const events = engine.submitAction('move', { targetIds: ['cave'] });
|
|
87
|
+
const moveEvent = engine.world.eventLog.find((e) => e.type === 'world.zone.entered');
|
|
88
|
+
// Guard is undead → should get undead-intrusion framing
|
|
89
|
+
const presented = presentForObserver(moveEvent, 'guard', engine.world, [undeadRule]);
|
|
90
|
+
expect(presented._appliedRules).toContain('undead-intrusion');
|
|
91
|
+
expect(presented.payload._undeadView).toBe(true);
|
|
92
|
+
expect(presented.payload._subjectiveDescription).toBe('the living dare to trespass');
|
|
93
|
+
});
|
|
94
|
+
it('different observers get different presentations of the same event', () => {
|
|
95
|
+
const engine = createTestEngine([undeadRule]);
|
|
96
|
+
const events = engine.submitAction('move', { targetIds: ['cave'] });
|
|
97
|
+
const moveEvent = engine.world.eventLog.find((e) => e.type === 'world.zone.entered');
|
|
98
|
+
const allyView = presentForObserver(moveEvent, 'ally', engine.world, [undeadRule]);
|
|
99
|
+
const guardView = presentForObserver(moveEvent, 'guard', engine.world, [undeadRule]);
|
|
100
|
+
// Guard sees undead framing, ally does not
|
|
101
|
+
expect(guardView.payload._undeadView).toBe(true);
|
|
102
|
+
expect(allyView.payload._undeadView).toBeUndefined();
|
|
103
|
+
});
|
|
104
|
+
it('presentForAllObservers produces one version per AI entity', () => {
|
|
105
|
+
const engine = createTestEngine([undeadRule]);
|
|
106
|
+
engine.submitAction('move', { targetIds: ['cave'] });
|
|
107
|
+
const moveEvent = engine.world.eventLog.find((e) => e.type === 'world.zone.entered');
|
|
108
|
+
const allViews = presentForAllObservers(moveEvent, engine.world);
|
|
109
|
+
// Two AI entities: ally and guard
|
|
110
|
+
expect(allViews.length).toBe(2);
|
|
111
|
+
const ids = allViews.map((v) => v._observerId);
|
|
112
|
+
expect(ids).toContain('ally');
|
|
113
|
+
expect(ids).toContain('guard');
|
|
114
|
+
});
|
|
115
|
+
it('records divergences when rules are applied', () => {
|
|
116
|
+
const engine = createTestEngine([undeadRule]);
|
|
117
|
+
engine.submitAction('move', { targetIds: ['cave'] });
|
|
118
|
+
const moveEvent = engine.world.eventLog.find((e) => e.type === 'world.zone.entered');
|
|
119
|
+
// This triggers divergence recording
|
|
120
|
+
presentForObserver(moveEvent, 'guard', engine.world, [undeadRule]);
|
|
121
|
+
const divergences = getDivergences(engine.world);
|
|
122
|
+
expect(divergences.length).toBe(1);
|
|
123
|
+
expect(divergences[0].observerId).toBe('guard');
|
|
124
|
+
expect(divergences[0].appliedRules).toContain('undead-intrusion');
|
|
125
|
+
});
|
|
126
|
+
it('getEventDivergences filters by event', () => {
|
|
127
|
+
const engine = createTestEngine([undeadRule]);
|
|
128
|
+
engine.submitAction('move', { targetIds: ['cave'] });
|
|
129
|
+
const moveEvent = engine.world.eventLog.find((e) => e.type === 'world.zone.entered');
|
|
130
|
+
presentForObserver(moveEvent, 'guard', engine.world, [undeadRule]);
|
|
131
|
+
presentForObserver(moveEvent, 'ally', engine.world, [undeadRule]);
|
|
132
|
+
const divergences = getEventDivergences(engine.world, moveEvent.id);
|
|
133
|
+
// Guard has undead-intrusion applied, ally may have built-in rules
|
|
134
|
+
expect(divergences.some((d) => d.observerId === 'guard')).toBe(true);
|
|
135
|
+
});
|
|
136
|
+
it('built-in hostile-faction-bias rule fires when observer believes actor hostile', () => {
|
|
137
|
+
const engine = createTestEngine();
|
|
138
|
+
// Give guard a hostile belief about the player
|
|
139
|
+
const guardCog = getCognition(engine.world, 'guard');
|
|
140
|
+
setBelief(guardCog, 'player', 'hostile', true, 0.9, 'observed', 0);
|
|
141
|
+
engine.submitAction('move', { targetIds: ['cave'] });
|
|
142
|
+
const moveEvent = engine.world.eventLog.find((e) => e.type === 'world.zone.entered');
|
|
143
|
+
const guardView = presentForObserver(moveEvent, 'guard', engine.world);
|
|
144
|
+
expect(guardView._appliedRules).toContain('hostile-faction-bias');
|
|
145
|
+
expect(guardView.payload._hostileBias).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
it('handles non-existent observer gracefully', () => {
|
|
148
|
+
const engine = createTestEngine();
|
|
149
|
+
engine.submitAction('move', { targetIds: ['cave'] });
|
|
150
|
+
const moveEvent = engine.world.eventLog.find((e) => e.type === 'world.zone.entered');
|
|
151
|
+
const presented = presentForObserver(moveEvent, 'nonexistent', engine.world);
|
|
152
|
+
expect(presented._observerId).toBe('nonexistent');
|
|
153
|
+
expect(presented._appliedRules.length).toBe(0);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
//# sourceMappingURL=observer-presentation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer-presentation.test.js","sourceRoot":"","sources":["../src/observer-presentation.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { EngineModule, EntityState, WorldState, ResolvedEvent } from '@ai-rpg-engine/core';
|
|
2
|
+
export type SenseType = 'sight' | 'hearing' | 'smell' | 'tremorsense' | 'thermal' | 'network';
|
|
3
|
+
export type PerceivedEvent = {
|
|
4
|
+
eventId: string;
|
|
5
|
+
entityId: string;
|
|
6
|
+
tick: number;
|
|
7
|
+
detected: boolean;
|
|
8
|
+
/** 0-1: how clearly they perceived it */
|
|
9
|
+
clarity: number;
|
|
10
|
+
sense: SenseType;
|
|
11
|
+
interpretation: 'full' | 'partial' | 'none';
|
|
12
|
+
data?: Record<string, unknown>;
|
|
13
|
+
};
|
|
14
|
+
export type PerceptionLayer = {
|
|
15
|
+
id: string;
|
|
16
|
+
/** What event types this layer handles (exact match or domain wildcard like 'combat.*') */
|
|
17
|
+
eventPatterns: string[];
|
|
18
|
+
/** What sense is required */
|
|
19
|
+
sense: SenseType;
|
|
20
|
+
/** Base detection difficulty */
|
|
21
|
+
baseDifficulty: number;
|
|
22
|
+
/** Can be detected from adjacent zones? */
|
|
23
|
+
crossZone?: boolean;
|
|
24
|
+
/** How to process a successfully perceived event */
|
|
25
|
+
onPerceived: (event: ResolvedEvent, entity: EntityState, clarity: number, world: WorldState) => void;
|
|
26
|
+
/** What partial info leaks on failed perception (clarity > 0.15) */
|
|
27
|
+
onPartial?: (event: ResolvedEvent, entity: EntityState, clarity: number, world: WorldState) => void;
|
|
28
|
+
};
|
|
29
|
+
export type PerceptionFilterConfig = {
|
|
30
|
+
/** Custom perception layers (added to built-ins) */
|
|
31
|
+
layers?: PerceptionLayer[];
|
|
32
|
+
/** Default perception stat name (default: 'instinct') */
|
|
33
|
+
perceptionStat?: string;
|
|
34
|
+
/** Per-sense stat overrides */
|
|
35
|
+
senseStats?: Partial<Record<SenseType, string>>;
|
|
36
|
+
};
|
|
37
|
+
export declare function createPerceptionFilter(config?: PerceptionFilterConfig): EngineModule;
|
|
38
|
+
/** Get all perception log entries for an entity */
|
|
39
|
+
export declare function getPerceptionLog(world: WorldState, entityId: string): PerceivedEvent[];
|
|
40
|
+
/** Get recent perceptions within a tick window */
|
|
41
|
+
export declare function getRecentPerceptions(world: WorldState, entityId: string, withinTicks: number): PerceivedEvent[];
|
|
42
|
+
/** Check if an entity perceived a specific event */
|
|
43
|
+
export declare function didPerceive(world: WorldState, entityId: string, eventId: string): PerceivedEvent | undefined;
|
|
44
|
+
/** Get all entities that perceived a specific event */
|
|
45
|
+
export declare function whoPerceived(world: WorldState, eventId: string): PerceivedEvent[];
|
|
46
|
+
//# sourceMappingURL=perception-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perception-filter.d.ts","sourceRoot":"","sources":["../src/perception-filter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,aAAa,EAEd,MAAM,qBAAqB,CAAC;AAS7B,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,CAAC;AAE9F,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS,CAAC;IACjB,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,2FAA2F;IAC3F,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,6BAA6B;IAC7B,KAAK,EAAE,SAAS,CAAC;IACjB,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oDAAoD;IACpD,WAAW,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACrG,oEAAoE;IACpE,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACrG,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,oDAAoD;IACpD,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,yDAAyD;IACzD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+BAA+B;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;CACjD,CAAC;AAMF,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE,sBAAsB,GAAG,YAAY,CA2BpF;AA8QD,mDAAmD;AACnD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CAItF;AAED,kDAAkD;AAClD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,cAAc,EAAE,CAIlB;AAED,oDAAoD;AACpD,wBAAgB,WAAW,CACzB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,cAAc,GAAG,SAAS,CAE5B;AAED,uDAAuD;AACvD,wBAAgB,YAAY,CAC1B,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,MAAM,GACd,cAAc,EAAE,CAUlB"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
// perception-filter — entity-level truth layers
|
|
2
|
+
// Each entity perceives events through their own cognitive filters.
|
|
3
|
+
// When loaded alongside cognition-core, replaces naive "all entities in zone know"
|
|
4
|
+
// with perception-checked awareness. Direct participants always know what happened.
|
|
5
|
+
import { getCognition, setBelief, addMemory, } from './cognition-core.js';
|
|
6
|
+
// --- Module ---
|
|
7
|
+
const DEFAULT_PERCEPTION_STAT = 'instinct';
|
|
8
|
+
export function createPerceptionFilter(config) {
|
|
9
|
+
const perceptionStat = config?.perceptionStat ?? DEFAULT_PERCEPTION_STAT;
|
|
10
|
+
const senseStats = config?.senseStats ?? {};
|
|
11
|
+
const customLayers = config?.layers ?? [];
|
|
12
|
+
// Combine built-in layers with custom ones
|
|
13
|
+
const allLayers = [
|
|
14
|
+
...getBuiltinLayers(),
|
|
15
|
+
...customLayers,
|
|
16
|
+
];
|
|
17
|
+
return {
|
|
18
|
+
id: 'perception-filter',
|
|
19
|
+
version: '0.1.0',
|
|
20
|
+
dependsOn: ['cognition-core'],
|
|
21
|
+
register(ctx) {
|
|
22
|
+
ctx.persistence.registerNamespace('perception-filter', {
|
|
23
|
+
perceptionLog: {},
|
|
24
|
+
});
|
|
25
|
+
// Catch-all listener that routes events through perception layers
|
|
26
|
+
ctx.events.on('*', (event, world) => {
|
|
27
|
+
processEvent(event, world, allLayers, perceptionStat, senseStats);
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// --- Core Processing ---
|
|
33
|
+
function processEvent(event, world, layers, defaultStat, senseStats) {
|
|
34
|
+
// Find matching layers for this event type
|
|
35
|
+
const matchingLayers = layers.filter((layer) => layer.eventPatterns.some((pattern) => matchEventPattern(event.type, pattern)));
|
|
36
|
+
if (matchingLayers.length === 0)
|
|
37
|
+
return;
|
|
38
|
+
// Determine where this event occurred
|
|
39
|
+
const eventZone = getEventZone(event, world);
|
|
40
|
+
if (!eventZone)
|
|
41
|
+
return;
|
|
42
|
+
const actorId = event.actorId;
|
|
43
|
+
for (const entity of Object.values(world.entities)) {
|
|
44
|
+
// Skip the actor (they know what they did)
|
|
45
|
+
if (entity.id === actorId)
|
|
46
|
+
continue;
|
|
47
|
+
// Skip direct targets (cognition-core handles direct experience)
|
|
48
|
+
if (event.targetIds?.includes(entity.id))
|
|
49
|
+
continue;
|
|
50
|
+
// Skip non-AI entities
|
|
51
|
+
if (!entity.ai)
|
|
52
|
+
continue;
|
|
53
|
+
for (const layer of matchingLayers) {
|
|
54
|
+
const isInZone = entity.zoneId === eventZone;
|
|
55
|
+
const isAdjacent = layer.crossZone === true && isAdjacentZone(entity.zoneId, eventZone, world);
|
|
56
|
+
if (!isInZone && !isAdjacent)
|
|
57
|
+
continue;
|
|
58
|
+
// Determine the stat for this sense
|
|
59
|
+
const stat = senseStats[layer.sense] ?? defaultStat;
|
|
60
|
+
// Run perception check
|
|
61
|
+
const difficulty = layer.baseDifficulty + (isAdjacent ? 15 : 0);
|
|
62
|
+
const targetEntity = actorId ? world.entities[actorId] : undefined;
|
|
63
|
+
const result = runPerceptionCheck(entity, targetEntity, world, stat, difficulty, layer.sense);
|
|
64
|
+
// Calculate clarity
|
|
65
|
+
let clarity;
|
|
66
|
+
if (result.detected) {
|
|
67
|
+
const margin = result.roll - result.threshold;
|
|
68
|
+
clarity = Math.min(1, 0.5 + margin / 30);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
const deficit = result.threshold - result.roll;
|
|
72
|
+
clarity = Math.max(0, 0.4 - deficit / 20);
|
|
73
|
+
}
|
|
74
|
+
// Record perception
|
|
75
|
+
const perceived = {
|
|
76
|
+
eventId: event.id,
|
|
77
|
+
entityId: entity.id,
|
|
78
|
+
tick: event.tick,
|
|
79
|
+
detected: result.detected,
|
|
80
|
+
clarity,
|
|
81
|
+
sense: layer.sense,
|
|
82
|
+
interpretation: result.detected
|
|
83
|
+
? (clarity > 0.7 ? 'full' : 'partial')
|
|
84
|
+
: (clarity > 0.15 ? 'partial' : 'none'),
|
|
85
|
+
};
|
|
86
|
+
logPerception(world, perceived);
|
|
87
|
+
// Apply perception results
|
|
88
|
+
if (result.detected) {
|
|
89
|
+
layer.onPerceived(event, entity, clarity, world);
|
|
90
|
+
}
|
|
91
|
+
else if (clarity > 0.15 && layer.onPartial) {
|
|
92
|
+
layer.onPartial(event, entity, clarity, world);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// --- Built-in Layers ---
|
|
98
|
+
function getBuiltinLayers() {
|
|
99
|
+
return [
|
|
100
|
+
// Visual: zone entry
|
|
101
|
+
{
|
|
102
|
+
id: 'visual-movement',
|
|
103
|
+
eventPatterns: ['world.zone.entered'],
|
|
104
|
+
sense: 'sight',
|
|
105
|
+
baseDifficulty: 30,
|
|
106
|
+
crossZone: false,
|
|
107
|
+
onPerceived(event, entity, clarity, world) {
|
|
108
|
+
const cog = getCognition(world, entity.id);
|
|
109
|
+
const actorId = event.actorId;
|
|
110
|
+
const zoneId = event.payload.zoneId;
|
|
111
|
+
setBelief(cog, actorId, 'present', true, clarity, 'observed', event.tick);
|
|
112
|
+
setBelief(cog, actorId, 'location', zoneId, clarity, 'observed', event.tick);
|
|
113
|
+
addMemory(cog, 'saw-entity', event.tick, { entityId: actorId, zoneId: zoneId }, actorId, zoneId);
|
|
114
|
+
},
|
|
115
|
+
onPartial(event, entity, clarity, world) {
|
|
116
|
+
const cog = getCognition(world, entity.id);
|
|
117
|
+
// Sensed something but didn't see who
|
|
118
|
+
addMemory(cog, 'sensed-presence', event.tick, {
|
|
119
|
+
zoneId: event.payload.zoneId,
|
|
120
|
+
certainty: clarity,
|
|
121
|
+
});
|
|
122
|
+
cog.suspicion = Math.min(100, cog.suspicion + Math.round(20 * clarity));
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
// Visual: combat events (same zone)
|
|
126
|
+
{
|
|
127
|
+
id: 'visual-combat',
|
|
128
|
+
eventPatterns: ['combat.contact.hit', 'combat.contact.miss'],
|
|
129
|
+
sense: 'sight',
|
|
130
|
+
baseDifficulty: 20, // Combat is loud and visible
|
|
131
|
+
crossZone: false,
|
|
132
|
+
onPerceived(event, entity, clarity, world) {
|
|
133
|
+
const cog = getCognition(world, entity.id);
|
|
134
|
+
const attackerId = event.payload.attackerId;
|
|
135
|
+
const targetId = event.payload.targetId;
|
|
136
|
+
if (clarity > 0.5) {
|
|
137
|
+
// High clarity: know exactly who is hostile
|
|
138
|
+
setBelief(cog, attackerId, 'hostile', true, clarity * 0.8, 'observed', event.tick);
|
|
139
|
+
addMemory(cog, 'saw-combat', event.tick, { attackerId: attackerId, targetId: targetId }, undefined, entity.zoneId);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
// Low clarity: know there's danger but not who
|
|
143
|
+
addMemory(cog, 'sensed-danger', event.tick, { certainty: clarity }, undefined, entity.zoneId);
|
|
144
|
+
}
|
|
145
|
+
cog.suspicion = Math.min(100, cog.suspicion + Math.round(25 * clarity));
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
// Auditory: combat sounds carry to adjacent zones
|
|
149
|
+
{
|
|
150
|
+
id: 'auditory-combat',
|
|
151
|
+
eventPatterns: ['combat.contact.hit', 'combat.contact.miss'],
|
|
152
|
+
sense: 'hearing',
|
|
153
|
+
baseDifficulty: 25,
|
|
154
|
+
crossZone: true,
|
|
155
|
+
onPerceived(event, entity, clarity, world) {
|
|
156
|
+
const cog = getCognition(world, entity.id);
|
|
157
|
+
const sourceZone = getEventZone(event, world);
|
|
158
|
+
addMemory(cog, 'heard-combat', event.tick, {
|
|
159
|
+
direction: (sourceZone ?? 'unknown'),
|
|
160
|
+
certainty: clarity,
|
|
161
|
+
}, undefined, entity.zoneId);
|
|
162
|
+
cog.suspicion = Math.min(100, cog.suspicion + Math.round(15 * clarity));
|
|
163
|
+
},
|
|
164
|
+
onPartial(event, entity, clarity, world) {
|
|
165
|
+
const cog = getCognition(world, entity.id);
|
|
166
|
+
addMemory(cog, 'heard-noise', event.tick, { certainty: clarity });
|
|
167
|
+
cog.suspicion = Math.min(100, cog.suspicion + 5);
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
// Visual: entity defeat
|
|
171
|
+
{
|
|
172
|
+
id: 'visual-defeat',
|
|
173
|
+
eventPatterns: ['combat.entity.defeated'],
|
|
174
|
+
sense: 'sight',
|
|
175
|
+
baseDifficulty: 15, // Very noticeable
|
|
176
|
+
crossZone: false,
|
|
177
|
+
onPerceived(event, entity, clarity, world) {
|
|
178
|
+
const cog = getCognition(world, entity.id);
|
|
179
|
+
const defeatedId = event.payload.entityId;
|
|
180
|
+
setBelief(cog, defeatedId, 'alive', false, clarity, 'observed', event.tick);
|
|
181
|
+
addMemory(cog, 'saw-defeat', event.tick, { entityId: defeatedId }, defeatedId, entity.zoneId);
|
|
182
|
+
// Seeing an ally fall tanks morale
|
|
183
|
+
cog.morale = Math.max(0, cog.morale - Math.round(15 * clarity));
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
];
|
|
187
|
+
}
|
|
188
|
+
// --- Perception Check ---
|
|
189
|
+
function runPerceptionCheck(observer, target, world, stat, baseDifficulty, sense) {
|
|
190
|
+
const zone = world.zones[observer.zoneId ?? ''];
|
|
191
|
+
let threshold = baseDifficulty;
|
|
192
|
+
// Light affects visual perception
|
|
193
|
+
if (sense === 'sight') {
|
|
194
|
+
const light = zone?.light ?? 5;
|
|
195
|
+
threshold -= (light - 5) * 2;
|
|
196
|
+
}
|
|
197
|
+
// Ambient noise affects hearing (high noise = harder to pick out sounds)
|
|
198
|
+
if (sense === 'hearing') {
|
|
199
|
+
const noise = zone?.noise ?? 0;
|
|
200
|
+
threshold += noise * 2;
|
|
201
|
+
}
|
|
202
|
+
// Target visibility
|
|
203
|
+
if (target?.visibility?.hidden) {
|
|
204
|
+
threshold += 20;
|
|
205
|
+
}
|
|
206
|
+
const statValue = observer.stats[stat] ?? 5;
|
|
207
|
+
const targetId = target?.id ?? 'env';
|
|
208
|
+
const roll = perceptionRoll(world.meta.tick, observer.id, targetId, sense);
|
|
209
|
+
const score = statValue * 7 + roll;
|
|
210
|
+
return { detected: score >= threshold, roll: score, threshold };
|
|
211
|
+
}
|
|
212
|
+
function perceptionRoll(tick, observerId, targetId, sense) {
|
|
213
|
+
let hash = tick * 2654435761;
|
|
214
|
+
for (const char of observerId + targetId + sense) {
|
|
215
|
+
hash = ((hash << 5) - hash + char.charCodeAt(0)) | 0;
|
|
216
|
+
}
|
|
217
|
+
return (Math.abs(hash) % 50) + 1; // 1-50
|
|
218
|
+
}
|
|
219
|
+
// --- Helpers ---
|
|
220
|
+
function getEventZone(event, world) {
|
|
221
|
+
if (event.payload.zoneId)
|
|
222
|
+
return event.payload.zoneId;
|
|
223
|
+
if (event.actorId)
|
|
224
|
+
return world.entities[event.actorId]?.zoneId;
|
|
225
|
+
if (event.targetIds?.[0])
|
|
226
|
+
return world.entities[event.targetIds[0]]?.zoneId;
|
|
227
|
+
return undefined;
|
|
228
|
+
}
|
|
229
|
+
function isAdjacentZone(entityZoneId, eventZoneId, world) {
|
|
230
|
+
if (!entityZoneId)
|
|
231
|
+
return false;
|
|
232
|
+
const zone = world.zones[entityZoneId];
|
|
233
|
+
return zone?.neighbors.includes(eventZoneId) ?? false;
|
|
234
|
+
}
|
|
235
|
+
function matchEventPattern(eventType, pattern) {
|
|
236
|
+
if (pattern === '*')
|
|
237
|
+
return true;
|
|
238
|
+
if (pattern.endsWith('.*')) {
|
|
239
|
+
return eventType.startsWith(pattern.slice(0, -2) + '.');
|
|
240
|
+
}
|
|
241
|
+
return eventType === pattern;
|
|
242
|
+
}
|
|
243
|
+
function logPerception(world, perceived) {
|
|
244
|
+
const mod = world.modules['perception-filter'];
|
|
245
|
+
if (!mod)
|
|
246
|
+
return;
|
|
247
|
+
if (!mod.perceptionLog[perceived.entityId]) {
|
|
248
|
+
mod.perceptionLog[perceived.entityId] = [];
|
|
249
|
+
}
|
|
250
|
+
mod.perceptionLog[perceived.entityId].push(perceived);
|
|
251
|
+
}
|
|
252
|
+
// --- Query API ---
|
|
253
|
+
/** Get all perception log entries for an entity */
|
|
254
|
+
export function getPerceptionLog(world, entityId) {
|
|
255
|
+
const mod = world.modules['perception-filter'];
|
|
256
|
+
return mod?.perceptionLog[entityId] ?? [];
|
|
257
|
+
}
|
|
258
|
+
/** Get recent perceptions within a tick window */
|
|
259
|
+
export function getRecentPerceptions(world, entityId, withinTicks) {
|
|
260
|
+
const log = getPerceptionLog(world, entityId);
|
|
261
|
+
const currentTick = world.meta.tick;
|
|
262
|
+
return log.filter((p) => currentTick - p.tick <= withinTicks);
|
|
263
|
+
}
|
|
264
|
+
/** Check if an entity perceived a specific event */
|
|
265
|
+
export function didPerceive(world, entityId, eventId) {
|
|
266
|
+
return getPerceptionLog(world, entityId).find((p) => p.eventId === eventId);
|
|
267
|
+
}
|
|
268
|
+
/** Get all entities that perceived a specific event */
|
|
269
|
+
export function whoPerceived(world, eventId) {
|
|
270
|
+
const mod = world.modules['perception-filter'];
|
|
271
|
+
if (!mod)
|
|
272
|
+
return [];
|
|
273
|
+
const results = [];
|
|
274
|
+
for (const entries of Object.values(mod.perceptionLog)) {
|
|
275
|
+
const match = entries.find((p) => p.eventId === eventId);
|
|
276
|
+
if (match)
|
|
277
|
+
results.push(match);
|
|
278
|
+
}
|
|
279
|
+
return results;
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=perception-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perception-filter.js","sourceRoot":"","sources":["../src/perception-filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perception-filter.test.d.ts","sourceRoot":"","sources":["../src/perception-filter.test.ts"],"names":[],"mappings":""}
|