@patterkit/runtime 0.8.0 → 0.9.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/CHANGELOG.md +49 -0
- package/dist/index.cjs +122 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +127 -14
- package/dist/index.d.ts +127 -14
- package/dist/index.js +122 -83
- package/dist/index.js.map +1 -1
- package/dist/patterplay.min.js +2 -2
- package/dist/patterplay.min.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ScalarValue } from '@wildwinter/expr';
|
|
2
|
-
import { ScopeResolver, ScopeRegistry, ScopeDeclaration } from '@wildwinter/scoperegistry';
|
|
2
|
+
import { ScopeResolver, ScopeRegistry, ScopeDeclaration, PropertyBag, PropertyRow } from '@wildwinter/scoperegistry';
|
|
3
|
+
export { PropertyRow } from '@wildwinter/scoperegistry';
|
|
3
4
|
import { GameData, Bundle, CompiledGroup, CompiledSnippet, CompiledBlock, PropertyType, ScalarValue as ScalarValue$1, GameDataNodeKind, GameDataField } from '@patterkit/model';
|
|
4
5
|
export { Bundle } from '@patterkit/model';
|
|
5
6
|
|
|
@@ -196,6 +197,88 @@ interface ChoiceOption {
|
|
|
196
197
|
* are never stored or saved by this engine.
|
|
197
198
|
*/
|
|
198
199
|
type WorldResolver = ScopeResolver;
|
|
200
|
+
/** What the engine DECIDED, as opposed to what it produced. A step tells you the line that
|
|
201
|
+
* played; a trace event tells you why that line and not its siblings - which children were
|
|
202
|
+
* eligible, where the selector's cursor stood, which choice options were live.
|
|
203
|
+
*
|
|
204
|
+
* The reasoning is IN the entry, not implied by it. `select` carries every child it looked at
|
|
205
|
+
* with its own verdict, the way a deal in the Storylet Engine carries every card it considered.
|
|
206
|
+
* A log that recorded only the winner would answer "what happened" and not "why", and "why"
|
|
207
|
+
* is the question a dialogue author cannot otherwise answer: the line you expected is missing
|
|
208
|
+
* and nothing anywhere says which condition dropped it.
|
|
209
|
+
*
|
|
210
|
+
* Patter's vocabulary, not the Storylet Engine's: there are no cards or hands here. The
|
|
211
|
+
* structure is shared (an ordered retained log, `seq`, a flow-level and an engine-level tap);
|
|
212
|
+
* the events are this engine's own. */
|
|
213
|
+
type TraceEvent = {
|
|
214
|
+
type: "select";
|
|
215
|
+
/** The group whose children were being chosen among. */
|
|
216
|
+
group: string;
|
|
217
|
+
/** `branch` | `sequence` | `run` | `choice`, and for `sequence` its order/exhaust policy. */
|
|
218
|
+
selector: string;
|
|
219
|
+
order?: string;
|
|
220
|
+
exhaust?: string;
|
|
221
|
+
/** Every child considered, in authored order, each with why it was or was not takeable. */
|
|
222
|
+
children: {
|
|
223
|
+
id: string;
|
|
224
|
+
eligible: boolean;
|
|
225
|
+
}[];
|
|
226
|
+
/** The child selected, or null when nothing was takeable. */
|
|
227
|
+
picked: string | null;
|
|
228
|
+
} | {
|
|
229
|
+
type: "choice";
|
|
230
|
+
group: string;
|
|
231
|
+
/** Every option the group offered, with the ones a condition dropped marked. */
|
|
232
|
+
options: {
|
|
233
|
+
id: string;
|
|
234
|
+
eligible: boolean;
|
|
235
|
+
}[];
|
|
236
|
+
}
|
|
237
|
+
/** A choice the player answered. `option` is what they took. */
|
|
238
|
+
| {
|
|
239
|
+
type: "chose";
|
|
240
|
+
group: string;
|
|
241
|
+
option: string;
|
|
242
|
+
}
|
|
243
|
+
/** A choice with no takeable option and no eligible fallback, which falls through
|
|
244
|
+
* silently. Also reported through `onDryChoice`, which stays: a log is an audit read
|
|
245
|
+
* afterwards, that callback is live feedback a host acts on. */
|
|
246
|
+
| {
|
|
247
|
+
type: "dry";
|
|
248
|
+
group: string;
|
|
249
|
+
} | {
|
|
250
|
+
type: "jump";
|
|
251
|
+
to: string;
|
|
252
|
+
mode: "jump" | "call";
|
|
253
|
+
}
|
|
254
|
+
/** One landed effect; `prev` is the value it replaced, so a reader can say "0 -> 1". */
|
|
255
|
+
| {
|
|
256
|
+
type: "write";
|
|
257
|
+
target: string;
|
|
258
|
+
value: ScalarValue;
|
|
259
|
+
prev?: ScalarValue;
|
|
260
|
+
}
|
|
261
|
+
/** An expression that would not evaluate: never a silent pass, always visible. */
|
|
262
|
+
| {
|
|
263
|
+
type: "diagnostic";
|
|
264
|
+
where: string;
|
|
265
|
+
message: string;
|
|
266
|
+
};
|
|
267
|
+
type TraceHandler = (event: TraceEvent) => void;
|
|
268
|
+
/** The engine-level tap: every flow's events, tagged with the flow id - one stream for tools. */
|
|
269
|
+
type EngineTraceHandler = (flow: string, event: TraceEvent) => void;
|
|
270
|
+
/** A retained entry: the event plus its place in flow time. `seq` is monotonic across the
|
|
271
|
+
* flow and survives clearLog, so two reads of the log agree about order. */
|
|
272
|
+
type LogEntry = TraceEvent & {
|
|
273
|
+
seq: number;
|
|
274
|
+
scene?: string;
|
|
275
|
+
};
|
|
276
|
+
/** One entry on the ENGINE's log: the same event plus the flow it happened in. A run is
|
|
277
|
+
* several flows over shared state, so "what happened in this run" is only answerable in one
|
|
278
|
+
* ordered stream, and only if each line says who. */
|
|
279
|
+
type EngineLogEntry = LogEntry & {
|
|
280
|
+
flow: string;
|
|
281
|
+
};
|
|
199
282
|
interface EngineOptions {
|
|
200
283
|
/**
|
|
201
284
|
* Custom float-in-[0,1) source for `random()` / shuffle, shared by all flows.
|
|
@@ -227,17 +310,11 @@ interface EngineOptions {
|
|
|
227
310
|
* unchanged; this only makes the fall-through observable. The coverage harness uses it to flag choices
|
|
228
311
|
* that ran dry. Leave it unset in shipped games (zero cost). */
|
|
229
312
|
onDryChoice?: (groupId: string) => void;
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
type: PropertyType;
|
|
236
|
-
value: ScalarValue | undefined;
|
|
237
|
-
default: ScalarValue;
|
|
238
|
-
values?: string[];
|
|
239
|
-
/** A quality's ordered stage ladder (lets an inspector offer stages instead of free text). */
|
|
240
|
-
stages?: string[];
|
|
313
|
+
/** Retain a trace of the engine's DECISIONS (what it chose and why), readable through
|
|
314
|
+
* `engine.log()` and `flow.log()`. Off by default: a shipped game pays nothing for a
|
|
315
|
+
* debugging surface it never reads. `onDryChoice` above is unaffected and stays useful
|
|
316
|
+
* with the log off - it is live feedback, not an audit read afterwards. */
|
|
317
|
+
log?: boolean;
|
|
241
318
|
}
|
|
242
319
|
/** Options for opening a flow. */
|
|
243
320
|
interface OpenFlowOptions {
|
|
@@ -256,6 +333,10 @@ interface SelectorState {
|
|
|
256
333
|
}
|
|
257
334
|
/** Shared, read-mostly context the engine hands to every flow it owns. */
|
|
258
335
|
interface FlowHost {
|
|
336
|
+
/** True when the run asked for a log; flows skip building entries otherwise. */
|
|
337
|
+
logEnabled: boolean;
|
|
338
|
+
/** A flow's events reach the ENGINE's stream through here, tagged with the flow id. */
|
|
339
|
+
emitEngine: (flow: string, event: TraceEvent, scene?: string) => void;
|
|
259
340
|
bundle: Bundle;
|
|
260
341
|
/** IDs-only build (`localisation.mode === "ids"`, no source-debug): the engine emits each beat's ID as
|
|
261
342
|
* its text and omits character display names, leaving localisation to the game (use `flow.interpolate`
|
|
@@ -293,7 +374,11 @@ interface FlowHost {
|
|
|
293
374
|
/** Shared selector cursors (node id -> SelectorState) for `shared` memoried selectors. */
|
|
294
375
|
sharedSelectors: Map<string, SelectorState>;
|
|
295
376
|
/** Shared, scene-namespaced `@scene` bags (scene id -> name -> value) for shared scene props. */
|
|
296
|
-
|
|
377
|
+
/** Per-scene SHARED scene props. A PropertyBag rather than a bare record since
|
|
378
|
+
* 2026-09-02: seeding, name normalisation and the mutable-default clone were all
|
|
379
|
+
* written out by hand here, and the shared bag already had them. The SAVE is
|
|
380
|
+
* unchanged - bag.save() is a bare record, which is what the envelope carries. */
|
|
381
|
+
stageBags: Map<string, PropertyBag>;
|
|
297
382
|
customRng?: () => number;
|
|
298
383
|
/** Play a chosen option's prompt as its first beat (spec §5); default false. */
|
|
299
384
|
replayPromptOnChoose?: boolean;
|
|
@@ -337,6 +422,10 @@ declare class Engine {
|
|
|
337
422
|
/** The options this engine was built with - reused verbatim by `hotSwap` so the replacement
|
|
338
423
|
* engine keeps the same world resolver, custom RNG, and diagnostic hooks. */
|
|
339
424
|
private readonly creationOptions;
|
|
425
|
+
/** The run's ordered stream: every flow's events, each naming its flow. Empty and
|
|
426
|
+
* unwritten unless `options.log` asked for it. */
|
|
427
|
+
private readonly engineLog;
|
|
428
|
+
private readonly engineTraceHandlers;
|
|
340
429
|
constructor(bundle: Bundle, options?: EngineOptions);
|
|
341
430
|
/** The active locale (string + character-name lookups resolve in it). */
|
|
342
431
|
get locale(): string;
|
|
@@ -496,6 +585,17 @@ declare class Engine {
|
|
|
496
585
|
setProperty(ref: string, value: ScalarValue): void;
|
|
497
586
|
/** The shared `@patter` properties, for a live state inspector: each with its ref, type, current
|
|
498
587
|
* value, declared default (for reset), and enum options. Mirrors the Unity / Godot ports. */
|
|
588
|
+
/** The run's decisions, in order, each naming the flow it happened in. Empty unless the
|
|
589
|
+
* run was opened with `log: true`. A flow's own log stays flow-local; this is the only
|
|
590
|
+
* place a story spanning several flows reads as one sequence. */
|
|
591
|
+
log(): readonly EngineLogEntry[];
|
|
592
|
+
/** Drop the retained entries. `seq` does NOT restart: two reads of a log either side of a
|
|
593
|
+
* clear still agree about what came first. */
|
|
594
|
+
clearLog(): void;
|
|
595
|
+
/** Live tap on the run's decisions, for tooling that wants them as they happen rather than
|
|
596
|
+
* retained. Returns its own unsubscribe. */
|
|
597
|
+
onTrace(handler: EngineTraceHandler): () => void;
|
|
598
|
+
private emitEngine;
|
|
499
599
|
listProperties(): PropertyRow[];
|
|
500
600
|
private splitShared;
|
|
501
601
|
/** Snapshot shared `@patter` state only (for a unified cross-engine save blob, Phase D). */
|
|
@@ -530,10 +630,14 @@ declare class Flow {
|
|
|
530
630
|
private selectors;
|
|
531
631
|
/** Per-node entry counts for this flow (node id -> times entered). */
|
|
532
632
|
private visitCounts;
|
|
633
|
+
/** This flow's per-scene LOCAL scene props; see FlowHost.stageBags. */
|
|
533
634
|
private sceneBags;
|
|
534
635
|
private readonly patterResolver;
|
|
535
636
|
private readonly sceneResolver;
|
|
536
637
|
private readonly evalCtx;
|
|
638
|
+
private readonly flowLog;
|
|
639
|
+
/** Monotonic across the flow's life; survives clearLog so two reads agree on order. */
|
|
640
|
+
private flowSeq;
|
|
537
641
|
constructor(id: string, host: FlowHost, seed: number);
|
|
538
642
|
/** The stage ladder of `@scope.name` when it is a declared quality, else undefined. Names compare
|
|
539
643
|
* lowercase, as the compiler emits references (the selfBackedResolver lesson). */
|
|
@@ -599,6 +703,15 @@ declare class Flow {
|
|
|
599
703
|
*/
|
|
600
704
|
private settle;
|
|
601
705
|
/** The options of a pending choice (empty when not at a choice point). */
|
|
706
|
+
/** This flow's decisions, in order. Empty unless the run was opened with `log: true`.
|
|
707
|
+
* The engine's log carries the same events tagged with the flow; this one is what a
|
|
708
|
+
* single conversation reads as. */
|
|
709
|
+
log(): readonly LogEntry[];
|
|
710
|
+
/** Drop the retained entries. `seq` keeps counting, so order survives a clear. */
|
|
711
|
+
clearLog(): void;
|
|
712
|
+
/** Record one decision, on this flow's log and the engine's. Cheap to call with logging
|
|
713
|
+
* off: the entry is never built. */
|
|
714
|
+
private emit;
|
|
602
715
|
getChoices(): ChoiceOption[];
|
|
603
716
|
/** Pick an eligible option by id; the next `advance()` runs it. */
|
|
604
717
|
choose(id: string): void;
|
|
@@ -887,4 +1000,4 @@ declare function effectiveGameData(fields: GameDataField[], node: GameData | und
|
|
|
887
1000
|
*/
|
|
888
1001
|
declare function buildTagIndex(bundle: Bundle): Map<string, string[]>;
|
|
889
1002
|
|
|
890
|
-
export { type AddressSummary, type AdvanceToStopResult, type BeatInfo, type BundleCounts, type BundleDescription, type BundleIdentity, type ChoiceOption, Engine, type EngineOptions, type EngineSave, type FlatBeat, Flow, type FlowSnapshot, type GameDataFieldSummary, type GameDataSummary, type HostScopeSummary, type OpenFlowOptions, type OutlineBlock, type OutlineNode, type OutlineScene, type OwnedProperties, type
|
|
1003
|
+
export { type AddressSummary, type AdvanceToStopResult, type BeatInfo, type BundleCounts, type BundleDescription, type BundleIdentity, type ChoiceOption, Engine, type EngineLogEntry, type EngineOptions, type EngineSave, type EngineTraceHandler, type FlatBeat, Flow, type FlowSnapshot, type GameDataFieldSummary, type GameDataSummary, type HostScopeSummary, type LogEntry, type OpenFlowOptions, type OutlineBlock, type OutlineNode, type OutlineScene, type OwnedProperties, type PropertySummary, type SaveGame, type SavedChoice, type SelectorSnapshot, type StackFrame, type StepResult, type TraceEvent, type TraceHandler, type WorldResolver, buildTagIndex, describeBundle, effectiveGameData, gameDataFields, gameDataValue };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ScalarValue } from '@wildwinter/expr';
|
|
2
|
-
import { ScopeResolver, ScopeRegistry, ScopeDeclaration } from '@wildwinter/scoperegistry';
|
|
2
|
+
import { ScopeResolver, ScopeRegistry, ScopeDeclaration, PropertyBag, PropertyRow } from '@wildwinter/scoperegistry';
|
|
3
|
+
export { PropertyRow } from '@wildwinter/scoperegistry';
|
|
3
4
|
import { GameData, Bundle, CompiledGroup, CompiledSnippet, CompiledBlock, PropertyType, ScalarValue as ScalarValue$1, GameDataNodeKind, GameDataField } from '@patterkit/model';
|
|
4
5
|
export { Bundle } from '@patterkit/model';
|
|
5
6
|
|
|
@@ -196,6 +197,88 @@ interface ChoiceOption {
|
|
|
196
197
|
* are never stored or saved by this engine.
|
|
197
198
|
*/
|
|
198
199
|
type WorldResolver = ScopeResolver;
|
|
200
|
+
/** What the engine DECIDED, as opposed to what it produced. A step tells you the line that
|
|
201
|
+
* played; a trace event tells you why that line and not its siblings - which children were
|
|
202
|
+
* eligible, where the selector's cursor stood, which choice options were live.
|
|
203
|
+
*
|
|
204
|
+
* The reasoning is IN the entry, not implied by it. `select` carries every child it looked at
|
|
205
|
+
* with its own verdict, the way a deal in the Storylet Engine carries every card it considered.
|
|
206
|
+
* A log that recorded only the winner would answer "what happened" and not "why", and "why"
|
|
207
|
+
* is the question a dialogue author cannot otherwise answer: the line you expected is missing
|
|
208
|
+
* and nothing anywhere says which condition dropped it.
|
|
209
|
+
*
|
|
210
|
+
* Patter's vocabulary, not the Storylet Engine's: there are no cards or hands here. The
|
|
211
|
+
* structure is shared (an ordered retained log, `seq`, a flow-level and an engine-level tap);
|
|
212
|
+
* the events are this engine's own. */
|
|
213
|
+
type TraceEvent = {
|
|
214
|
+
type: "select";
|
|
215
|
+
/** The group whose children were being chosen among. */
|
|
216
|
+
group: string;
|
|
217
|
+
/** `branch` | `sequence` | `run` | `choice`, and for `sequence` its order/exhaust policy. */
|
|
218
|
+
selector: string;
|
|
219
|
+
order?: string;
|
|
220
|
+
exhaust?: string;
|
|
221
|
+
/** Every child considered, in authored order, each with why it was or was not takeable. */
|
|
222
|
+
children: {
|
|
223
|
+
id: string;
|
|
224
|
+
eligible: boolean;
|
|
225
|
+
}[];
|
|
226
|
+
/** The child selected, or null when nothing was takeable. */
|
|
227
|
+
picked: string | null;
|
|
228
|
+
} | {
|
|
229
|
+
type: "choice";
|
|
230
|
+
group: string;
|
|
231
|
+
/** Every option the group offered, with the ones a condition dropped marked. */
|
|
232
|
+
options: {
|
|
233
|
+
id: string;
|
|
234
|
+
eligible: boolean;
|
|
235
|
+
}[];
|
|
236
|
+
}
|
|
237
|
+
/** A choice the player answered. `option` is what they took. */
|
|
238
|
+
| {
|
|
239
|
+
type: "chose";
|
|
240
|
+
group: string;
|
|
241
|
+
option: string;
|
|
242
|
+
}
|
|
243
|
+
/** A choice with no takeable option and no eligible fallback, which falls through
|
|
244
|
+
* silently. Also reported through `onDryChoice`, which stays: a log is an audit read
|
|
245
|
+
* afterwards, that callback is live feedback a host acts on. */
|
|
246
|
+
| {
|
|
247
|
+
type: "dry";
|
|
248
|
+
group: string;
|
|
249
|
+
} | {
|
|
250
|
+
type: "jump";
|
|
251
|
+
to: string;
|
|
252
|
+
mode: "jump" | "call";
|
|
253
|
+
}
|
|
254
|
+
/** One landed effect; `prev` is the value it replaced, so a reader can say "0 -> 1". */
|
|
255
|
+
| {
|
|
256
|
+
type: "write";
|
|
257
|
+
target: string;
|
|
258
|
+
value: ScalarValue;
|
|
259
|
+
prev?: ScalarValue;
|
|
260
|
+
}
|
|
261
|
+
/** An expression that would not evaluate: never a silent pass, always visible. */
|
|
262
|
+
| {
|
|
263
|
+
type: "diagnostic";
|
|
264
|
+
where: string;
|
|
265
|
+
message: string;
|
|
266
|
+
};
|
|
267
|
+
type TraceHandler = (event: TraceEvent) => void;
|
|
268
|
+
/** The engine-level tap: every flow's events, tagged with the flow id - one stream for tools. */
|
|
269
|
+
type EngineTraceHandler = (flow: string, event: TraceEvent) => void;
|
|
270
|
+
/** A retained entry: the event plus its place in flow time. `seq` is monotonic across the
|
|
271
|
+
* flow and survives clearLog, so two reads of the log agree about order. */
|
|
272
|
+
type LogEntry = TraceEvent & {
|
|
273
|
+
seq: number;
|
|
274
|
+
scene?: string;
|
|
275
|
+
};
|
|
276
|
+
/** One entry on the ENGINE's log: the same event plus the flow it happened in. A run is
|
|
277
|
+
* several flows over shared state, so "what happened in this run" is only answerable in one
|
|
278
|
+
* ordered stream, and only if each line says who. */
|
|
279
|
+
type EngineLogEntry = LogEntry & {
|
|
280
|
+
flow: string;
|
|
281
|
+
};
|
|
199
282
|
interface EngineOptions {
|
|
200
283
|
/**
|
|
201
284
|
* Custom float-in-[0,1) source for `random()` / shuffle, shared by all flows.
|
|
@@ -227,17 +310,11 @@ interface EngineOptions {
|
|
|
227
310
|
* unchanged; this only makes the fall-through observable. The coverage harness uses it to flag choices
|
|
228
311
|
* that ran dry. Leave it unset in shipped games (zero cost). */
|
|
229
312
|
onDryChoice?: (groupId: string) => void;
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
type: PropertyType;
|
|
236
|
-
value: ScalarValue | undefined;
|
|
237
|
-
default: ScalarValue;
|
|
238
|
-
values?: string[];
|
|
239
|
-
/** A quality's ordered stage ladder (lets an inspector offer stages instead of free text). */
|
|
240
|
-
stages?: string[];
|
|
313
|
+
/** Retain a trace of the engine's DECISIONS (what it chose and why), readable through
|
|
314
|
+
* `engine.log()` and `flow.log()`. Off by default: a shipped game pays nothing for a
|
|
315
|
+
* debugging surface it never reads. `onDryChoice` above is unaffected and stays useful
|
|
316
|
+
* with the log off - it is live feedback, not an audit read afterwards. */
|
|
317
|
+
log?: boolean;
|
|
241
318
|
}
|
|
242
319
|
/** Options for opening a flow. */
|
|
243
320
|
interface OpenFlowOptions {
|
|
@@ -256,6 +333,10 @@ interface SelectorState {
|
|
|
256
333
|
}
|
|
257
334
|
/** Shared, read-mostly context the engine hands to every flow it owns. */
|
|
258
335
|
interface FlowHost {
|
|
336
|
+
/** True when the run asked for a log; flows skip building entries otherwise. */
|
|
337
|
+
logEnabled: boolean;
|
|
338
|
+
/** A flow's events reach the ENGINE's stream through here, tagged with the flow id. */
|
|
339
|
+
emitEngine: (flow: string, event: TraceEvent, scene?: string) => void;
|
|
259
340
|
bundle: Bundle;
|
|
260
341
|
/** IDs-only build (`localisation.mode === "ids"`, no source-debug): the engine emits each beat's ID as
|
|
261
342
|
* its text and omits character display names, leaving localisation to the game (use `flow.interpolate`
|
|
@@ -293,7 +374,11 @@ interface FlowHost {
|
|
|
293
374
|
/** Shared selector cursors (node id -> SelectorState) for `shared` memoried selectors. */
|
|
294
375
|
sharedSelectors: Map<string, SelectorState>;
|
|
295
376
|
/** Shared, scene-namespaced `@scene` bags (scene id -> name -> value) for shared scene props. */
|
|
296
|
-
|
|
377
|
+
/** Per-scene SHARED scene props. A PropertyBag rather than a bare record since
|
|
378
|
+
* 2026-09-02: seeding, name normalisation and the mutable-default clone were all
|
|
379
|
+
* written out by hand here, and the shared bag already had them. The SAVE is
|
|
380
|
+
* unchanged - bag.save() is a bare record, which is what the envelope carries. */
|
|
381
|
+
stageBags: Map<string, PropertyBag>;
|
|
297
382
|
customRng?: () => number;
|
|
298
383
|
/** Play a chosen option's prompt as its first beat (spec §5); default false. */
|
|
299
384
|
replayPromptOnChoose?: boolean;
|
|
@@ -337,6 +422,10 @@ declare class Engine {
|
|
|
337
422
|
/** The options this engine was built with - reused verbatim by `hotSwap` so the replacement
|
|
338
423
|
* engine keeps the same world resolver, custom RNG, and diagnostic hooks. */
|
|
339
424
|
private readonly creationOptions;
|
|
425
|
+
/** The run's ordered stream: every flow's events, each naming its flow. Empty and
|
|
426
|
+
* unwritten unless `options.log` asked for it. */
|
|
427
|
+
private readonly engineLog;
|
|
428
|
+
private readonly engineTraceHandlers;
|
|
340
429
|
constructor(bundle: Bundle, options?: EngineOptions);
|
|
341
430
|
/** The active locale (string + character-name lookups resolve in it). */
|
|
342
431
|
get locale(): string;
|
|
@@ -496,6 +585,17 @@ declare class Engine {
|
|
|
496
585
|
setProperty(ref: string, value: ScalarValue): void;
|
|
497
586
|
/** The shared `@patter` properties, for a live state inspector: each with its ref, type, current
|
|
498
587
|
* value, declared default (for reset), and enum options. Mirrors the Unity / Godot ports. */
|
|
588
|
+
/** The run's decisions, in order, each naming the flow it happened in. Empty unless the
|
|
589
|
+
* run was opened with `log: true`. A flow's own log stays flow-local; this is the only
|
|
590
|
+
* place a story spanning several flows reads as one sequence. */
|
|
591
|
+
log(): readonly EngineLogEntry[];
|
|
592
|
+
/** Drop the retained entries. `seq` does NOT restart: two reads of a log either side of a
|
|
593
|
+
* clear still agree about what came first. */
|
|
594
|
+
clearLog(): void;
|
|
595
|
+
/** Live tap on the run's decisions, for tooling that wants them as they happen rather than
|
|
596
|
+
* retained. Returns its own unsubscribe. */
|
|
597
|
+
onTrace(handler: EngineTraceHandler): () => void;
|
|
598
|
+
private emitEngine;
|
|
499
599
|
listProperties(): PropertyRow[];
|
|
500
600
|
private splitShared;
|
|
501
601
|
/** Snapshot shared `@patter` state only (for a unified cross-engine save blob, Phase D). */
|
|
@@ -530,10 +630,14 @@ declare class Flow {
|
|
|
530
630
|
private selectors;
|
|
531
631
|
/** Per-node entry counts for this flow (node id -> times entered). */
|
|
532
632
|
private visitCounts;
|
|
633
|
+
/** This flow's per-scene LOCAL scene props; see FlowHost.stageBags. */
|
|
533
634
|
private sceneBags;
|
|
534
635
|
private readonly patterResolver;
|
|
535
636
|
private readonly sceneResolver;
|
|
536
637
|
private readonly evalCtx;
|
|
638
|
+
private readonly flowLog;
|
|
639
|
+
/** Monotonic across the flow's life; survives clearLog so two reads agree on order. */
|
|
640
|
+
private flowSeq;
|
|
537
641
|
constructor(id: string, host: FlowHost, seed: number);
|
|
538
642
|
/** The stage ladder of `@scope.name` when it is a declared quality, else undefined. Names compare
|
|
539
643
|
* lowercase, as the compiler emits references (the selfBackedResolver lesson). */
|
|
@@ -599,6 +703,15 @@ declare class Flow {
|
|
|
599
703
|
*/
|
|
600
704
|
private settle;
|
|
601
705
|
/** The options of a pending choice (empty when not at a choice point). */
|
|
706
|
+
/** This flow's decisions, in order. Empty unless the run was opened with `log: true`.
|
|
707
|
+
* The engine's log carries the same events tagged with the flow; this one is what a
|
|
708
|
+
* single conversation reads as. */
|
|
709
|
+
log(): readonly LogEntry[];
|
|
710
|
+
/** Drop the retained entries. `seq` keeps counting, so order survives a clear. */
|
|
711
|
+
clearLog(): void;
|
|
712
|
+
/** Record one decision, on this flow's log and the engine's. Cheap to call with logging
|
|
713
|
+
* off: the entry is never built. */
|
|
714
|
+
private emit;
|
|
602
715
|
getChoices(): ChoiceOption[];
|
|
603
716
|
/** Pick an eligible option by id; the next `advance()` runs it. */
|
|
604
717
|
choose(id: string): void;
|
|
@@ -887,4 +1000,4 @@ declare function effectiveGameData(fields: GameDataField[], node: GameData | und
|
|
|
887
1000
|
*/
|
|
888
1001
|
declare function buildTagIndex(bundle: Bundle): Map<string, string[]>;
|
|
889
1002
|
|
|
890
|
-
export { type AddressSummary, type AdvanceToStopResult, type BeatInfo, type BundleCounts, type BundleDescription, type BundleIdentity, type ChoiceOption, Engine, type EngineOptions, type EngineSave, type FlatBeat, Flow, type FlowSnapshot, type GameDataFieldSummary, type GameDataSummary, type HostScopeSummary, type OpenFlowOptions, type OutlineBlock, type OutlineNode, type OutlineScene, type OwnedProperties, type
|
|
1003
|
+
export { type AddressSummary, type AdvanceToStopResult, type BeatInfo, type BundleCounts, type BundleDescription, type BundleIdentity, type ChoiceOption, Engine, type EngineLogEntry, type EngineOptions, type EngineSave, type EngineTraceHandler, type FlatBeat, Flow, type FlowSnapshot, type GameDataFieldSummary, type GameDataSummary, type HostScopeSummary, type LogEntry, type OpenFlowOptions, type OutlineBlock, type OutlineNode, type OutlineScene, type OwnedProperties, type PropertySummary, type SaveGame, type SavedChoice, type SelectorSnapshot, type StackFrame, type StepResult, type TraceEvent, type TraceHandler, type WorldResolver, buildTagIndex, describeBundle, effectiveGameData, gameDataFields, gameDataValue };
|