@sharpee/engine 0.9.60-beta
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 +328 -0
- package/dist/action-context-factory.d.ts +11 -0
- package/dist/action-context-factory.d.ts.map +1 -0
- package/dist/action-context-factory.js +258 -0
- package/dist/action-context-factory.js.map +1 -0
- package/dist/capability-dispatch-helper.d.ts +106 -0
- package/dist/capability-dispatch-helper.d.ts.map +1 -0
- package/dist/capability-dispatch-helper.js +269 -0
- package/dist/capability-dispatch-helper.js.map +1 -0
- package/dist/command-executor.d.ts +53 -0
- package/dist/command-executor.d.ts.map +1 -0
- package/dist/command-executor.js +329 -0
- package/dist/command-executor.js.map +1 -0
- package/dist/event-adapter.d.ts +44 -0
- package/dist/event-adapter.d.ts.map +1 -0
- package/dist/event-adapter.js +127 -0
- package/dist/event-adapter.js.map +1 -0
- package/dist/event-sequencer.d.ts +73 -0
- package/dist/event-sequencer.d.ts.map +1 -0
- package/dist/event-sequencer.js +134 -0
- package/dist/event-sequencer.js.map +1 -0
- package/dist/events/event-emitter.d.ts +34 -0
- package/dist/events/event-emitter.d.ts.map +1 -0
- package/dist/events/event-emitter.js +67 -0
- package/dist/events/event-emitter.js.map +1 -0
- package/dist/game-engine.d.ts +292 -0
- package/dist/game-engine.d.ts.map +1 -0
- package/dist/game-engine.js +1631 -0
- package/dist/game-engine.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/narrative/index.d.ts +5 -0
- package/dist/narrative/index.d.ts.map +1 -0
- package/dist/narrative/index.js +10 -0
- package/dist/narrative/index.js.map +1 -0
- package/dist/narrative/narrative-settings.d.ts +73 -0
- package/dist/narrative/narrative-settings.d.ts.map +1 -0
- package/dist/narrative/narrative-settings.js +28 -0
- package/dist/narrative/narrative-settings.js.map +1 -0
- package/dist/parser-interface.d.ts +77 -0
- package/dist/parser-interface.d.ts.map +1 -0
- package/dist/parser-interface.js +48 -0
- package/dist/parser-interface.js.map +1 -0
- package/dist/platform-operations.d.ts +83 -0
- package/dist/platform-operations.d.ts.map +1 -0
- package/dist/platform-operations.js +218 -0
- package/dist/platform-operations.js.map +1 -0
- package/dist/save-restore-service.d.ts +133 -0
- package/dist/save-restore-service.d.ts.map +1 -0
- package/dist/save-restore-service.js +446 -0
- package/dist/save-restore-service.js.map +1 -0
- package/dist/scheduler/index.d.ts +9 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +25 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/scheduler-service.d.ts +75 -0
- package/dist/scheduler/scheduler-service.d.ts.map +1 -0
- package/dist/scheduler/scheduler-service.js +310 -0
- package/dist/scheduler/scheduler-service.js.map +1 -0
- package/dist/scheduler/seeded-random.d.ts +7 -0
- package/dist/scheduler/seeded-random.d.ts.map +1 -0
- package/dist/scheduler/seeded-random.js +11 -0
- package/dist/scheduler/seeded-random.js.map +1 -0
- package/dist/scheduler/types.d.ts +134 -0
- package/dist/scheduler/types.d.ts.map +1 -0
- package/dist/scheduler/types.js +9 -0
- package/dist/scheduler/types.js.map +1 -0
- package/dist/shared-data-keys.d.ts +53 -0
- package/dist/shared-data-keys.d.ts.map +1 -0
- package/dist/shared-data-keys.js +29 -0
- package/dist/shared-data-keys.js.map +1 -0
- package/dist/story.d.ts +211 -0
- package/dist/story.d.ts.map +1 -0
- package/dist/story.js +60 -0
- package/dist/story.js.map +1 -0
- package/dist/test-helpers/mock-text-service.d.ts +11 -0
- package/dist/test-helpers/mock-text-service.d.ts.map +1 -0
- package/dist/test-helpers/mock-text-service.js +47 -0
- package/dist/test-helpers/mock-text-service.js.map +1 -0
- package/dist/turn-event-processor.d.ts +89 -0
- package/dist/turn-event-processor.d.ts.map +1 -0
- package/dist/turn-event-processor.js +144 -0
- package/dist/turn-event-processor.js.map +1 -0
- package/dist/types.d.ts +214 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/vocabulary-manager.d.ts +35 -0
- package/dist/vocabulary-manager.d.ts.map +1 -0
- package/dist/vocabulary-manager.js +74 -0
- package/dist/vocabulary-manager.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Save/Restore Service - Manages game state persistence and undo
|
|
4
|
+
*
|
|
5
|
+
* Extracted from GameEngine as part of Phase 4 remediation.
|
|
6
|
+
* Handles save/restore data creation, undo snapshots, and serialization.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.SaveRestoreService = void 0;
|
|
10
|
+
exports.createSaveRestoreService = createSaveRestoreService;
|
|
11
|
+
const world_model_1 = require("@sharpee/world-model");
|
|
12
|
+
const core_1 = require("@sharpee/core");
|
|
13
|
+
const event_adapter_1 = require("./event-adapter");
|
|
14
|
+
/**
|
|
15
|
+
* Service for managing save/restore and undo functionality
|
|
16
|
+
*/
|
|
17
|
+
class SaveRestoreService {
|
|
18
|
+
// Undo system - circular buffer of world snapshots
|
|
19
|
+
undoSnapshots = [];
|
|
20
|
+
undoSnapshotTurns = [];
|
|
21
|
+
maxUndoSnapshots;
|
|
22
|
+
constructor(config) {
|
|
23
|
+
this.maxUndoSnapshots = config?.maxSnapshots ?? 10;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create an undo snapshot of the current world state
|
|
27
|
+
*/
|
|
28
|
+
createUndoSnapshot(world, currentTurn) {
|
|
29
|
+
if (this.maxUndoSnapshots <= 0)
|
|
30
|
+
return; // Undo disabled
|
|
31
|
+
// Serialize world state
|
|
32
|
+
const snapshot = world.toJSON();
|
|
33
|
+
// Add to circular buffer
|
|
34
|
+
this.undoSnapshots.push(snapshot);
|
|
35
|
+
this.undoSnapshotTurns.push(currentTurn);
|
|
36
|
+
// Trim if over limit
|
|
37
|
+
while (this.undoSnapshots.length > this.maxUndoSnapshots) {
|
|
38
|
+
this.undoSnapshots.shift();
|
|
39
|
+
this.undoSnapshotTurns.shift();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Undo to previous turn
|
|
44
|
+
* @returns The turn number restored to, or null if nothing to undo
|
|
45
|
+
*/
|
|
46
|
+
undo(world) {
|
|
47
|
+
if (this.undoSnapshots.length === 0) {
|
|
48
|
+
return null; // Nothing to undo
|
|
49
|
+
}
|
|
50
|
+
// Pop the most recent snapshot
|
|
51
|
+
const snapshot = this.undoSnapshots.pop();
|
|
52
|
+
const turn = this.undoSnapshotTurns.pop();
|
|
53
|
+
// Restore world state
|
|
54
|
+
world.loadJSON(snapshot);
|
|
55
|
+
return { turn };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check if undo is available
|
|
59
|
+
*/
|
|
60
|
+
canUndo() {
|
|
61
|
+
return this.undoSnapshots.length > 0;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get number of undo levels available
|
|
65
|
+
*/
|
|
66
|
+
getUndoLevels() {
|
|
67
|
+
return this.undoSnapshots.length;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Clear all undo snapshots (e.g., after restore)
|
|
71
|
+
*/
|
|
72
|
+
clearUndoSnapshots() {
|
|
73
|
+
this.undoSnapshots = [];
|
|
74
|
+
this.undoSnapshotTurns = [];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Create save data from current engine state
|
|
78
|
+
*/
|
|
79
|
+
createSaveData(provider) {
|
|
80
|
+
const context = provider.getContext();
|
|
81
|
+
const story = provider.getStory();
|
|
82
|
+
const eventSource = provider.getEventSource();
|
|
83
|
+
const scheduler = provider.getScheduler();
|
|
84
|
+
const world = provider.getWorld();
|
|
85
|
+
const parser = provider.getParser();
|
|
86
|
+
const metadata = {
|
|
87
|
+
storyId: story?.config.id || 'unknown',
|
|
88
|
+
storyVersion: story?.config.version || '0.0.0',
|
|
89
|
+
turnCount: context.currentTurn - 1,
|
|
90
|
+
playTime: Date.now() - context.metadata.started.getTime(),
|
|
91
|
+
description: `Turn ${context.currentTurn - 1}`
|
|
92
|
+
};
|
|
93
|
+
const engineState = {
|
|
94
|
+
eventSource: this.serializeEventSource(eventSource),
|
|
95
|
+
spatialIndex: this.serializeSpatialIndex(world),
|
|
96
|
+
turnHistory: this.serializeTurnHistory(context.history),
|
|
97
|
+
parserState: this.serializeParserState(parser),
|
|
98
|
+
schedulerState: this.serializeSchedulerState(scheduler)
|
|
99
|
+
};
|
|
100
|
+
return {
|
|
101
|
+
version: '1.0.0',
|
|
102
|
+
timestamp: Date.now(),
|
|
103
|
+
metadata,
|
|
104
|
+
engineState,
|
|
105
|
+
storyConfig: {
|
|
106
|
+
id: story?.config.id || 'unknown',
|
|
107
|
+
version: story?.config.version || '0.0.0',
|
|
108
|
+
title: story?.config.title || 'Unknown',
|
|
109
|
+
author: Array.isArray(story?.config.author)
|
|
110
|
+
? story.config.author.join(', ')
|
|
111
|
+
: (story?.config.author || 'Unknown')
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Load save data into engine state
|
|
117
|
+
* @returns New event source with restored events
|
|
118
|
+
*/
|
|
119
|
+
loadSaveData(saveData, provider) {
|
|
120
|
+
const story = provider.getStory();
|
|
121
|
+
// Validate save compatibility
|
|
122
|
+
if (saveData.version !== '1.0.0') {
|
|
123
|
+
throw new Error(`Unsupported save version: ${saveData.version}`);
|
|
124
|
+
}
|
|
125
|
+
if (saveData.storyConfig?.id &&
|
|
126
|
+
story?.config.id &&
|
|
127
|
+
saveData.storyConfig.id !== story.config.id) {
|
|
128
|
+
throw new Error(`Save is for different story: ${saveData.storyConfig.id}`);
|
|
129
|
+
}
|
|
130
|
+
// Restore event source
|
|
131
|
+
const eventSource = this.deserializeEventSource(saveData.engineState.eventSource);
|
|
132
|
+
// Restore spatial index (world state)
|
|
133
|
+
const world = provider.getWorld();
|
|
134
|
+
this.deserializeSpatialIndex(saveData.engineState.spatialIndex, world);
|
|
135
|
+
// Restore scheduler state if present
|
|
136
|
+
if (saveData.engineState.schedulerState) {
|
|
137
|
+
this.deserializeSchedulerState(saveData.engineState.schedulerState, provider.getScheduler());
|
|
138
|
+
}
|
|
139
|
+
// Clear undo snapshots after restore
|
|
140
|
+
this.clearUndoSnapshots();
|
|
141
|
+
return {
|
|
142
|
+
eventSource,
|
|
143
|
+
currentTurn: saveData.metadata.turnCount + 1
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Serialize event source
|
|
148
|
+
*/
|
|
149
|
+
serializeEventSource(eventSource) {
|
|
150
|
+
const events = [];
|
|
151
|
+
for (const event of eventSource.getAllEvents()) {
|
|
152
|
+
events.push({
|
|
153
|
+
id: event.id,
|
|
154
|
+
type: event.type,
|
|
155
|
+
timestamp: event.timestamp || Date.now(),
|
|
156
|
+
data: this.serializeEventData(event.data)
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return events;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Serialize event data, handling functions and special types
|
|
163
|
+
*/
|
|
164
|
+
serializeEventData(data) {
|
|
165
|
+
if (!data || typeof data !== 'object') {
|
|
166
|
+
return (data || {});
|
|
167
|
+
}
|
|
168
|
+
const serialized = {};
|
|
169
|
+
for (const [key, value] of Object.entries(data)) {
|
|
170
|
+
if (typeof value === 'function') {
|
|
171
|
+
// Mark functions for special handling during deserialization
|
|
172
|
+
serialized[key] = { __type: 'function', __marker: '[Function]' };
|
|
173
|
+
}
|
|
174
|
+
else if (value && typeof value === 'object') {
|
|
175
|
+
// Recursively serialize nested objects
|
|
176
|
+
if (Array.isArray(value)) {
|
|
177
|
+
serialized[key] = value.map((item) => typeof item === 'object' ? this.serializeEventData(item) : item);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
serialized[key] = this.serializeEventData(value);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
// Primitive values can be stored directly
|
|
185
|
+
serialized[key] = value;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return serialized;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Deserialize event source
|
|
192
|
+
*/
|
|
193
|
+
deserializeEventSource(events) {
|
|
194
|
+
const eventSource = (0, core_1.createSemanticEventSource)();
|
|
195
|
+
for (const event of events) {
|
|
196
|
+
eventSource.emit({
|
|
197
|
+
id: event.id,
|
|
198
|
+
type: event.type,
|
|
199
|
+
timestamp: event.timestamp,
|
|
200
|
+
data: this.deserializeEventData(event.data),
|
|
201
|
+
entities: {}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return eventSource;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Deserialize event data, handling function markers
|
|
208
|
+
*/
|
|
209
|
+
deserializeEventData(data) {
|
|
210
|
+
if (!data || typeof data !== 'object') {
|
|
211
|
+
return data;
|
|
212
|
+
}
|
|
213
|
+
// Check if this is a function marker
|
|
214
|
+
if (data.__type === 'function') {
|
|
215
|
+
// Return a placeholder function
|
|
216
|
+
return () => '[Serialized Function]';
|
|
217
|
+
}
|
|
218
|
+
if (Array.isArray(data)) {
|
|
219
|
+
return data.map((item) => this.deserializeEventData(item));
|
|
220
|
+
}
|
|
221
|
+
const deserialized = {};
|
|
222
|
+
for (const [key, value] of Object.entries(data)) {
|
|
223
|
+
deserialized[key] = this.deserializeEventData(value);
|
|
224
|
+
}
|
|
225
|
+
return deserialized;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Serialize spatial index (world state)
|
|
229
|
+
*/
|
|
230
|
+
serializeSpatialIndex(world) {
|
|
231
|
+
const entities = {};
|
|
232
|
+
const locations = {};
|
|
233
|
+
const relationships = {};
|
|
234
|
+
// Serialize all entities
|
|
235
|
+
for (const entity of world.getAllEntities()) {
|
|
236
|
+
const traits = {};
|
|
237
|
+
// Serialize each trait
|
|
238
|
+
for (const [name, trait] of entity.traits) {
|
|
239
|
+
traits[name] = this.serializeTrait(trait);
|
|
240
|
+
}
|
|
241
|
+
entities[entity.id] = {
|
|
242
|
+
id: entity.id,
|
|
243
|
+
traits,
|
|
244
|
+
entityType: entity.constructor.name
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
// Serialize locations and their contents
|
|
248
|
+
const allLocations = world.getAllEntities().filter((e) => e.type === 'room' || e.type === 'location' || e.has('if.trait.room'));
|
|
249
|
+
for (const location of allLocations) {
|
|
250
|
+
const contents = world.getContents(location.id);
|
|
251
|
+
locations[location.id] = {
|
|
252
|
+
id: location.id,
|
|
253
|
+
properties: {
|
|
254
|
+
name: location.get(world_model_1.TraitType.IDENTITY)?.name || 'Unknown',
|
|
255
|
+
description: location.get(world_model_1.TraitType.IDENTITY)?.description || ''
|
|
256
|
+
},
|
|
257
|
+
contents: contents.map((e) => e.id),
|
|
258
|
+
connections: this.extractConnections(location, world)
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
return { entities, locations, relationships };
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Deserialize spatial index
|
|
265
|
+
*/
|
|
266
|
+
deserializeSpatialIndex(index, world) {
|
|
267
|
+
// Note: Full deserialization would need to clear and recreate the world
|
|
268
|
+
// For now, this restores entity traits and locations
|
|
269
|
+
// Restore entity traits
|
|
270
|
+
for (const [id, data] of Object.entries(index.entities)) {
|
|
271
|
+
const entity = world.getEntity(id);
|
|
272
|
+
if (entity) {
|
|
273
|
+
// Restore traits
|
|
274
|
+
for (const [name, traitData] of Object.entries(data.traits)) {
|
|
275
|
+
const trait = this.deserializeTrait(name, traitData);
|
|
276
|
+
if (trait) {
|
|
277
|
+
// Remove existing trait if present, then add the restored one
|
|
278
|
+
if (entity.has(name)) {
|
|
279
|
+
entity.remove(name);
|
|
280
|
+
}
|
|
281
|
+
entity.add(trait);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// Restore locations and contents
|
|
287
|
+
for (const [locationId, data] of Object.entries(index.locations)) {
|
|
288
|
+
for (const entityId of data.contents) {
|
|
289
|
+
const entity = world.getEntity(entityId);
|
|
290
|
+
if (entity) {
|
|
291
|
+
world.moveEntity(entity.id, locationId);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Serialize turn history
|
|
298
|
+
*/
|
|
299
|
+
serializeTurnHistory(history) {
|
|
300
|
+
const turns = [];
|
|
301
|
+
for (const [index, result] of history.entries()) {
|
|
302
|
+
turns.push({
|
|
303
|
+
turnNumber: index + 1,
|
|
304
|
+
eventIds: result.events.map((e) => e.source || `${e.turn}-${e.sequence}`),
|
|
305
|
+
timestamp: result.events[0]?.timestamp.getTime() || Date.now(),
|
|
306
|
+
command: result.input
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
return turns;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Deserialize turn history
|
|
313
|
+
*/
|
|
314
|
+
deserializeTurnHistory(turns, eventSource) {
|
|
315
|
+
const history = [];
|
|
316
|
+
for (const turn of turns) {
|
|
317
|
+
// Find the events for this turn
|
|
318
|
+
const events = eventSource.getAllEvents().filter((e) => turn.eventIds.includes(e.id));
|
|
319
|
+
// Convert SemanticEvents to SequencedEvents
|
|
320
|
+
const sequencedEvents = events.map((event, index) => (0, event_adapter_1.toSequencedEvent)(event, turn.turnNumber, index));
|
|
321
|
+
history.push({
|
|
322
|
+
turn: turn.turnNumber,
|
|
323
|
+
input: turn.command || '',
|
|
324
|
+
success: true,
|
|
325
|
+
events: sequencedEvents
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
return history;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Serialize parser state
|
|
332
|
+
*/
|
|
333
|
+
serializeParserState(parser) {
|
|
334
|
+
if (!parser) {
|
|
335
|
+
return undefined;
|
|
336
|
+
}
|
|
337
|
+
// Parser state serialization is parser-specific
|
|
338
|
+
// For now, return empty object
|
|
339
|
+
return {};
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Serialize scheduler state (daemons and fuses)
|
|
343
|
+
*/
|
|
344
|
+
serializeSchedulerState(scheduler) {
|
|
345
|
+
const state = scheduler.getState();
|
|
346
|
+
return {
|
|
347
|
+
turn: state.turn,
|
|
348
|
+
daemons: state.daemons.map((d) => ({
|
|
349
|
+
id: d.id,
|
|
350
|
+
isPaused: d.isPaused,
|
|
351
|
+
runCount: d.runCount
|
|
352
|
+
})),
|
|
353
|
+
fuses: state.fuses.map((f) => ({
|
|
354
|
+
id: f.id,
|
|
355
|
+
turnsRemaining: f.turnsRemaining,
|
|
356
|
+
isPaused: f.isPaused,
|
|
357
|
+
entityId: f.entityId
|
|
358
|
+
})),
|
|
359
|
+
randomSeed: state.randomSeed
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Deserialize scheduler state
|
|
364
|
+
*/
|
|
365
|
+
deserializeSchedulerState(state, scheduler) {
|
|
366
|
+
scheduler.setState({
|
|
367
|
+
turn: state.turn,
|
|
368
|
+
daemons: state.daemons.map((d) => ({
|
|
369
|
+
id: d.id,
|
|
370
|
+
isPaused: d.isPaused,
|
|
371
|
+
runCount: d.runCount
|
|
372
|
+
})),
|
|
373
|
+
fuses: state.fuses.map((f) => ({
|
|
374
|
+
id: f.id,
|
|
375
|
+
turnsRemaining: f.turnsRemaining,
|
|
376
|
+
isPaused: f.isPaused,
|
|
377
|
+
entityId: f.entityId
|
|
378
|
+
})),
|
|
379
|
+
randomSeed: state.randomSeed
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Serialize a trait
|
|
384
|
+
*/
|
|
385
|
+
serializeTrait(trait) {
|
|
386
|
+
if (typeof trait === 'object' && trait !== null) {
|
|
387
|
+
return { ...trait };
|
|
388
|
+
}
|
|
389
|
+
return trait;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Deserialize a trait
|
|
393
|
+
*/
|
|
394
|
+
deserializeTrait(name, data) {
|
|
395
|
+
if (data && typeof data === 'object') {
|
|
396
|
+
return { type: name, ...data };
|
|
397
|
+
}
|
|
398
|
+
return null;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Extract connections from a location entity
|
|
402
|
+
*/
|
|
403
|
+
extractConnections(location, world) {
|
|
404
|
+
const connections = {};
|
|
405
|
+
// Check for ROOM trait with exits
|
|
406
|
+
const roomTrait = location.get('if.trait.room');
|
|
407
|
+
if (roomTrait?.exits) {
|
|
408
|
+
Object.entries(roomTrait.exits).forEach(([direction, exit]) => {
|
|
409
|
+
if (exit.destination) {
|
|
410
|
+
connections[direction] = exit.destination;
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
// Check for doors in this location
|
|
415
|
+
const contents = world.getContents(location.id);
|
|
416
|
+
contents.forEach((entity) => {
|
|
417
|
+
const doorTrait = entity.get('if.trait.door');
|
|
418
|
+
if (doorTrait) {
|
|
419
|
+
const otherRoom = doorTrait.room1 === location.id ? doorTrait.room2 : doorTrait.room1;
|
|
420
|
+
if (otherRoom) {
|
|
421
|
+
// Try to determine direction from door name
|
|
422
|
+
const name = entity.name?.toLowerCase() || '';
|
|
423
|
+
if (name.includes('north'))
|
|
424
|
+
connections.north = otherRoom;
|
|
425
|
+
else if (name.includes('south'))
|
|
426
|
+
connections.south = otherRoom;
|
|
427
|
+
else if (name.includes('east'))
|
|
428
|
+
connections.east = otherRoom;
|
|
429
|
+
else if (name.includes('west'))
|
|
430
|
+
connections.west = otherRoom;
|
|
431
|
+
else
|
|
432
|
+
connections.door = otherRoom;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
return connections;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
exports.SaveRestoreService = SaveRestoreService;
|
|
440
|
+
/**
|
|
441
|
+
* Create a save/restore service instance
|
|
442
|
+
*/
|
|
443
|
+
function createSaveRestoreService(config) {
|
|
444
|
+
return new SaveRestoreService(config);
|
|
445
|
+
}
|
|
446
|
+
//# sourceMappingURL=save-restore-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save-restore-service.js","sourceRoot":"","sources":["../src/save-restore-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scheduler/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Scheduler module exports (ADR-071)
|
|
4
|
+
*
|
|
5
|
+
* Provides daemon and fuse management for timed events in IF games.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
__exportStar(require("./types"), exports);
|
|
23
|
+
__exportStar(require("./seeded-random"), exports);
|
|
24
|
+
__exportStar(require("./scheduler-service"), exports);
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scheduler/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;AAEH,0CAAwB;AACxB,kDAAgC;AAChC,sDAAoC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SchedulerService - Manages Daemons and Fuses (ADR-071)
|
|
3
|
+
*
|
|
4
|
+
* The scheduler runs during the turn cycle, after NPCs act:
|
|
5
|
+
* 1. Player action
|
|
6
|
+
* 2. NPC turns
|
|
7
|
+
* 3. Scheduler tick (daemons run, fuses count down)
|
|
8
|
+
* 4. Turn complete
|
|
9
|
+
*/
|
|
10
|
+
import { ISemanticEvent, EntityId } from '@sharpee/core';
|
|
11
|
+
import { WorldModel } from '@sharpee/world-model';
|
|
12
|
+
import { Daemon, Fuse, DaemonInfo, FuseInfo, SchedulerResult, SchedulerState, SeededRandom } from './types';
|
|
13
|
+
/**
|
|
14
|
+
* SchedulerService interface
|
|
15
|
+
*/
|
|
16
|
+
export interface ISchedulerService {
|
|
17
|
+
registerDaemon(daemon: Daemon): void;
|
|
18
|
+
removeDaemon(id: string): void;
|
|
19
|
+
pauseDaemon(id: string): void;
|
|
20
|
+
resumeDaemon(id: string): void;
|
|
21
|
+
hasDaemon(id: string): boolean;
|
|
22
|
+
setFuse(fuse: Fuse): void;
|
|
23
|
+
cancelFuse(id: string): ISemanticEvent[];
|
|
24
|
+
getFuseRemaining(id: string): number | undefined;
|
|
25
|
+
adjustFuse(id: string, delta: number): void;
|
|
26
|
+
pauseFuse(id: string): void;
|
|
27
|
+
resumeFuse(id: string): void;
|
|
28
|
+
hasFuse(id: string): boolean;
|
|
29
|
+
tick(world: WorldModel, turn: number, playerId: EntityId): SchedulerResult;
|
|
30
|
+
getActiveDaemons(): DaemonInfo[];
|
|
31
|
+
getActiveFuses(): FuseInfo[];
|
|
32
|
+
getState(): SchedulerState;
|
|
33
|
+
setState(state: SchedulerState): void;
|
|
34
|
+
cleanupEntity(entityId: EntityId): ISemanticEvent[];
|
|
35
|
+
getRandom(): SeededRandom;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* SchedulerService implementation
|
|
39
|
+
*/
|
|
40
|
+
export declare class SchedulerService implements ISchedulerService {
|
|
41
|
+
private daemons;
|
|
42
|
+
private daemonStates;
|
|
43
|
+
private fuses;
|
|
44
|
+
private fuseStates;
|
|
45
|
+
private random;
|
|
46
|
+
private currentTurn;
|
|
47
|
+
constructor(seed?: number);
|
|
48
|
+
registerDaemon(daemon: Daemon): void;
|
|
49
|
+
removeDaemon(id: string): void;
|
|
50
|
+
pauseDaemon(id: string): void;
|
|
51
|
+
resumeDaemon(id: string): void;
|
|
52
|
+
hasDaemon(id: string): boolean;
|
|
53
|
+
setFuse(fuse: Fuse): void;
|
|
54
|
+
cancelFuse(id: string): ISemanticEvent[];
|
|
55
|
+
getFuseRemaining(id: string): number | undefined;
|
|
56
|
+
adjustFuse(id: string, delta: number): void;
|
|
57
|
+
pauseFuse(id: string): void;
|
|
58
|
+
resumeFuse(id: string): void;
|
|
59
|
+
hasFuse(id: string): boolean;
|
|
60
|
+
tick(world: WorldModel, turn: number, playerId: EntityId): SchedulerResult;
|
|
61
|
+
getActiveDaemons(): DaemonInfo[];
|
|
62
|
+
getActiveFuses(): FuseInfo[];
|
|
63
|
+
getState(): SchedulerState;
|
|
64
|
+
setState(state: SchedulerState): void;
|
|
65
|
+
cleanupEntity(entityId: EntityId): ISemanticEvent[];
|
|
66
|
+
getRandom(): SeededRandom;
|
|
67
|
+
private createContext;
|
|
68
|
+
private getSortedDaemons;
|
|
69
|
+
private getSortedFuses;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create a new SchedulerService instance
|
|
73
|
+
*/
|
|
74
|
+
export declare function createSchedulerService(seed?: number): ISchedulerService;
|
|
75
|
+
//# sourceMappingURL=scheduler-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler-service.d.ts","sourceRoot":"","sources":["../../src/scheduler/scheduler-service.ts"],"names":[],"mappings":"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"}
|