LSDE Dialog Engine / LsdeUtils
Class: LsdeUtils
Defined in: lsde-utils.ts:33
Public utility class exposing common helpers for game developers integrating the LSDE engine.
Constructors
Constructor
new LsdeUtils():
LsdeUtils
Returns
LsdeUtils
Properties
evaluateConditionCases
staticevaluateConditionCases: (cases,portPerCase,evaluator) =>string
Defined in: lsde-utils.ts:184
The exit port of a condition block: out/default in if mode, K1… with portPerCase. Replaces the v1 evaluateConditionGroups, which returned an index and had a third, dispatcher mode that no longer exists.
Pick the exit port of a condition block. There are two modes and only two.
portPerCase | rule | exit |
|---|---|---|
| absent | every case must hold | out if they all do, default otherwise |
true | the first case that holds, in order | its own port (K1…), default if none |
A case with no when is always true — and makes every case below it unreachable in portPerCase mode. That is the writer's drawing, not an error to report.
A block with no cases at all leaves by out: nothing was asked, so nothing failed.
Parameters
cases
ConditionCase[] | undefined
portPerCase
boolean
evaluator
Returns
string
evaluateConditionChain
staticevaluateConditionChain: (tests,evaluator) =>boolean
Defined in: lsde-utils.ts:177
Evaluate a chain of tests left to right, with NO operator precedence. Absent or empty means true — which is how "always" is written in v2.
Evaluate a chain of tests left to right, with no operator precedence.
a AND b OR c reads as (a AND b) OR c, never as a AND (b OR c). That is deliberate: the editor draws a flat list, so the engine evaluates a flat list. A writer who needs grouping uses two condition blocks in a row, which is also what the reader of the graph sees.
join links a test to the one ABOVE it and is absent on the first. Missing means AND.
Every test is evaluated, even once the answer is settled. No short-circuit: the game's evaluator is also where a project logs, counts or displays what was asked, and skipping calls would make that log depend on the order the writer happened to use.
No tests at all = true. That is how "always" is written in v2 — by the ABSENCE of when, never by an empty list.
Parameters
tests
ConditionTest[] | undefined
evaluator
Returns
boolean
evaluateEachCase
staticevaluateEachCase: (cases,evaluator) =>boolean[]
Defined in: lsde-utils.ts:187
Each case on its own, in order — to show what matched without changing where the flow goes.
Evaluate every case on its own, without picking a port.
Handed to a game that wants to show what matched without changing where the flow goes. The engine fills context.cases[i].result with the same rule, then reads the exit port off those results, by the same rule evaluateConditionCases applies — never by calling this and deciding for itself.
Parameters
cases
ConditionCase[] | undefined
evaluator
Returns
boolean[]
isActionBlock
staticisActionBlock: (block) =>block is ActionBlock
Defined in: lsde-utils.ts:49
Returns true if the block is an action.
Parameters
block
Returns
block is ActionBlock
isChoiceBlock
staticisChoiceBlock: (block) =>block is ChoiceBlock
Defined in: lsde-utils.ts:43
Returns true if the block is a choice.
Parameters
block
Returns
block is ChoiceBlock
isChoiceCondition
staticisChoiceCondition: (test) =>boolean=isChoiceTest
Defined in: lsde-utils.ts:166
Does this test read a past answer of the player rather than game state?
choice is a reserved dictionary id that no project dictionary may take: entry is a CHOICE block id of this scene, value an option id of that block. The engine answers these from its own history, so a game never has to remember what it already told the engine.
Is this test about what the player already answered, rather than about game state?
choice is a reserved dictionary id — no project dictionary may take it. entry is a CHOICE block id of this scene and value an option id of that block. The engine answers these from the history it kept during the scene, so they never reach the game's evaluator: a game does not have to remember what it already told the engine.
Parameters
test
Returns
boolean
isConditionBlock
staticisConditionBlock: (block) =>block is ConditionBlock
Defined in: lsde-utils.ts:45
Returns true if the block is a condition.
Parameters
block
Returns
block is ConditionBlock
isDialogBlock
staticisDialogBlock: (block) =>block is DialogBlock
Defined in: lsde-utils.ts:41
Returns true if the block is a dialog.
Parameters
block
Returns
block is DialogBlock
isNoteBlock
staticisNoteBlock: (block) =>block is NoteBlock
Defined in: lsde-utils.ts:51
Returns true if the block is a note.
Parameters
block
Returns
block is NoteBlock
isRouterBlock
staticisRouterBlock: (block) =>block is RouterBlock
Defined in: lsde-utils.ts:47
Returns true if the block is a router.
Parameters
block
Returns
block is RouterBlock
locale
staticlocale:string|null=null
Defined in: lsde-utils.ts:36
Current locale set by engine.setLocale(). Used as the default by the text helpers.
pickRouterPorts
staticpickRouterPorts: (cases,results) =>string[]
Defined in: lsde-utils.ts:194
The exits of a ROUTER, from case results already computed: the port of every true case, then then when they all held or catch when one did not — always last. The router's reading of the same cases a condition carries.
A ROUTER's exits: the port of every true case, then then or catch.
The opposite reading of the same cases a condition carries. A condition asks which one and leaves by a single port; a router asks which ones, launches each of them, and continues besides — by then when every case held, by catch when any did not.
Three rules this encodes, all of them from the format's own contract:
- No break. Every case is counted, so a false one in the middle does not hide the true ones after it. That is the whole difference with a condition.
- The tally is over CASES, not over ports. A port carrying several wires launches several tracks and still counts as one case — and two cases wired to the same block dispatch it twice.
- No cases at all →
then, the wayPromise.all([])resolves.
The continuation is LAST in the list on purpose: the traversal keeps the first non-async target as the main flow, so then/catch stays the main flow as long as the case routes are async.
catch cancels nothing. The tracks of the true cases are already running by the time the tally is read — exactly like a Promise.all that rejects while its promises carry on.
Parameters
cases
ConditionCase[] | undefined
results
boolean[]
Returns
string[]
tagOptionVisibility
statictagOptionVisibility: (options,evaluator) =>RuntimeChoiceItem[]
Defined in: lsde-utils.ts:201
Tag every option of a choice with whether its when holds, returning them ALL. Replaces the v1 filterVisibleChoices, which shortened the list and took away the ability to show a locked answer.
Tag every option of a choice with whether its when holds.
The engine hands over all the options, tagged — never a shortened list. A game that wants only the offered ones writes options.filter( o => o.visible !== false ); a game that wants to grey out the others, or show "[locked]", still has them. Filtering here would take that away.
visible is left undefined when no evaluator is installed: unknown, not hidden.
Parameters
options
Option[] | undefined
evaluator
ConditionEvaluator | undefined
Returns
Methods
getBlockLabel()
staticgetBlockLabel(block):string
Defined in: lsde-utils.ts:62
How to name a block on screen or in a log.
There is no mandatory block name in v2, and none is needed: DIALOG-007 already reads better than the uuid it replaced. A designer note says far more than a three-word label would, so it comes next; a label wins when an export carries one.
Parameters
block
Returns
string
getChoiceConditionBlockId()
staticgetChoiceConditionBlockId(test):string|undefined
Defined in: lsde-utils.ts:169
The CHOICE block a choice: test reads, or undefined for any other test.
Parameters
test
Returns
string | undefined
getCustomProperties()
staticgetCustomProperties(block):PropertyBag
Defined in: lsde-utils.ts:145
The properties the DESIGNER declared, with the natives taken out — everything the game is free to give its own meaning to.
Parameters
block
Returns
getLocalizedText()
staticgetLocalizedText(text,locale?):string|undefined
Defined in: lsde-utils.ts:74
Pick a locale out of an inline text map — block.text, or an option's.
Only works when texts were exported INSIDE the payload. With the separate mode, the blocks carry no text at all and getTextFromTable is the one to use.
Parameters
text
TextByLocale | undefined
locale?
string
Returns
string | undefined
Throws
when no locale is set, by parameter or by engine.setLocale().
getNativeProperties()
staticgetNativeProperties(block):NativeProperties
Defined in: lsde-utils.ts:130
The properties the ENGINE acts on, pulled out of a block's props.
v2 puts natives and the designer's own properties in one bag, keyed by bare id, and ids cannot collide — LSDE refuses a project property that takes a native name. So this is a lookup against NATIVE_PROPERTY_IDS, not a guess.
delay and timeout are MILLISECONDS. They were seconds in v1 and nothing reports the change at runtime: a migrated project turns a 3-second pause into 3 ms.
Parameters
block
Returns
getTextFromTable()
staticgetTextFromTable(table,scene,blockId,optionId?):string|undefined
Defined in: lsde-utils.ts:91
Read a line out of a loaded localization/<locale>/__blueprints__.json, for the separate text mode.
The game loads the file — the engine does no IO, ever. Pass the block's scene and id, plus an option id for one answer of a choice.
const fr = JSON.parse( await readFile( 'localization/fr/__blueprints__.json', 'utf-8' ) );
LsdeUtils.getTextFromTable( fr, 'reactor_breach', 'DIALOG-001' );
LsdeUtils.getTextFromTable( fr, 'reactor_breach', 'CHOICE-001', 'C1' );Parameters
table
LocaleTable | undefined
scene
string
blockId
string
optionId?
string
Returns
string | undefined
getTextKey()
staticgetTextKey(block,optionId?):string
Defined in: lsde-utils.ts:114
The i18n key of a block, or of one option of a choice.
The key is already in the payload (block.key), so this only builds the option variant — useful for a voice file, whose name is derived from the key.
Parameters
block
optionId?
string
Returns
string
