Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

PropertyValue
Extension(s).dlg
Magic SignatureDLG / V3.2
TypeDialogue Blueprint
Rust ReferenceView 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 DlgAnimation and DlgCamera models).
  • (Note: rakata-lint does not currently implement behavioral validation for .dlg formats.)

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 CategoryEngine Property & TypeNotable Default or Behavioral Quirk
Identity & RulesCameraModel (ResRef), DelayEntry/Reply (DWord)Standard execution behaviors.
Identity & RulesSkippable (Byte)Defaults to 1 (True).
Logic HooksEndConversation, EndConverAbort (ResRefs)Fire when the dialogue terminates abruptly or via conclusion.
Hardware InterfacingConversationType (Int)0 = Cinematic, 1 = Computer, 2 = Special. Cinematic explicitly unstealths the party.
Hardware InterfacingComputerType (Byte)Only evaluated if ConversationType is 1. Otherwise, completely dead data.
Equipment & ActionsUnequipItems, UnequipHItem, AnimatedCutAnimatedCut 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.

FieldTypeEngine Evaluation
TextLocStringThe spoken localized string.
Script, Speaker, QuestStrings/ResRefsStandard execution scripts and entity mapping.
Sound, VO_ResRefResRefSound 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.
DelayDWordDelay Special Case: If value is 0xFFFFFFFF, the engine explicitly reads from the root DelayEntry/DelayReply field instead and modulates WaitFlags!
FadeTypeByteDetermines the FadeDelay and FadeLength. If set to 0 or missing, all fade configurations are zeroed inherently.

Viewport Framing (LoadDialogCamera)

FieldTypeEngine Evaluation
CameraIDINTDependent Field: Only permitted when CameraAngle = 6 (Placeable Camera). Otherwise, the engine forces the ID to -1 regardless of the static binary value.
CamFieldOfViewFLOATAggressively validated. If the property is entirely missing or is explicitly negative, the engine forces the perspective to -1.0.
CamHeightOffset, TarHeightOffsetFLOATStandard float deltas.

Relational Data Trees

Dialogues operate as highly interconnected link-lists.

  • Entry -> Reply Links (RepliesList within an Entry Node): Maps the Index (DWORD) to the overarching .ReplyList bounds. Unique in that it exclusively parses the DisplayInactive Byte.
  • Reply -> Entry Links (EntriesList within a Reply Node): Maps the Index to the .EntryList bounds.
  • Start Indices (StartingList): Uses the exact same linkage schema as a Reply->Entry link. Validates Index against entry_count.

Warning

Corrupted Link Constraints Index paths are strictly evaluated against the internal array bounds prior to traversing. If a node tries to link out of bounds, it immediately triggers a fatal Load Failure within the engine.

Ancillary Configuration Lists

  • AnimList: Defines custom Participant models and their accompanying Animation (WORD) action index to loop.
  • StuntList: Dictates which StuntModel should proxy standard rendering behavior for a given Participant.

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:

  1. Camera Angle Compliance: Detect if CameraID holds a value while CameraAngle is anything other than 6, warning that the data is ignored by the engine.
  2. Conversation Type Mismatch: Warn if a ComputerType sub-property is set, but the parent ConversationType is not explicitly flagged to 1 (Computer Dialog).
  3. Ghost Delay Flags: Warn when an entry delay is maxed (0xFFFFFFFF), but execution triggers evaluate to an instantaneous termination sequence (Warning on Sound invalidation).
  4. Fatal Bounds Checking: Statically trace every Index parameter in node link-lists to ensure they never exceed array bounds and cause an engine hard-stop.
  5. Context Zeroing: Inform the developer if fade delays are configured, but the parent FadeType is 0, causing the engine to discard the timings.