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

2DA (2D Array)

2DAs are data tables defining the engine’s core rules and constraints (such as item costs and Force powers, which the engine internally stores as spells.2da). They bridge the gap between human-readable text for modding and fast-loading binaries for the final game.

At a Glance

PropertyValue
Extension(s).2da
Magic Signature2DA / V2.b (Binary) or V2.0 (Text)
TypeTabular Data
Rust ReferenceView rakata_formats::TwoDa in Rustdocs

Data Model Structure

The rakata-formats crate parses 2DAs so that binary and text formats look identical to the rest of the application. The TwoDa container lets developers simply retrieve cells using twoda.cell(row, "Label"), completely hiding the inner offset calculations and padding differences between text and binary structures.

Engine Audits & Decompilation

The following documents the engine’s exact load sequence for 2D Arrays mapped from swkotor.exe.

(Decompilation logic for this section was audited and verified via native Ghidra pipeline against swkotor.exe, explicitly pulling from C2DA::Load2DArray at 0x004143b0.)

Pipeline EventGhidra Provenance & Engine Behavior
Magic/Version GateThe engine first checks for the "2DA " signature. It then branches down a binary parsing path for "V2.b" or a text parsing path for "V2.0". Any other version string triggers an instant load failure.
Binary Load (V2.b)The parser starts with an 8-byte skip into the file (data_ptr = raw_data_ptr + 8), jumping right past the header to the starting newline character. Column headers are a tab-separated, null-terminated block. The cell offsets are then parsed as an array of u16 integers (rows × cols) in row-major order.
Text Load (V2.0)The text parser strips whitespace and newlines, specifically hunting for "DEFAULT:" or "DEFAULT" blocks. When parsing individual cells, the literal text "****" is converted into an empty string "" to signal the fallback rule. Finally, it runs _strlwr on all column headers to immediately convert them to lowercase.

Tip

Orphaned Size Field: In binary row blocks, the 2-byte cell_data_size u16 is completely bypassed. The engine skips it with +2 and performs no reading or validation.