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

UTT Format (Trigger Blueprint)

Description: The Trigger (.utt) blueprint defines invisible zones placed across level maps. While encounters spawn creatures, triggers operate as tripwires – firing scripts, acting as loading zones to new areas, or springing mechanical traps when a character crosses them.

At a Glance

PropertyValue
Extension(s).utt
Magic SignatureUTT / V3.2
TypeTrigger Blueprint
Rust ReferenceView rakata_generics::Utt in Rustdocs

Data Model Structure

Rakata maps the Trigger definition directly into the rakata_generics::Utt 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 Trigger breaks down into four main categories:

  1. Core Identity & Geometry: The basic identifiers and coordinate boundaries that define what the trigger is and where it sits on the ground (e.g., Tag, Geometry).
  2. Interactive State & Sub-types: Settings that determine if the trigger acts as a loading zone, a trap, or just a generic scripting boundary (e.g., Type, Cursor, HighlightHeight).
  3. Trap Mechanics: The parameters defining rules for trap visibility and skill checks required to disarm them (e.g., TrapType, TrapOneShot).
  4. Transition & Behavioral Hooks (Scripts): The event scripts that fire when a character enters, clicks, leaves, or disarms the trigger, as well as the destination area if the trigger acts as a loading zone (e.g., ScriptOnEnter, LinkedTo).
  • State Validation: rakata-lint checks the GFF structure directly against the constraints the engine expects.

Engine Audits & Decompilation

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

Structural Load Phasing

FunctionSizeBehavior
LoadTrigger3381 BThe main constructor. It reads the trigger’s properties, scripts, and trap rules.
LoadTriggerGeometry743 BReads the X, Y, and Z coordinates that draw the trigger’s boundary on the floor.

Core Structural Findings

Engine RuleRuntime Behavior
Behavior Derived from TypeThe engine determines the trigger’s behavior and UI cursor based on the Type field. Type 1 makes it a map transition zone. Type 2 makes it a trap.
OnClick Duplication BugThe engine has a known bug where it copies the ScriptOnEnter value and uses it to overwrite the OnClick listener by default, unless explicitly overridden.
Trap Hook FallbackIf the OnTrapTriggered script is left empty, set to null, or named "default", the engine ignores it and pulls the default script from traps.2da based on the TrapType.
Highlight ClampingThe trigger’s HighlightHeight is ignored by the engine unless it is greater than 0.0. If it is exactly zero or negative, the engine falls back to a default rendering height of 0.1.
Contextual LoadingFields like LinkedTo, LinkedToModule, AutoRemoveKey, Tag, and Faction are only loaded into memory when the Trigger is processed from a .git area layout file.
Portrait ShadowingIf 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.

Legacy & Ignored Data

Finding TypeExplanation
Legacy Engine ArtifactsAs with other templates, older asset revisions include TemplateResRef, Comment, PaletteID, and PartyRequired. The engine completely ignores these.
Superseded Legacy FieldsOlder asset revisions typically map TrapDetectDC and DisarmDC in the .utt file itself, but the engine ignores them – it calculates DCs dynamically using the rules in the .2da files instead.

Implemented Linter Rules (Rakata-Lint)

Phase 1 (intra-resource, no context)

Implemented under rakata_lint::rules::utt.

  1. UTT-001 (Transition Enforcement): Warns when Type==1 (Transition) but no destination (LinkedTo, LinkedToModule, or TransitionDestin) is configured.
  2. UTT-002 (Trap Consistency): Informs when TrapDetectDC/DisarmDC are set (engine reads from traps.2da); also warns when TrapFlag=true but Type != 2.
  3. UTT-003 (Geometry Safety): Warns when the trigger’s geometry contains fewer than 3 vertices.
  4. UTT-004 (OnClick on Generic Trigger): Informs when OnClick is set on a Generic trigger (Type==0); the event only fires for Transition triggers.
  5. UTT-005 (Highlight Bounding): Informs when HighlightHeight <= 0.0; the engine falls back to a default of 0.1.
  6. UTT-006 (Portrait Shadowing): Warns when PortraitId < 0xFFFE and Portrait resref is set; the resref is ignored at runtime.
  7. UTT-007 (PartyRequired Dead Data): Informs when PartyRequired is set; the K1 engine never reads this field.

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

Implemented under rakata_lint::rules::utt_range.

  1. UTT-008 (Portrait Bounds): Errors when PortraitId (when not the 0xFFFE “use string Portrait” sentinel) does not resolve to a row in portraits.2da.
  2. UTT-009 (Resref Existence): Warns when any of OnDisarm, OnTrapTriggered, OnClick, OnHeartbeat, OnEnter, OnExit, or OnUserDefined (.ncs), or Portrait (.tga), does not resolve in the configured resource sources. LinkedToModule (area transition) is deferred to Phase 3.

Pending

  • Default Script Identification: Identifies empty / null / literally-named "default" OnTrapTriggered entries that silently invoke the traps.2da fallback.