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).
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) | DelayEntry and DelayReply safely default to 0 if missing. |
| Identity & Rules | Skippable (Byte) | Explicitly defaults to 1 (True) if missing. |
| Logic Hooks | EndConversation, EndConverAbort (ResRefs), AmbientTrack | Fire when the dialogue terminates abruptly or via conclusion. Fallback to empty strings "" if missing. |
| 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, standard camera positioning and animations are bypassed. |
| Equipment & Actions | UnequipItems, UnequipHItem, AnimatedCut, OldHitCheck | AnimatedCut forces a global unpauseable state if non-zero. AnimatedCut and OldHitCheck default to 0. |
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.
Implemented Linter Rules (Rakata-Lint)
Phase 1 (intra-resource, no context)
Implemented under rakata_lint::rules::dlg.
- DLG-001 (Camera Angle Compliance): Warns when
CameraIDis populated whileCameraAngle != 6; the engine forces the ID to -1. - DLG-002 (Conversation Type Mismatch): Warns when
ComputerTypeis set butConversationType != 1(Computer Dialog); ComputerType is dead data otherwise. - DLG-003 (Ghost Delay Flags): Warns when an entry delay is maxed (
0xFFFFFFFF) but no sound/VO is configured and the parent fallback delay is 0; the node terminates instantly. - DLG-004 (Fatal Bounds Checking): Errors when any
Indexin a node’s link list, the starting list, or a reply list exceeds the target array bounds; this triggers a fatal engine load failure. - DLG-005 (Context Zeroing): Warns when
FadeDelay,FadeLength, orFadeColorare configured butFadeType=0; the engine discards the timings.
Phase 2 (resource existence, requires LintContext)
Implemented under rakata_lint::rules::dlg_range.
- DLG-006 (Resref Existence): Warns when any of
EndConversation/EndConverAbort(.ncs),CameraModel(.mdl),AmbientTrack(.wav), per-stuntStuntList[i].StuntModel(.mdl), or per-nodeScript(.ncs),Sound/VO_ResRef(.wav), andLinks[j].Activecondition scripts (.ncs) do not resolve in the configured resource sources.