DLG Format (Dialogue Blueprint)
Description: The Dialogue (.dlg) format is the beating heart of KOTOR’s storytelling. It acts as the master “script” for every conversation, cutscene, and cinematic sequence. Rather than just holding localized text, it acts as a branching storyboard that tells the engine exactly what the characters should say in audio, what animations they should perform, which camera angles to use, and when to fire off scripts that impact the plot.
At a Glance
| Property | Value |
|---|---|
| Extension(s) | .dlg |
| Magic Signature | DLG / V3.2 |
| Type | Dialogue Blueprint |
| Rust Reference | View rakata_generics::Dlg in Rustdocs |
Data Model Structure
Rakata parses the raw GFF structure into the rakata_generics::Dlg struct.
- Typestate Extraction: By extracting the loosely-typed GFF binary into a strict Rust struct, Rakata replaces unsafe dynamic string queries with compile-time guaranteed data types (such as
DlgAnimationandDlgCameramodels). - (Note:
rakata-lintdoes not currently implement behavioral validation for.dlgformats.)
Engine Audits & Decompilation
The following documents the engine’s exact load sequence and field requirements for .dlg files mapped from swkotor.exe.
(Decompilation logic for this section was entirely audited and verified via native Ghidra pipeline against swkotor.exe, explicitly pulling from CSWSDialog::LoadDialog (0x005a2ae0), cascading through LoadDialogBase (0x005a11c0) and LoadDialogCamera (0x005a1ab0).)
The LoadDialog subroutine processes the root-level conversation configuration before iterating over the heavily nested EntryList and ReplyList. For each of those conversational nodes, it delegates parsing to LoadDialogBase (for text and scripts) and LoadDialogCamera (for viewport directions).
Additionally, StartingList provides the dialogue entry points, while the StuntList associates cutscene actor models.
Root Conversation Configuration
| Field Category | Engine Property & Type | Notable Default or Behavioral Quirk |
|---|---|---|
| Identity & Rules | CameraModel (ResRef), DelayEntry/Reply (DWord) | Standard execution behaviors. |
| Identity & Rules | Skippable (Byte) | Defaults to 1 (True). |
| Logic Hooks | EndConversation, EndConverAbort (ResRefs) | Fire when the dialogue terminates abruptly or via conclusion. |
| Hardware Interfacing | ConversationType (Int) | 0 = Cinematic, 1 = Computer, 2 = Special. Cinematic explicitly unstealths the party. |
| Hardware Interfacing | ComputerType (Byte) | Only evaluated if ConversationType is 1. Otherwise, completely dead data. |
| Equipment & Actions | UnequipItems, UnequipHItem, AnimatedCut | AnimatedCut forces a global unpauseable state within the client if non-zero. |
Shared Dialogue Node Properties (LoadDialogBase)
These fields apply to both entries (NPC spoken) and replies (Player spoken), and are parsed via LoadDialogBase.
| Field | Type | Engine Evaluation |
|---|---|---|
Text | LocString | The spoken localized string. |
Script, Speaker, Quest | Strings/ResRefs | Standard execution scripts and entity mapping. |
Sound, VO_ResRef | ResRef | Sound Fallback: If Sound fails to execute, the engine will attempt to play VO_ResRef. If both fail, the bitmask SoundExists is forcibly downgraded to 0. |
Delay | DWord | Delay Special Case: If value is 0xFFFFFFFF, the engine explicitly reads from the root DelayEntry/DelayReply field instead and modulates WaitFlags! |
FadeType | Byte | Determines the FadeDelay and FadeLength. If set to 0 or missing, all fade configurations are zeroed inherently. |
Viewport Framing (LoadDialogCamera)
| Field | Type | Engine Evaluation |
|---|---|---|
CameraID | INT | Dependent Field: Only permitted when CameraAngle = 6 (Placeable Camera). Otherwise, the engine forces the ID to -1 regardless of the static binary value. |
CamFieldOfView | FLOAT | Aggressively validated. If the property is entirely missing or is explicitly negative, the engine forces the perspective to -1.0. |
CamHeightOffset, TarHeightOffset | FLOAT | Standard float deltas. |
Relational Data Trees
Dialogues operate as highly interconnected link-lists.
- Entry -> Reply Links (
RepliesListwithin an Entry Node): Maps theIndex(DWORD) to the overarching.ReplyListbounds. Unique in that it exclusively parses theDisplayInactiveByte. - Reply -> Entry Links (
EntriesListwithin a Reply Node): Maps theIndexto the.EntryListbounds. - Start Indices (
StartingList): Uses the exact same linkage schema as a Reply->Entry link. ValidatesIndexagainstentry_count.
Warning
Corrupted Link Constraints
Indexpaths are strictly evaluated against the internal array bounds prior to traversing. If a node tries to link out of bounds, it immediately triggers a fatalLoad Failurewithin the engine.
Ancillary Configuration Lists
- AnimList: Defines custom
Participantmodels and their accompanyingAnimation(WORD) action index to loop. - StuntList: Dictates which
StuntModelshould proxy standard rendering behavior for a givenParticipant.
Proposed Linter Rules
The rakata-lint dialogue ruleset has not been formally implemented yet. However, the following diagnostics are heavily recommended to combat engine failure domains directly derived from these decompilation audits:
- Camera Angle Compliance: Detect if
CameraIDholds a value whileCameraAngleis anything other than6, warning that the data is ignored by the engine. - Conversation Type Mismatch: Warn if a
ComputerTypesub-property is set, but the parentConversationTypeis not explicitly flagged to1(Computer Dialog). - Ghost Delay Flags: Warn when an entry delay is maxed (
0xFFFFFFFF), but execution triggers evaluate to an instantaneous termination sequence (Warning onSoundinvalidation). - Fatal Bounds Checking: Statically trace every
Indexparameter in node link-lists to ensure they never exceed array bounds and cause an engine hard-stop. - Context Zeroing: Inform the developer if fade delays are configured, but the parent
FadeTypeis0, causing the engine to discard the timings.