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

UTP Format (Placeable Blueprint)

Description: The Placeable (.utp) blueprint dictates the configuration of universally interactive scenery and containers within a map. Ranging from simple locked footlockers to rigged command consoles and explodable starship barricades, .utp structs blend physical static properties (like structural HP and lock difficulties) with heavy dynamic script bindings.

At a Glance

PropertyValue
Extension(s).utp
Magic SignatureUTP / V3.2
TypePlaceable Blueprint
Rust ReferenceView rakata_generics::Utp in Rustdocs

Data Model Structure

Rakata maps the Placeable definition directly into the rakata_generics::Utp 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 Placeable breaks down into five main categories:

  1. Core Identity & Geometry: The configuration for what the placeable looks like, its faction, and the text displayed when targeted (e.g., Appearance, TemplateResRef, LocName).
  2. Interactive State & Dialogue: Flags determining if the placeable can be clicked, if it starts a conversation/computer sequence, or if it acts as a loot container (e.g., Useable, Conversation, HasInventory).
  3. 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).
  4. Health & Destruction: The physical integrity of the object, defining if it can be destroyed and its defensive thresholds (e.g., HP, Hardness, Static, Plot).
  5. Behavioral Hooks (Scripts): The scripts that run when a player explores, attacks, or opens the placeable (e.g., OnOpen, OnInvDisturbed, OnDamaged).
  • State Validation: rakata-lint checks the data against engine constraints to prevent runtime bugs.

Engine Audits & Decompilation

(Decompilation logic for this section was entirely audited and verified via native Ghidra pipeline against swkotor.exe, explicitly pulling from CSWSPlaceable::LoadPlaceable at 0x00585670.)

Because Placeables act as physical junctions for event hooking, they expose a massive suite of script triggers natively.

Structural Load Phasing

FunctionSizeBehavior
LoadPlaceable5092 BThe primary physical parser evaluating 46 core metrics including health, conversation dialogues, basic trap bindings, and physical alignment states.
ReadScriptsFromGff–Attaches 16 dedicated script hooks dictating behavior when the placeable is bashed, opened, unlocked, or triggered.

Core Structural Findings

Engine RuleRuntime Behavior
Appearance TruncationThe engine reads Appearance as a 32-bit integer but forcefully truncates it to a single byte. Any ID above 255 automatically wraps to 0 and physically breaks the placeable model rendering.
Static vs. Plot ChainingJust like Doors, if a Placeable is marked Static=1, the engine completely overrides all other behaviors and acts as if Plot=1 is true, making the placeable totally indestructible even if it has an HP value defined.
Default Usability CheckIf the Static toggle is completely missing from the binary file, the engine automatically derives it by actively checking if the Placeable is marked as usable (!Useable).
Ground Pile ForcingThe engine reads whatever value you place in GroundPile, but physically overwrites it and forces it to 1 in memory, making native static configuration of this field utterly pointless.
Missing Door HooksToolsets erroneously expose OnFailToOpen for Placeables, but the engine specifically treats this as a Door-exclusive (.utd) script hook and completely ignores it here.
Trap Hook FallbackIf a trap bounds check fails or the OnTrapTriggered script is left blank, the engine automatically attempts to read the traps.2da table and pulls the default script based on the specific TrapType.

Legacy & Ignored Data

Finding TypeExplanation
Legacy Engine ArtifactsPlaceable binaries are littered with legacy metrics from older tools or other Odyssey games (Comment, OpenLockDiff, Interruptable, Type, PaletteID). The physical KOTOR engine constructor entirely ignores these.

Implemented Linter Rules (Rakata-Lint)

These static constraints are targeted for implementation under rakata_lint::rules::utp.

  1. Appearance Truncation: (Pending) Prevents rendering crashes by asserting Appearance never mathematically exceeds 255.
  2. Plot Chaining Context: (Pending) Asserts that if Static=1 is defined, Plot must explicitly match the forced reality of being indestructible.
  3. Ghost Value Detection: (Pending) Warns when GroundPile defaults to anything structurally since the engine forces it to 1.
  4. Dead Hook Pruning: (Pending) Flags OnFailToOpen instances because Placeables physically lack the event memory map to trigger it.
  5. HP Health Ceiling: (Pending) Confirms CurrentHP is less than or mathematically equal to HP, preventing immediate game-break physics on spawn.
  6. Animation Conditional Limits: (Pending) Verifies that custom AnimationState indices are strictly guarded by Open==0 closures.