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

UTE Format (Encounter Blueprint)

Description: The Encounter (.ute) blueprint defines interactive spawn points and boundary triggers across a level map. Instead of acting merely as a spatial zone, encounters handle complex difficulty scaling, bubble-sort creature limits, and explicit coordinate vertices to dynamically deploy combatants when a player crosses their geometry bounds.

At a Glance

PropertyValue
Extension(s).ute
Magic SignatureUTE / V3.2
TypeEncounter Blueprint
Rust ReferenceView rakata_generics::Ute in Rustdocs

Data Model Structure

Rakata maps the Encounter definition directly into the rakata_generics::Ute 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.

An Encounter breaks down into four main categories:

  1. Spawn Population (CreatureList): The list of creature blueprints the encounter can spawn.
  2. Difficulty & Limits: Setting how many creatures spawn at once and how difficult they should be relative to the player (e.g., MaxCreatures, DifficultyIndex).
  3. Trigger Boundaries (Geometry): The coordinates defining the physical tripwire that triggers the spawn.
  4. Behavioral Hooks (Scripts): The scripts that run when a player enters or exits the trigger, or when the spawn pool runs dry (e.g., OnEntered, OnExhausted).
  • Model Validation: rakata-lint checks the data against engine constraints to prevent fatal runtime crashes.

Engine Audits & Decompilation

The following information documents the engine’s exact load sequence and field requirements for .ute files mapped from swkotor.exe.

(Decompilation logic for this section was audited and verified via native Ghidra pipeline against swkotor.exe, explicitly pulling from the primary dispatcher CSWSEncounter::LoadEncounter at 0x00593830.)

Structural Load Phasing

The engine processes an Encounter structurally across several chunked subroutines, each responsible for unique spatial and logic bindings.

FunctionSizeBehavior
ReadEncounterFromGff3445 BThe initial pass that sets up the encounter’s identity, difficulty limits, and the spawn list.
ReadEncounterScriptsFromGff567 BAttaches scripts that trigger when players enter, exit, or exhaust the spawn pool.
LoadEncounterSpawnPoints364 BReads the coordinates so the engine knows exactly where to spawn the creatures.
LoadEncounterGeometry651 BReads the coordinates that trace the trigger’s boundaries on the floor.

Core Structural Findings

The engine rigorously evaluates geometric and spatial boundaries. Improper definitions break the spawn mapping algorithm.

Warning

Understanding Fatal Log Drops While minor coordinate math errors usually just cause creatures to spawn inside walls, failing strict geometry constraints causes KOTOR to abruptly abort parsing the Encounter. Specifically, if a .ute file declares it has geometry boundaries but fails to provide the actual coordinate vertices, the engine dumps a fatal error to its trace log and refuses to spawn the encounter at all.

Engine RuleRuntime Behavior
Tag OverridesThe engine forcefully converts any Tag to all-lowercase via CSWSObject::SetTag. Any static casing is lost immediately upon load.
Geometry IntegrityIf Geometry is explicitly defined but has 0 vertices, the engine logs a “has geometry, but no vertices” error and aborts loading the encounter entirely.
Geometry SynthesisIf the Geometry list is completely omitted from the blueprint, the engine falls back and safely synthesizes a default 4-vertex spatial box.
Difficulty ResolutionThe engine prioritizes using DifficultyIndex to look up the difficulty in encdifficulty.2da. The static Difficulty field is ignored unless the 2DA table fails to resolve.
Bubble SortingUpon loading the CreatureList, the engine runs a Bubble Sort algorithm to firmly re-order the encounter’s spawn pool by ascending CR (Challenge Rating), completely overriding any custom static display order.
Area InstantiationAreaList buffer allocation size is strictly dictated by AreaListMaxSize. If the real list exceeds this size, the buffer will silently overrun.

Legacy & Ignored Data

Finding TypeExplanation
Passive Legacy ArtifactsUnused fields left over from older tools or Odyssey branches (e.g., TemplateResRef, Comment, PaletteID) are completely dark. The engine inherently ignores them.
Superseded Legacy FieldsThe static Difficulty field is a completely inactive legacy metric as long as DifficultyIndex maps to a valid row inside encdifficulty.2da.

Implemented Linter Rules (Rakata-Lint)

These rules are documented for engine parity but are not yet implemented into rakata-lint/src/rules/.

  1. Dead Difficulty Traces: (Pending) Flags instances where a file statically defines Difficulty alongside a valid DifficultyIndex.
  2. Deficient Spawn Loops: (Pending) Warns when an Encounter evaluates as Active but initializes a completely empty CreatureList.
  3. Dead Field Evaluation: (Pending) Maps extraneous legacy engine artifacts (TemplateResRef, Comment, PaletteID) as dead fields.