UTW Format (Waypoint Blueprint)
Description: The Waypoint (.utw) blueprint defines static reference coordinates within an area map. Unlike functional triggers or physical placeables, waypoints act exclusively as invisible logic markers. They provide coordinate anchors for creature patrol routes, spawn locations, camera focal points, or visible map pins in the player’s UI.
At a Glance
| Property | Value |
|---|---|
| Extension(s) | .utw |
| Magic Signature | UTW / V3.2 |
| Type | Waypoint Blueprint |
| Rust Reference | View rakata_generics::Utw in Rustdocs |
Data Model Structure
Rakata maps the Waypoint definition directly into the rakata_generics::Utw 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 Waypoint breaks down into three main categories:
- Core Identity: The basic identifiers that define the waypoint’s name and tag used heavily by scripts (e.g.,
Tag,LocalizedName). - Spatial Geometry: The exact map coordinates and facing orientation that creatures or cameras will reference (e.g.,
XPosition,XOrientation). - Map Navigation Notes: The text and toggles that dictate whether the waypoint draws a physical pin on the player’s mini-map UI (e.g.,
HasMapNote,MapNote).
- State Validation:
rakata-lintchecks the data against engine constraints to prevent runtime bugs or dead data paths.
Engine Audits & Decompilation
The following documents the engine’s exact load sequence and field requirements for .utw files mapped from swkotor.exe.
(Decompilation logic for this section was audited and verified via native Ghidra pipeline against swkotor.exe, explicitly pulling from CSWSWaypoint::LoadWaypoint at 0x005c7f30.)
Structural Load Phasing
| Function | Size | Behavior |
|---|---|---|
LoadWaypoint | 682 B | The main constructor. It loads the waypoint’s identity, map geometry, and checks for mini-map pins. |
LoadFromTemplate | 134 B | A fallback used when dynamically spawning a waypoint from a script. |
Core Structural Findings
| Engine Rule | Runtime Behavior |
|---|---|
| Map Note Two-Gate Pattern | If HasMapNote is 0 or missing, the engine skips reading the map note entirely. If it is 1, it reads the strings but uses a second gate: if the MapNote string itself is missing, the entire map pin block is discarded silently. |
| Orientation Normalization | The engine computes the squared magnitude of the orientation vectors. If it is not exactly 1.0, it automatically calls Vector::Normalize() to fix the math. Non-unit vectors are tolerated but corrected instantly at load. |
| Position Override | When a waypoint is loaded from a .git area layout via LoadWaypoints, the engine re-reads the X and Y coordinates directly from the .git file, completely overriding the .utw. It also forcefully calculates the Z height based on the terrain collision mesh via ComputeHeight. |
| Dynamic Identification | Waypoints never pull an ObjectId from their own .utw file. It is always forcibly assigned by the .git list element (defaulting to 0x7f000000). |
Legacy & Ignored Data
| Finding Type | Explanation |
|---|---|
| Superseded Legacy Fields | Older asset revisions pad the file with fields like TemplateResRef, Appearance, PaletteID, Comment, LinkedTo, and Description. The KOTOR engine completely ignores these. |
Implemented Linter Rules (Rakata-Lint)
These static constraints are targeted for implementation under rakata_lint::rules::utw.
- Tag enforcement: (Pending) Flags if
Tagis completely empty, as waypoints are primarily targeted by scripts. - Boolean Clamping: (Pending) Ensures
HasMapNoteacts properly as a BYTE constraint. - Double-Gating Check: (Pending) Detects dead data patterns where
MapNoteorMapNoteEnabledare defined butHasMapNoteis configured to0. - Orientation Warnings: (Pending) Warns if orientation vectors do not mathematically normalize to ~
1.0, documenting the engine’s forced correction.