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

UTD Format (Door Blueprint)

Description: The Door (.utd) blueprint defines interactive pathways on a level map. Beyond acting as physical barriers or transitions between areas, doors house lock mechanics, trap configurations, script hooks, and basic visual states (open, destroyed, jammed).

At a Glance

PropertyValue
Extension(s).utd
Magic SignatureUTD / V3.2
TypeDoor Blueprint
Rust ReferenceView rakata_generics::Utd in Rustdocs

Data Model Structure

Rakata maps the Door definition directly into the rakata_generics::Utd struct. To view the exhaustive binary schema and strict GFF field mappings, please refer to the Rustdocs for this struct, where each field is explicitly documented.

A Door breaks down into four main categories:

  1. Core Identity & Geometry: The configuration for what the door looks like, its faction, and the text displayed when targeted (e.g., Appearance, TemplateResRef, LocName).
  2. Lock & Trap Mechanics: The parameters defining whether it’s locked, what key is needed, and rules for any attached traps (e.g., Locked, KeyName, TrapType, DisarmDC).
  3. Transition Pathways: The linked destination used when a door acts as a loading zone to another area (e.g., LinkedTo, LinkedToFlags).
  4. Behavioral Hooks (Scripts): The scripts that run when a player opens, destroys, or fails to unlock the door (e.g., OnOpen, OnFailToOpen, OnMeleeAttacked).
  • Active Validation: rakata-lint enforces checks against missing keys or invalid transition references before a module ever reaches the game engine.

Engine Audits & Decompilation

The following information documents the engine’s exact load sequence and field requirements for .utd 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 the primary dispatcher CSWSDoor::LoadDoor at 0x0058a1f0.)

Structural Load Phasing

The engine processes a Door structurally by mapping its sub-fields into distinct operational constraints.

DomainSub-fields EvaluatedPurpose
Scales & State22Reads the physical health, visual appearance, and base traits determining whether the door is locked or indestructible.
Hooks15Attaches custom event scripts that fire when the door is opened, forced, unlocked, or trapped.
Mechanical9Configures the lock difficulty tiers and the specific skill hurdles required to detect and disarm any attached traps.
Transitions4Links the door strictly to another area (.are), turning it into a physical loading screen transition node.

Core Structural Findings

The CSWSDoor parser natively guarantees strict state adjustments upon parsing.

Engine RuleRuntime Behavior
Appearance TruncationThe engine reads Appearance as a 32-bit integer but forcefully truncates it to a single byte ((byte)uVar5). Any ID above 255 automatically wraps to 0 and breaks the physical door model.
Static EnforcementIf the door is marked Static, the engine automatically forces plot = 1. This safely guarantees that static level architecture cannot be destroyed by players.
Portrait ShadowingIf PortraitId is 0, the engine hardcodes it to 0x22E. If PortraitId is < 0xFFFE, the engine completely ignores the Portrait string ResRef and relies entirely on the ID. Any value in the Portrait ResRef field is treated as dead data.
Trap Hook FallbackIf the OnTrapTriggered script is left empty, set to null, or literally named "default", the engine pulls the default standard script from traps.2da instead.
HP SynchronizationCurrentHP is securely clamped against the door’s maximum HP to prevent overflow bugs.

Legacy & Ignored Data

Finding TypeExplanation
Legacy Engine Artifacts7 explicitly mapped template structures (like AnimationState, NotBlastable, OpenLockDiff) are Neverwinter Nights or KOTOR 2 legacy dependencies inherently ignored by the K1 parser.

Implemented Linter Rules (Rakata-Lint)

Phase 1 (intra-resource, no context)

Implemented under rakata_lint::rules::utd.

  1. UTD-001 (Static Parity): Warns when Static=true but Plot=false; the engine forces Plot to true at runtime.
  2. UTD-002 (HP Bounds): Errors when CurrentHP > HP; the engine clamps to HP on template load.
  3. UTD-003 (Portrait Shadowing): Warns when PortraitId < 0xFFFE and Portrait resref is set; the resref is ignored at runtime.

Phase 2 (range / 2DA / resref existence, requires LintContext)

Implemented under rakata_lint::rules::utd_range.

  1. UTD-004 (Generic Door Type Bounds): Errors when GenericType does not resolve to a row in genericdoors.2da; engine renders missing model.
  2. UTD-005 (Portrait Bounds): Errors when PortraitId (when not the 0xFFFE “use string Portrait” sentinel) does not resolve to a row in portraits.2da.
  3. UTD-006 (Resref Existence): Warns when Conversation (.dlg), Portrait (.tga), or any of the 15 On* script hooks (.ncs) does not resolve in the configured resource sources. LinkedToModule (area transition) is deferred to Phase 3.

Pending

  • Appearance Truncation: Flags legacy Appearance (u32) values above 255 (engine truncates to a single byte).
  • Trap Hook Fallback Detection: Scans for empty / null / literally-named "default" OnTrapTriggered references that silently invoke the traps.2da fallback.
  • Portrait Zero Hardcode: Detects PortraitId == 0 mappings since the engine hardcodes lookup to 0x22E.