@holoscript/core 2.0.0 → 2.0.2
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/dist/chunk-3N67RLQP.cjs +1298 -0
- package/dist/chunk-3N67RLQP.cjs.map +1 -0
- package/dist/chunk-3X2EGU7Z.cjs +52 -0
- package/dist/chunk-3X2EGU7Z.cjs.map +1 -0
- package/dist/chunk-4CV4JOE5.js +24 -0
- package/dist/chunk-4CV4JOE5.js.map +1 -0
- package/dist/chunk-4OHVW4XR.cjs +1027 -0
- package/dist/chunk-4OHVW4XR.cjs.map +1 -0
- package/dist/chunk-CZLDE2OZ.cjs +28 -0
- package/dist/chunk-CZLDE2OZ.cjs.map +1 -0
- package/{src/HoloScriptRuntime.ts → dist/chunk-EU6CZMGJ.js} +437 -794
- package/dist/chunk-EU6CZMGJ.js.map +1 -0
- package/dist/chunk-KWYIVRIH.js +344 -0
- package/dist/chunk-KWYIVRIH.js.map +1 -0
- package/dist/chunk-MCP6D4LT.js +1025 -0
- package/dist/chunk-MCP6D4LT.js.map +1 -0
- package/dist/chunk-SATNCODL.js +45 -0
- package/dist/chunk-SATNCODL.js.map +1 -0
- package/dist/chunk-VMZN4EVR.cjs +347 -0
- package/dist/chunk-VMZN4EVR.cjs.map +1 -0
- package/{src/HoloScriptDebugger.ts → dist/chunk-VYIDLUCV.js} +118 -257
- package/dist/chunk-VYIDLUCV.js.map +1 -0
- package/dist/chunk-WFI4T3XB.cjs +424 -0
- package/dist/chunk-WFI4T3XB.cjs.map +1 -0
- package/dist/debugger.cjs +20 -0
- package/dist/debugger.cjs.map +1 -0
- package/dist/debugger.d.cts +171 -0
- package/dist/debugger.d.ts +171 -0
- package/dist/debugger.js +7 -0
- package/dist/debugger.js.map +1 -0
- package/dist/index.cjs +6006 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2482 -0
- package/dist/index.d.ts +2482 -0
- package/dist/index.js +5926 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.cjs +14 -0
- package/dist/parser.cjs.map +1 -0
- package/dist/parser.d.cts +139 -0
- package/dist/parser.d.ts +139 -0
- package/dist/parser.js +5 -0
- package/dist/parser.js.map +1 -0
- package/dist/runtime.cjs +14 -0
- package/dist/runtime.cjs.map +1 -0
- package/dist/runtime.d.cts +180 -0
- package/dist/runtime.d.ts +180 -0
- package/dist/runtime.js +5 -0
- package/dist/runtime.js.map +1 -0
- package/dist/type-checker.cjs +17 -0
- package/dist/type-checker.cjs.map +1 -0
- package/dist/type-checker.d.cts +105 -0
- package/dist/type-checker.d.ts +105 -0
- package/dist/type-checker.js +4 -0
- package/dist/type-checker.js.map +1 -0
- package/dist/types-D6g4ACjP.d.cts +262 -0
- package/dist/types-D6g4ACjP.d.ts +262 -0
- package/package.json +11 -8
- package/src/HoloScript2DParser.js +0 -227
- package/src/HoloScript2DParser.ts +0 -261
- package/src/HoloScriptCodeParser.js +0 -1102
- package/src/HoloScriptCodeParser.ts +0 -1188
- package/src/HoloScriptDebugger.js +0 -458
- package/src/HoloScriptParser.js +0 -338
- package/src/HoloScriptParser.ts +0 -397
- package/src/HoloScriptPlusParser.js +0 -371
- package/src/HoloScriptPlusParser.ts +0 -543
- package/src/HoloScriptRuntime.js +0 -1399
- package/src/HoloScriptRuntime.test.js +0 -351
- package/src/HoloScriptRuntime.test.ts +0 -436
- package/src/HoloScriptTypeChecker.js +0 -356
- package/src/HoloScriptTypeChecker.ts +0 -475
- package/src/__tests__/GraphicsServices.test.js +0 -357
- package/src/__tests__/GraphicsServices.test.ts +0 -427
- package/src/__tests__/HoloScriptPlusParser.test.js +0 -317
- package/src/__tests__/HoloScriptPlusParser.test.ts +0 -392
- package/src/__tests__/integration.test.js +0 -336
- package/src/__tests__/integration.test.ts +0 -416
- package/src/__tests__/performance.bench.js +0 -218
- package/src/__tests__/performance.bench.ts +0 -262
- package/src/__tests__/type-checker.test.js +0 -60
- package/src/__tests__/type-checker.test.ts +0 -73
- package/src/index.js +0 -217
- package/src/index.ts +0 -426
- package/src/interop/Interoperability.js +0 -413
- package/src/interop/Interoperability.ts +0 -494
- package/src/logger.js +0 -42
- package/src/logger.ts +0 -57
- package/src/parser/EnhancedParser.js +0 -205
- package/src/parser/EnhancedParser.ts +0 -251
- package/src/parser/HoloScriptPlusParser.js +0 -928
- package/src/parser/HoloScriptPlusParser.ts +0 -1089
- package/src/runtime/HoloScriptPlusRuntime.js +0 -674
- package/src/runtime/HoloScriptPlusRuntime.ts +0 -861
- package/src/runtime/PerformanceTelemetry.js +0 -323
- package/src/runtime/PerformanceTelemetry.ts +0 -467
- package/src/runtime/RuntimeOptimization.js +0 -361
- package/src/runtime/RuntimeOptimization.ts +0 -416
- package/src/services/HololandGraphicsPipelineService.js +0 -506
- package/src/services/HololandGraphicsPipelineService.ts +0 -662
- package/src/services/PlatformPerformanceOptimizer.js +0 -356
- package/src/services/PlatformPerformanceOptimizer.ts +0 -503
- package/src/state/ReactiveState.js +0 -427
- package/src/state/ReactiveState.ts +0 -572
- package/src/tools/DeveloperExperience.js +0 -376
- package/src/tools/DeveloperExperience.ts +0 -438
- package/src/traits/AIDriverTrait.js +0 -322
- package/src/traits/AIDriverTrait.test.js +0 -329
- package/src/traits/AIDriverTrait.test.ts +0 -357
- package/src/traits/AIDriverTrait.ts +0 -474
- package/src/traits/LightingTrait.js +0 -313
- package/src/traits/LightingTrait.test.js +0 -410
- package/src/traits/LightingTrait.test.ts +0 -462
- package/src/traits/LightingTrait.ts +0 -505
- package/src/traits/MaterialTrait.js +0 -194
- package/src/traits/MaterialTrait.test.js +0 -286
- package/src/traits/MaterialTrait.test.ts +0 -329
- package/src/traits/MaterialTrait.ts +0 -324
- package/src/traits/RenderingTrait.js +0 -356
- package/src/traits/RenderingTrait.test.js +0 -363
- package/src/traits/RenderingTrait.test.ts +0 -427
- package/src/traits/RenderingTrait.ts +0 -555
- package/src/traits/VRTraitSystem.js +0 -740
- package/src/traits/VRTraitSystem.ts +0 -1040
- package/src/traits/VoiceInputTrait.js +0 -284
- package/src/traits/VoiceInputTrait.test.js +0 -226
- package/src/traits/VoiceInputTrait.test.ts +0 -252
- package/src/traits/VoiceInputTrait.ts +0 -401
- package/src/types/AdvancedTypeSystem.js +0 -226
- package/src/types/AdvancedTypeSystem.ts +0 -494
- package/src/types/HoloScriptPlus.d.ts +0 -853
- package/src/types.js +0 -6
- package/src/types.ts +0 -369
- package/tsconfig.json +0 -23
- package/tsup.config.d.ts +0 -2
- package/tsup.config.js +0 -18
- package/tsup.config.ts +0 -19
|
@@ -1,474 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @holoscript/core AI-Driven NPC Trait
|
|
3
|
-
*
|
|
4
|
-
* Enables intelligent NPC behaviors using behavior trees and goal planning
|
|
5
|
-
* Integrates with Infinity Assistant service for agent-based decision making
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export type BehaviorState = 'idle' | 'moving' | 'acting' | 'talking' | 'reacting';
|
|
9
|
-
export type DecisionMode = 'reactive' | 'goal-driven' | 'learning' | 'hybrid';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Behavior tree node
|
|
13
|
-
*/
|
|
14
|
-
export interface BehaviorNode {
|
|
15
|
-
id: string;
|
|
16
|
-
type: 'sequence' | 'selector' | 'parallel' | 'action' | 'condition';
|
|
17
|
-
children?: BehaviorNode[];
|
|
18
|
-
action?: (context: NPCContext) => Promise<boolean>;
|
|
19
|
-
condition?: (context: NPCContext) => boolean;
|
|
20
|
-
metadata?: Record<string, unknown>;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* NPC Context for behavior execution
|
|
25
|
-
*/
|
|
26
|
-
export interface NPCContext {
|
|
27
|
-
npcId: string;
|
|
28
|
-
position: [number, number, number];
|
|
29
|
-
rotation: [number, number, number];
|
|
30
|
-
targetId?: string;
|
|
31
|
-
targetPosition?: [number, number, number];
|
|
32
|
-
memory: Map<string, unknown>;
|
|
33
|
-
state: BehaviorState;
|
|
34
|
-
energy: number; // 0-1
|
|
35
|
-
mood: number; // -1 to 1 (negative = sad, positive = happy)
|
|
36
|
-
perception: {
|
|
37
|
-
nearbyEntities: string[];
|
|
38
|
-
visibleEntities: string[];
|
|
39
|
-
hearableVoice?: string;
|
|
40
|
-
};
|
|
41
|
-
dialogue?: {
|
|
42
|
-
lastSaid?: string;
|
|
43
|
-
lastHeard?: string;
|
|
44
|
-
conversationHistory: Array<{ speaker: string; text: string }>;
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Goal for GOAP-style planning
|
|
50
|
-
*/
|
|
51
|
-
export interface NPCGoal {
|
|
52
|
-
id: string;
|
|
53
|
-
name: string;
|
|
54
|
-
priority: number; // 0-1
|
|
55
|
-
preconditions: Map<string, unknown>;
|
|
56
|
-
effects: Map<string, unknown>;
|
|
57
|
-
cost: number;
|
|
58
|
-
timeoutMs?: number;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* AI-Driven NPC configuration
|
|
63
|
-
*/
|
|
64
|
-
export interface AIDriverConfig {
|
|
65
|
-
/** NPC identifier */
|
|
66
|
-
npcId: string;
|
|
67
|
-
|
|
68
|
-
/** Decision making mode */
|
|
69
|
-
decisionMode: DecisionMode;
|
|
70
|
-
|
|
71
|
-
/** Base behavior tree */
|
|
72
|
-
behaviorTree?: BehaviorNode;
|
|
73
|
-
|
|
74
|
-
/** Available goals */
|
|
75
|
-
goals?: NPCGoal[];
|
|
76
|
-
|
|
77
|
-
/** Personality traits */
|
|
78
|
-
personality?: {
|
|
79
|
-
sociability: number; // 0-1
|
|
80
|
-
aggression: number; // 0-1
|
|
81
|
-
curiosity: number; // 0-1
|
|
82
|
-
loyalty: number; // 0-1
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
/** Response to stimuli */
|
|
86
|
-
stimuliThresholds?: {
|
|
87
|
-
hearing: number; // perception distance
|
|
88
|
-
sight: number; // vision distance
|
|
89
|
-
touch: number; // collision distance
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
/** Learning config */
|
|
93
|
-
enableLearning?: boolean;
|
|
94
|
-
learningRate?: number;
|
|
95
|
-
|
|
96
|
-
/** Infinity Assistant integration */
|
|
97
|
-
agentId?: string;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Behavior tree runner
|
|
102
|
-
*/
|
|
103
|
-
export class BehaviorTreeRunner {
|
|
104
|
-
private rootNode: BehaviorNode;
|
|
105
|
-
|
|
106
|
-
constructor(rootNode: BehaviorNode) {
|
|
107
|
-
this.rootNode = rootNode;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
async tick(context: NPCContext): Promise<boolean> {
|
|
111
|
-
return this.executeNode(this.rootNode, context);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
private async executeNode(
|
|
115
|
-
node: BehaviorNode,
|
|
116
|
-
context: NPCContext
|
|
117
|
-
): Promise<boolean> {
|
|
118
|
-
if (node.type === 'action') {
|
|
119
|
-
if (node.action) {
|
|
120
|
-
try {
|
|
121
|
-
return await node.action(context);
|
|
122
|
-
} catch (error) {
|
|
123
|
-
console.error(`Action failed: ${node.id}`, error);
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return true;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (node.type === 'condition') {
|
|
131
|
-
return node.condition ? node.condition(context) : true;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (node.type === 'sequence') {
|
|
135
|
-
for (const child of node.children || []) {
|
|
136
|
-
const result = await this.executeNode(child, context);
|
|
137
|
-
if (!result) return false;
|
|
138
|
-
}
|
|
139
|
-
return true;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (node.type === 'selector') {
|
|
143
|
-
for (const child of node.children || []) {
|
|
144
|
-
const result = await this.executeNode(child, context);
|
|
145
|
-
if (result) return true;
|
|
146
|
-
}
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (node.type === 'parallel') {
|
|
151
|
-
const results = await Promise.all(
|
|
152
|
-
(node.children || []).map((child) => this.executeNode(child, context))
|
|
153
|
-
);
|
|
154
|
-
return results.every((r) => r);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return true;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Goal-Oriented Action Planning (GOAP)
|
|
163
|
-
*/
|
|
164
|
-
export class GOAPPlanner {
|
|
165
|
-
private goals: NPCGoal[];
|
|
166
|
-
|
|
167
|
-
constructor(goals: NPCGoal[]) {
|
|
168
|
-
this.goals = goals.sort((a, b) => b.priority - a.priority);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Plan a sequence of actions to reach goal
|
|
173
|
-
*/
|
|
174
|
-
planGoal(currentState: Map<string, unknown>, _goal: NPCGoal): NPCGoal[] {
|
|
175
|
-
// Simple greedy planner: select highest-priority achievable goal
|
|
176
|
-
for (const g of this.goals) {
|
|
177
|
-
if (this.canAchieve(currentState, g)) {
|
|
178
|
-
return [g];
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
return [];
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
private canAchieve(
|
|
185
|
-
currentState: Map<string, unknown>,
|
|
186
|
-
goal: NPCGoal
|
|
187
|
-
): boolean {
|
|
188
|
-
for (const [key, value] of goal.preconditions) {
|
|
189
|
-
if (currentState.get(key) !== value) {
|
|
190
|
-
return false;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return true;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* AIDriverTrait - Enables intelligent NPC behaviors
|
|
199
|
-
*/
|
|
200
|
-
export class AIDriverTrait {
|
|
201
|
-
private config: AIDriverConfig;
|
|
202
|
-
private context: NPCContext;
|
|
203
|
-
private behaviorRunner: BehaviorTreeRunner | null = null;
|
|
204
|
-
private goapPlanner: GOAPPlanner | null = null;
|
|
205
|
-
private updateInterval: ReturnType<typeof setInterval> | null = null;
|
|
206
|
-
private learningModel: Map<string, number> = new Map();
|
|
207
|
-
|
|
208
|
-
constructor(config: AIDriverConfig) {
|
|
209
|
-
const defaults = {
|
|
210
|
-
decisionMode: 'hybrid' as const,
|
|
211
|
-
personality: {
|
|
212
|
-
sociability: 0.5,
|
|
213
|
-
aggression: 0.3,
|
|
214
|
-
curiosity: 0.6,
|
|
215
|
-
loyalty: 0.7,
|
|
216
|
-
},
|
|
217
|
-
stimuliThresholds: {
|
|
218
|
-
hearing: 50,
|
|
219
|
-
sight: 100,
|
|
220
|
-
touch: 5,
|
|
221
|
-
},
|
|
222
|
-
enableLearning: true,
|
|
223
|
-
learningRate: 0.1,
|
|
224
|
-
};
|
|
225
|
-
this.config = { ...defaults, ...config };
|
|
226
|
-
|
|
227
|
-
this.context = {
|
|
228
|
-
npcId: config.npcId,
|
|
229
|
-
position: [0, 0, 0],
|
|
230
|
-
rotation: [0, 0, 0],
|
|
231
|
-
memory: new Map(),
|
|
232
|
-
state: 'idle',
|
|
233
|
-
energy: 1.0,
|
|
234
|
-
mood: 0,
|
|
235
|
-
perception: {
|
|
236
|
-
nearbyEntities: [],
|
|
237
|
-
visibleEntities: [],
|
|
238
|
-
},
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
if (config.behaviorTree) {
|
|
242
|
-
this.behaviorRunner = new BehaviorTreeRunner(config.behaviorTree);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (config.goals && config.goals.length > 0) {
|
|
246
|
-
this.goapPlanner = new GOAPPlanner(config.goals);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Start NPC AI loop
|
|
252
|
-
*/
|
|
253
|
-
public startAI(): void {
|
|
254
|
-
if (this.updateInterval) return;
|
|
255
|
-
|
|
256
|
-
this.updateInterval = setInterval(() => {
|
|
257
|
-
this.tick();
|
|
258
|
-
}, 100); // 10 Hz update rate
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Stop NPC AI loop
|
|
263
|
-
*/
|
|
264
|
-
public stopAI(): void {
|
|
265
|
-
if (this.updateInterval) {
|
|
266
|
-
clearInterval(this.updateInterval);
|
|
267
|
-
this.updateInterval = null;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Main AI tick
|
|
273
|
-
*/
|
|
274
|
-
private async tick(): Promise<void> {
|
|
275
|
-
// Update energy (decreases over time)
|
|
276
|
-
this.context.energy = Math.max(0, this.context.energy - 0.001);
|
|
277
|
-
|
|
278
|
-
// Stress/mood changes
|
|
279
|
-
if (this.context.perception.visibleEntities.length > 0) {
|
|
280
|
-
this.context.mood += 0.1 * (Math.random() - 0.5);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// Execute appropriate decision mode
|
|
284
|
-
switch (this.config.decisionMode) {
|
|
285
|
-
case 'reactive':
|
|
286
|
-
await this.reactiveDecision();
|
|
287
|
-
break;
|
|
288
|
-
case 'goal-driven':
|
|
289
|
-
await this.goalDrivenDecision();
|
|
290
|
-
break;
|
|
291
|
-
case 'learning':
|
|
292
|
-
await this.learningDecision();
|
|
293
|
-
break;
|
|
294
|
-
case 'hybrid':
|
|
295
|
-
await this.hybridDecision();
|
|
296
|
-
break;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* Reactive decision: immediate response to stimuli
|
|
302
|
-
*/
|
|
303
|
-
private async reactiveDecision(): Promise<void> {
|
|
304
|
-
if (this.behaviorRunner) {
|
|
305
|
-
await this.behaviorRunner.tick(this.context);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Goal-driven decision: plan towards objectives
|
|
311
|
-
*/
|
|
312
|
-
private async goalDrivenDecision(): Promise<void> {
|
|
313
|
-
if (!this.goapPlanner) return;
|
|
314
|
-
|
|
315
|
-
const worldState = this.buildWorldState();
|
|
316
|
-
// Select highest priority goal
|
|
317
|
-
const plan = this.goapPlanner.planGoal(
|
|
318
|
-
worldState,
|
|
319
|
-
this.config.goals?.[0] || { id: 'idle', name: 'Idle', priority: 0, preconditions: new Map(), effects: new Map(), cost: 0 }
|
|
320
|
-
);
|
|
321
|
-
|
|
322
|
-
if (plan.length > 0) {
|
|
323
|
-
// Execute plan
|
|
324
|
-
this.context.state = 'moving';
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Learning decision: adapt behavior from experience
|
|
330
|
-
*/
|
|
331
|
-
private async learningDecision(): Promise<void> {
|
|
332
|
-
// Composite reactive + learning
|
|
333
|
-
await this.reactiveDecision();
|
|
334
|
-
|
|
335
|
-
// Learn from interactions
|
|
336
|
-
if (this.config.enableLearning) {
|
|
337
|
-
this.updateLearningModel();
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* Hybrid decision: combination of reactive and goal-driven
|
|
343
|
-
*/
|
|
344
|
-
private async hybridDecision(): Promise<void> {
|
|
345
|
-
// Execute behavior tree (reactive)
|
|
346
|
-
if (this.behaviorRunner) {
|
|
347
|
-
const treeResult = await this.behaviorRunner.tick(this.context);
|
|
348
|
-
|
|
349
|
-
// If no immediate action, pursue goals
|
|
350
|
-
if (!treeResult && this.goapPlanner) {
|
|
351
|
-
await this.goalDrivenDecision();
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Build world state for planning
|
|
358
|
-
*/
|
|
359
|
-
private buildWorldState(): Map<string, unknown> {
|
|
360
|
-
const state = new Map<string, unknown>();
|
|
361
|
-
state.set('position', this.context.position);
|
|
362
|
-
state.set('energy', this.context.energy);
|
|
363
|
-
state.set('mood', this.context.mood);
|
|
364
|
-
state.set('nearbyEntities', this.context.perception.nearbyEntities.length);
|
|
365
|
-
return state;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Update learning model from interactions
|
|
370
|
-
*/
|
|
371
|
-
private updateLearningModel(): void {
|
|
372
|
-
// Simple Q-learning-like update
|
|
373
|
-
const currentReward = this.calculateReward();
|
|
374
|
-
const learningRate = this.config.learningRate || 0.1;
|
|
375
|
-
|
|
376
|
-
// Update learned value estimates
|
|
377
|
-
const stateKey = `state_${this.context.state}`;
|
|
378
|
-
const currentValue = this.learningModel.get(stateKey) || 0;
|
|
379
|
-
const newValue = currentValue + learningRate * (currentReward - currentValue);
|
|
380
|
-
this.learningModel.set(stateKey, newValue);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
* Calculate immediate reward
|
|
385
|
-
*/
|
|
386
|
-
private calculateReward(): number {
|
|
387
|
-
let reward = 0;
|
|
388
|
-
|
|
389
|
-
// Reward based on energy maintenance
|
|
390
|
-
if (this.context.energy > 0.5) reward += 1;
|
|
391
|
-
|
|
392
|
-
// Reward based on social interaction (if sociable)
|
|
393
|
-
if (
|
|
394
|
-
this.config.personality?.sociability || 0 > 0.5 &&
|
|
395
|
-
this.context.perception.nearbyEntities.length > 0
|
|
396
|
-
) {
|
|
397
|
-
reward += 1;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// Reward based on goal progress
|
|
401
|
-
if (this.context.state !== 'idle') reward += 0.5;
|
|
402
|
-
|
|
403
|
-
return reward;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* Set NPC position
|
|
408
|
-
*/
|
|
409
|
-
public setPosition(position: [number, number, number]): void {
|
|
410
|
-
this.context.position = position;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
* Update perception (nearby entities, visible targets)
|
|
415
|
-
*/
|
|
416
|
-
public updatePerception(
|
|
417
|
-
nearbyEntities: string[],
|
|
418
|
-
visibleEntities: string[]
|
|
419
|
-
): void {
|
|
420
|
-
this.context.perception.nearbyEntities = nearbyEntities;
|
|
421
|
-
this.context.perception.visibleEntities = visibleEntities;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
/**
|
|
425
|
-
* Add dialogue to conversation history
|
|
426
|
-
*/
|
|
427
|
-
public speak(text: string): void {
|
|
428
|
-
if (!this.context.dialogue) {
|
|
429
|
-
this.context.dialogue = { conversationHistory: [] };
|
|
430
|
-
}
|
|
431
|
-
this.context.dialogue.lastSaid = text;
|
|
432
|
-
this.context.dialogue.conversationHistory.push({
|
|
433
|
-
speaker: this.config.npcId,
|
|
434
|
-
text,
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
/**
|
|
439
|
-
* Receive dialogue from another entity
|
|
440
|
-
*/
|
|
441
|
-
public hear(speaker: string, text: string): void {
|
|
442
|
-
if (!this.context.dialogue) {
|
|
443
|
-
this.context.dialogue = { conversationHistory: [] };
|
|
444
|
-
}
|
|
445
|
-
this.context.dialogue.lastHeard = text;
|
|
446
|
-
this.context.dialogue.conversationHistory.push({
|
|
447
|
-
speaker,
|
|
448
|
-
text,
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Get current NPC context
|
|
454
|
-
*/
|
|
455
|
-
public getContext(): Readonly<NPCContext> {
|
|
456
|
-
return { ...this.context };
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
/**
|
|
460
|
-
* Dispose and cleanup
|
|
461
|
-
*/
|
|
462
|
-
public dispose(): void {
|
|
463
|
-
this.stopAI();
|
|
464
|
-
this.context.memory.clear();
|
|
465
|
-
this.learningModel.clear();
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* HoloScript+ @ai_driven trait factory
|
|
471
|
-
*/
|
|
472
|
-
export function createAIDriverTrait(config: AIDriverConfig): AIDriverTrait {
|
|
473
|
-
return new AIDriverTrait(config);
|
|
474
|
-
}
|