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
| Property | Value |
|---|---|
| Extension(s) | .utp |
| Magic Signature | UTP / V3.2 |
| Type | Placeable Blueprint |
| Rust Reference | View 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:
- Core Identity & Geometry: The configuration for what the placeable looks like, its faction, and the text displayed when targeted (e.g.,
Appearance,TemplateResRef,LocName). - 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). - 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). - Health & Destruction: The physical integrity of the object, defining if it can be destroyed and its defensive thresholds (e.g.,
HP,Hardness,Static,Plot). - Behavioral Hooks (
Scripts): The scripts that run when a player explores, attacks, or opens the placeable (e.g.,OnOpen,OnInvDisturbed,OnDamaged).
- State Validation:
rakata-lintchecks 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
| Function | Size | Behavior |
|---|---|---|
LoadPlaceable | 5092 B | The 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 Rule | Runtime Behavior |
|---|---|
| Appearance Truncation | The 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 Chaining | Just 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 Check | If 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 Forcing | The 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 Hooks | Toolsets 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 Fallback | If 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 Type | Explanation |
|---|---|
| Legacy Engine Artifacts | Placeable 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.
- Appearance Truncation: (Pending) Prevents rendering crashes by asserting
Appearancenever mathematically exceeds255. - Plot Chaining Context: (Pending) Asserts that if
Static=1is defined,Plotmust explicitly match the forced reality of being indestructible. - Ghost Value Detection: (Pending) Warns when
GroundPiledefaults to anything structurally since the engine forces it to1. - Dead Hook Pruning: (Pending) Flags
OnFailToOpeninstances because Placeables physically lack the event memory map to trigger it. - HP Health Ceiling: (Pending) Confirms
CurrentHPis less than or mathematically equal toHP, preventing immediate game-break physics on spawn. - Animation Conditional Limits: (Pending) Verifies that custom
AnimationStateindices are strictly guarded byOpen==0closures.