ARE Format (Area Static Blueprint)
The Area (.are) blueprint format operates as the static environmental foundation of any game module. It establishes the rigid, overarching properties of a level, orchestrating the terrain’s grass rendering definitions, dynamic sunlight and fog constraints, ambient audio scale, and the primary interior/exterior state configurations. It effectively constructs the structural ‘stage’ that dynamic entities (like creatures and doors) populate later on.
At a Glance
| Property | Value |
|---|---|
| Extension(s) | .are |
| Magic Signature | ARE / V3.2 |
| Type | Area Static Blueprint |
| Rust Reference | View rakata_generics::Are in Rustdocs |
Data Model Structure
Rakata maps the Area definition directly into the rakata_generics::Are 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.
Engine Audits & Decompilation
The following documents the engine’s exact load sequence and field requirements for .are files mapped from swkotor.exe.
(Decompilation logic for this section was entirely audited and verified via native Ghidra pipeline against swkotor.exe, explicitly pulling from CSWSArea::LoadArea at 0x0050e190.)
The initial LoadArea dispatch branches out to parse the .are GFF, .lyt layout, .git instance tracking, and .pth bounds. The engine processes roughly 61 scalar fields, 4 scripts, 3 lists, and a nested minigame struct natively within the LoadAreaHeader subroutine.
Core Environmental Identity
| Field Category | Engine Property & Behavioral Quirk |
|---|---|
| Identity | Name (LocString), Comments (String), ID (Int) -> Standard definition strings. |
| Identity | Tag (String) -> Lowercased on load (via CExoString::LowerCase). The only tag to behave this way! |
| Scripts | OnHeartbeat, OnUserDefined, ... -> CResRef script payloads. |
| State Flags | Flags (DWord) -> Bit 0 explicitly marks an Interior environment. |
| State Flags | RestrictMode (Byte) -> Hardcoded Event: Changing this to a non-zero value during gameplay forces CSWPartyTable::UnstealthParty. |
Note
Internal Weather Truncation If
Flags(Bit 0) marks the area as an interior space, the engine zeros out all weather properties upon load, actively discarding any prior weather assignments.
Weather & Terrain Generation
| Field | Type | Engine Evaluation |
|---|---|---|
ChanceFog | INT | Stored persistently as an integer. |
ChanceRain, ChanceSnow, ChanceLightning, WindPower | INT | Warning: The engine explicitly truncates these INT properties to 8-bit bytes at runtime. Values over 255 silently wrap around. |
Grass_TexName | ResRef | If empty or invalid, the engine forces a hard fallback to "grass". |
AlphaTest | FLOAT | Defaults to 0.2 (older tools commonly assume 0.0). |
Area Lighting & Sun/Moon Tracking
KOTOR handles dynamic sunlight constraints separately between Sun and Moon.
| Property Groups | Type | Engine Evaluation |
|---|---|---|
Fog Ranges (MoonFogNear/Far, SunFogNear/Far) | FLOAT | Defaults to an immense distance of 10000.0. The engine aggressively clamps values to be ≥0.0. |
Tints (*AmbientColor, *DiffuseColor, *FogColor) | DWORD | Processed seamlessly as standard DWORD color masks. |
Environment Shadows (ShadowOpacity, *Shadows) | BYTE | Basic toggles and opacities orchestrating render limits. |
Map Transitions & Saving states
| Feature Category | Engine Evaluation & Triggers |
|---|---|
| Minimap Logic | Geographic vectors (MapResX, spatial coordinate structs like WorldPt1X) are only loaded if an actual Minimap TGA/TPC asset matching the level name exists on disk! |
| Parsing Type | If read, the engine parses MapPt along a dual-path logic checking if it is formally a FLOAT or INT type. |
| Zoom Bias | Area maps evaluate MapZoom to a default scaling scalar of 1, not 0! |
| Stealth Save-States | The stealth framework leverages the .are struct to snapshot .StealthXPMax and .StealthXPCurrent directly as DWORDs when parsing the layout. |
The Minigame Struct
Read via CSWMiniGame::Load (0x006723d0). If a minigame context triggers, the .are reads the nested Type (DWORD mapping 1=Swoop, 2=Turret). It injects highly specialized float properties modifying basic terrain speeds:
| Field | Injection Default / Constraint |
|---|---|
LateralAccel | Defaults safely to 60.0. |
MovementPerSec | Scales to 6.0 (Swoops), 90.0 (Turrets), or 0.0 otherwise! |
Bump_Plane | Bounds are heavily clamped to 0..3. |
| Nested Arrays | The struct natively requires sub-struct Player arrays (Models, Camera, Axes) and Enemy/Obstacles lists to operate properly. |
Implemented Linter Rules (Rakata-Lint)
Phase 1 (intra-resource, no context)
Implemented under rakata_lint::rules::are.
- ARE-001 (Context Discards): Warns when interior areas (
Flags & 1) carry non-zeroChanceRain,ChanceSnow,ChanceLightning, orWindPower; the engine discards weather for interiors. - ARE-002 (Weather Truncation): Warns when
ChanceRain,ChanceSnow,ChanceLightning, orWindPowerexceed 255; the engine truncates these to bytes at runtime. - ARE-003 (Fog Clamping): Warns when
MoonFogNear/FarorSunFogNear/Farare negative; the engine clamps fog distances to >= 0.0. - ARE-004 (Tag Lowercasing): Warns when
Tagcontains uppercase characters; the engine lowercases area tags on load. - ARE-005 (Toolset / K2 Fields): Informs when
DisableTransit,NoHangBack,PlayerOnly, orPlayerVsPlayerare set; never read by the K1 engine.
Phase 2 (resource existence, requires LintContext)
Implemented under rakata_lint::rules::are_range.
- ARE-006 (Resref Existence): Warns when any of
OnEnter,OnExit,OnHeartbeat, orOnUserDefined(.ncs) does not resolve, or when anyRooms[i].PartSounds[j].Sound(.wav) does not resolve in the configured resource sources.
Pending
- Grass Texture Fallback: Informs when
Grass_TexNameis empty; the engine treats this as the literal string"grass". - Texture / MiniGame Resref Existence:
DefaultEnvMap,Grass_TexName, and the nested MiniGame model / track / music graph – ResourceTypeCode mapping for engine-specific texture and model packs is still being audited.