Skip to content

Blueprints & Scenes

Blueprint Structure

A BlueprintExport is the JSON file exported from the LSDE editor. It contains all the data the engine needs.

ts
interface BlueprintExport {
  version: string;
  exportDate: string;
  projectName?: string;
  primaryLanguage?: string;
  locales: string[];
  dictionaries?: Dictionary[];
  signatures?: ActionSignature[];
  scenes: BlueprintScene[];
}
csharp
public class BlueprintExport {
    public string Version { get; set; }
    public string ExportDate { get; set; }
    public string? ProjectName { get; set; }
    public string? PrimaryLanguage { get; set; }
    public List<string> Locales { get; set; }
    public List<Dictionary>? Dictionaries { get; set; }
    public List<ActionSignature>? Signatures { get; set; }
    public List<BlueprintScene> Scenes { get; set; }
}
cpp
struct BlueprintExport {
    std::string version;
    std::string exportDate;
    std::optional<std::string> projectName;
    std::optional<std::string> primaryLanguage;
    std::vector<std::string> locales;
    std::vector<LsdeDictionary> dictionaries;
    std::vector<ActionSignature> signatures;
    std::vector<BlueprintScene> scenes;
};
gdscript
# Dictionary with keys:
# "version": String
# "exportDate": String
# "projectName": String (optional)
# "primaryLanguage": String (optional)
# "locales": Array[String]
# "dictionaries": Array[Dictionary] (optional)
# "signatures": Array[Dictionary] (optional)
# "scenes": Array[Dictionary]

Scenes

A scene is a self-contained dialogue sequence — a conversation, a cutscene, a tutorial prompt, a shop interaction. In a game, scenes are typically triggered by script events: the player talks to an NPC, enters a zone, or picks up an item.

Each scene has its own entry block, its own flow, and its own state. Multiple scenes can run in parallel (e.g. a main dialogue and a tutorial overlay). Scenes are defined by the BlueprintScene interface:

ts
interface BlueprintScene {
  uuid: string;
  label: string;
  note?: string;
  entryBlockId?: string;
  date: string;
  blocks: BlueprintBlock[];
  connections: BlueprintConnection[];
}
csharp
public class BlueprintScene {
    public string Uuid { get; set; }
    public string Label { get; set; }
    public string? Note { get; set; }
    public string? EntryBlockId { get; set; }
    public string Date { get; set; }
    public List<BlueprintBlock> Blocks { get; set; }
    public List<BlueprintConnection> Connections { get; set; }
}
cpp
struct BlueprintScene {
    std::string uuid;
    std::string label;
    std::optional<std::string> note;
    std::optional<std::string> entryBlockId;
    std::string date;
    std::vector<BlueprintBlock> blocks;
    std::vector<BlueprintConnection> connections;
};
gdscript
# Dictionary with keys:
# "uuid": String
# "label": String
# "note": String (optional)
# "entryBlockId": String (optional)
# "date": String
# "blocks": Array[Dictionary]
# "connections": Array[Dictionary]

Connections

Connections are the wires between blocks — they define which block leads to which. In the editor, you draw them visually; in the export, they become a flat list of source → target links defined by the BlueprintConnection interface:

ts
interface BlueprintConnection {
  id: string;
  fromId: string;
  toId: string;
  fromPort: string;
  toPort: string;
  fromPortIndex?: number;
}
csharp
public class BlueprintConnection {
    public string Id { get; set; }
    public string FromId { get; set; }
    public string ToId { get; set; }
    public string FromPort { get; set; }
    public string ToPort { get; set; }
    public int? FromPortIndex { get; set; }
}
cpp
struct BlueprintConnection {
    std::string id;
    std::string fromId;
    std::string toId;
    std::string fromPort;
    std::string toPort;
    std::optional<int> fromPortIndex;
};
gdscript
# Dictionary with keys:
# "id": String
# "fromId": String
# "toId": String
# "fromPort": String
# "toPort": String
# "fromPortIndex": int (optional)

You won't typically need to inspect connections directly — the engine handles routing internally. They are however exposed in onValidateNextBlock if needed.

Dictionaries

Dictionaries describe the registers of your game — switches, variables, inventory. The developer declares them in the LSDE editor to expose available game variables to the narrative designer. At runtime, the developer maps each dictionary to the corresponding system in their game. Conditions and onResolveCondition use these keys to evaluate game state. Defined by the Dictionary interface:

ts
interface Dictionary {
  uuid: string;
  id: string;
  rows: DictionaryRow[];
}

interface DictionaryRow {
  key: string;
}
csharp
public class LsdeDictionary {
    public string Uuid { get; set; }
    public string Id { get; set; }
    public List<DictionaryRow> Rows { get; set; }
}

public class DictionaryRow {
    public string Key { get; set; }
}
cpp
struct LsdeDictionary {
    std::string uuid;
    std::string id;
    std::vector<DictionaryRow> rows;
};

struct DictionaryRow {
    std::string key;
};
gdscript
# Dictionary with keys:
# "uuid": String
# "id": String
# "rows": Array[{"key": String}]

Action Signatures

Signatures describe the action types available in your game — set_flag, play_sound, give_item. The developer declares them in the LSDE editor so that narrative designers can compose action sequences with typed parameters. At runtime, the signature id is what the developer maps to their own systems. Defined by the ActionSignature interface:

ts
interface ActionSignature {
  uuid: string;
  id: string;
  params: SignatureParam[];
}

interface SignatureParam {
  label?: string;
  type: 'boolean' | 'string' | 'number' | 'enum' | 'dictionary';
  dictionaryGroupUuid?: string;
  enumOptions?: { id: string; label?: string }[];
}
csharp
public class ActionSignature {
    public string Uuid { get; set; }
    public string Id { get; set; }
    public List<SignatureParam> Params { get; set; }
}

public class SignatureParam {
    public string? Label { get; set; }
    public string Type { get; set; }
    public string? DictionaryGroupUuid { get; set; }
    public List<EnumOption>? EnumOptions { get; set; }
}
cpp
struct ActionSignature {
    std::string uuid;
    std::string id;
    std::vector<SignatureParam> params;
};

struct SignatureParam {
    std::optional<std::string> label;
    std::string type;
    std::optional<std::string> dictionaryGroupUuid;
    std::vector<EnumOption> enumOptions;
};
gdscript
# ActionSignature Dictionary:
# "uuid": String
# "id": String
# "params": Array[SignatureParam]
#
# SignatureParam Dictionary:
# "label": String (optional)
# "type": "boolean" | "string" | "number" | "enum" | "dictionary"
# "dictionaryGroupUuid": String (optional)
# "enumOptions": Array[{"id": String, "label": String?}] (optional)