Repository navigation
2DA File Format
This document provides a detailed description of the 2DA (Two-Dimensional array) file format used in Knights of the Old Republic (KotOR) and Knights of the Old Republic II: The Sith Lords (KotOR 2). 2DA files store tabular game data in a spreadsheet-like format, containing configuration data for nearly all game systems: items, Force powers, creatures, skills, feats, and many other game mechanics.
Official Bioware Documentation: For the authoritative Bioware Aurora Engine 2DA format specification, see Bioware Aurora 2DA Format.
For mod developers: To modify 2DA files in your mods, see the TSLPatcher 2DAList Syntax Guide. For general modding information, see HoloPatcher README for Mod Developers.
Related formats: 2DA files ARE often referenced by GFF files (such as UTC (Creature), UTI (Item), UTP (Placeable) templates) and may contain references to TLK files for text strings.
Important: While the 2DA file format structure is shared across BioWare's Aurora engine games (including Neverwinter Nights, Dragon Age, and Jade Empire), this documentation focuses exclusively on KotOR and KotOR 2. All 2DA file examples, column structures, and engine usage descriptions ARE specific to these games. References to vendor implementations ARE marked as either KotOR-specific or generic Aurora engine code (shared format).
-
KotOR 2DA file format Documentation
- Table of Contents
- file structure Overview
- Format
- data structure
- Cell value types
- Confirmed Engine Usage
- Known 2DA files
- Character & Combat 2DA files
- Items & Properties 2DA files
- Objects & Area 2DA files
- Visual Effects & animations 2DA files
- Progression Tables 2DA files
- Name Generation 2DA files
-
Additional 2DA files
- ambientmusic.2da
- ambientsound.2da
- ammunitiontypes.2da
- camerastyle.2da
- footstepsounds.2da
- prioritygroups.2da
- repute.2da
- surfacemat.2da
- loadscreenhints.2da
- bodybag.2da
- ranges.2da
- regeneration.2da
- animations.2da
- combatanimations.2da
- weaponsounds.2da
- placeableobjsnds.2da
- creaturespeed.2da
- exptable.2da
- guisounds.2da
- dialoganimations.2da
- tilecolor.2da
- forceshields.2da
- plot.2da
- traps.2da
- modulesave.2da
- tutorial.2da
- globalcat.2da
- subrace.2da
- gender.2da
- racialtypes.2da
- upgrade.2da
- encdifficulty.2da
- itempropdef.2da
- emotion.2da
- facialanim.2da
- videoeffects.2da
- planetary.2da
- cursors.2da
-
Item Property Parameter & Cost Tables 2DA files
- iprp_paramtable.2da
- iprp_costtable.2da
- iprp_abilities.2da
- iprp_aligngrp.2da
- iprp_combatdam.2da
- iprp_damagetype.2da
- iprp_protection.2da
- iprp_acmodtype.2da
- iprp_immunity.2da
- iprp_saveelement.2da
- iprp_savingthrow.2da
- iprp_onhit.2da
- iprp_ammotype.2da
- iprp_mosterhit.2da
- iprp_walk.2da
- ai_styles.2da
- iprp_damagevs.2da
- iprp_attackmod.2da
- iprp_bonusfeat.2da
- iprp_lightcol.2da
- iprp_monstdam.2da
- iprp_skillcost.2da
- iprp_weightinc.2da
- iprp_traptype.2da
- iprp_damagered.2da
- iprp_spellres.2da
- rumble.2da
- musictable.2da
- difficultyopt.2da
- xptable.2da
- featgain.2da
- effecticon.2da
- itempropsdef.2da
- pazaakdecks.2da
- acbonus.2da
- keymap.2da
- soundeax.2da
- poison.2da
- feedbacktext.2da
- creaturesize.2da
- appearancesndset.2da
- texpacks.2da
- videoquality.2da
- loadscreens.2da
- phenotype.2da
- palette.2da
- bodyvariation.2da
- textures.2da
- merchants.2da
- actions.2da
- aiscripts.2da
- bindablekeys.2da
- crtemplates.2da
- environment.2da
- fractionalcr.2da
- gamespyrooms.2da
- hen_companion.2da
- hen_familiar.2da
- masterfeats.2da
- movies.2da
- stringtokens.2da
- tutorial_old.2da
- credits.2da
- disease.2da
- droiddischarge.2da
- minglobalrim.2da
- upcrystals.2da
- chargenclothes.2da
- aliensound.2da
- alienvo.2da
- grenadesnd.2da
- inventorysnds.2da
- areaeffects.2da
- Implementation Details
2DA files store tabular game data in a compact format used by the KotOR game engine. files use version "V2.b" and have the .2da extension.
Implementation: Libraries/PyKotor/src/pykotor/resource/formats/twoda/
Vendor References:
-
vendor/kotor/docs/2da.md- Basic format structure and parsing overview -
vendor/reone/src/libs/resource/format/2dareader.cpp- Complete C++ 2DA parser implementation -
vendor/xoreos/src/aurora/2dafile.cpp- Generic Aurora engine 2DA implementation (shared format) -
vendor/KotOR-Unity/Assets/Scripts/FileObjects/2DAObject.cs- C# Unity 2DA loader -
vendor/KotOR.js/src/resource/TwoDAObject.ts- TypeScript 2DA parser with memory-efficient caching -
vendor/Kotor.NET/Kotor.NET/Formats/Kotor2DA/Kotor2DA.cs- .NET 2DA reader/writer
See Also:
- TSLPatcher 2DAList Syntax - Modding 2DA files with TSLPatcher
- GFF File Format - Related format that often references 2DA data
- TLK File Format - Text strings referenced by 2DA entries
The 2DA file format (version "V2.b") is the representation used by the game engine.
The file header is 9 bytes in size:
| Name | type | offset | size | Description |
|---|---|---|---|---|
| file type | char | 0 (0x00) | 4 | Always "2DA " (space-padded) or "2DA\t" (tab-padded) |
| file Version | char | 4 (0x04) | 4 | Always "V2.b"
|
| Line Break | uint8 | 8 (0x08) | 1 | Newline character (\n, value 0x0A) |
The file type can be either "2DA " (space-padded) or "2DA\t" (tab-padded). Both ARE valid and accepted by the game engine.
References:
-
vendor/reone/src/libs/resource/format/2dareader.cpp:29-32- KotOR-specific header validation -
vendor/xoreos/src/aurora/2dafile.cpp:48-51- Generic Aurora engine header constants (format shared across KotOR and other Aurora games) -
vendor/KotOR-Unity/Assets/Scripts/FileObjects/2DAObject.cs:25-32- KotOR-specific header reading
Column headers immediately follow the header, terminated by a null byte:
| Name | type | Description |
|---|---|---|
| Column headers | char[] |
Tab-separated column names (e.g., "label\tname\tdescription") |
| null terminator | uint8 | Single null byte (\0) marking end of headers |
Each column name is terminated by a tab character (0x09). The entire header list is terminated by a null byte (0x00). Column names ARE case-sensitive and typically lowercase in KotOR files.
References:
-
vendor/reone/src/libs/resource/format/2dareader.cpp:72-89- KotOR-specific token reading with tab separator -
vendor/xoreos/src/aurora/2dafile.cpp:260-275- Generic Aurora engine header reading (format shared across KotOR and other Aurora games) -
vendor/KotOR-Unity/Assets/Scripts/FileObjects/2DAObject.cs:36-48- KotOR-specific column header parsing -
vendor/kotor/docs/2da.md:32-37- KotOR-specific column structure
| Name | type | offset | size | Description |
|---|---|---|---|---|
| Row count | uint32 | varies | 4 | Number of data rows in the file (little-endian) |
The row count is stored as a 32-bit unsigned integer in little-endian byte order. This value determines how many row labels and data rows follow.
References:
-
vendor/reone/src/libs/resource/format/2dareader.cpp:34- KotOR-specific row count reading -
vendor/xoreos/src/aurora/2dafile.cpp:284- Generic Aurora engine row count reading (format shared across KotOR and other Aurora games) -
vendor/kotor/docs/2da.md:39-44- KotOR-specific row indices structure
Row labels immediately follow the row count:
| Name | type | Description |
|---|---|---|
| Row Labels | char[] | Tab-separated row labels (one per row, typically numeric) |
Each row label is read as a tab-terminated string (tab character 0x09). Row labels ARE usually numeric ("0", "1", "2"...) but can be arbitrary strings.
Important: The row label list is not terminated by a null byte (0x00). The reader must consume exactly row_count labels based on the count field. This differs from the column headers which do have a null terminator. The row labels ARE primarily for human readability and editing tools - the actual row indexing in the game engine is based on position, not label value.
References:
-
vendor/reone/src/libs/resource/format/2dareader.cpp:35- KotOR-specific row label reading (skipped in reone) -
vendor/xoreos/src/aurora/2dafile.cpp:277-294- Generic Aurora engine row label skipping implementation (format shared across KotOR and other Aurora games) -
vendor/KotOR-Unity/Assets/Scripts/FileObjects/2DAObject.cs:56-70- KotOR-specific row label parsing -
vendor/kotor/docs/2da.md:39-46- KotOR-specific row indices structure and termination note
After row labels, cell data offsets ARE stored:
| Name | type | size | Description |
|---|---|---|---|
| Cell offsets | uint16[] | 2×N | Array of offsets into cell data string table (N = row_count × column_count, little-endian) |
| Cell data size | uint16 | 2 | Total size of cell data string table in bytes (little-endian) |
Each cell has a 16-bit unsigned integer offset (little-endian) pointing to its string value in the cell data string table. Offsets ARE stored in row-major order (all cells of row 0, then all cells of row 1, etc.). The cell data size field immediately follows the offset array and precedes the actual cell data.
Important: The offsets ARE relative to the start of the cell data string table (which begins immediately after the cell_data_size field). Multiple cells can share the same offset value if they contain identical strings, enabling data deduplication.
References:
-
vendor/reone/src/libs/resource/format/2dareader.cpp:47-52- KotOR-specific offset array reading -
vendor/xoreos/src/aurora/2dafile.cpp:314-317- Generic Aurora engine offset reading (format shared across KotOR and other Aurora games) -
vendor/KotOR-Unity/Assets/Scripts/FileObjects/2DAObject.cs:72-83- KotOR-specific offset array parsing -
vendor/reone/src/libs/resource/format/2dawriter.cpp:63-89- KotOR-specific offset deduplication during writing -
vendor/kotor/docs/2da.md:48-54- KotOR-specific cell offsets structure
The cell data string table contains all cell values as null-terminated strings:
| Name | type | Description |
|---|---|---|
| Cell strings | char[] | Null-terminated strings, deduplicated (same value shares offset) |
The cell data string table begins immediately after the cell_data_size field. Each string is null-terminated (0x00). Blank or empty cells ARE typically stored as empty strings (immediately null-terminated) or the string "****". The string table is deduplicated - multiple cells with the same value share the same offset, reducing file size.
Reading Process: For each cell, the reader:
- Retrieves the 16-bit offset from the offset array (indexed by
row_index × column_count + column_index) - Seeks to
cell_data_start_position + offset - Reads a null-terminated string from that position
References:
-
vendor/reone/src/libs/resource/format/2dareader.cpp:54-65- KotOR-specific cell data reading with offset calculation -
vendor/xoreos/src/aurora/2dafile.cpp:319-335- Generic Aurora engine cell data reading (format shared across KotOR and other Aurora games, with KotOR-specific comment at line 545) -
vendor/KotOR-Unity/Assets/Scripts/FileObjects/2DAObject.cs:85-100- KotOR-specific cell data reading loop -
vendor/xoreos/src/aurora/2dafile.cpp:63-64- Generic Aurora engine empty cell representation ("****", shared across KotOR and other Aurora games) -
vendor/kotor/docs/2da.md:57-64- KotOR-specific cell data structure
The TwoDA class represents a complete 2DA file in memory:
Reference: Libraries/PyKotor/src/pykotor/resource/formats/twoda/twoda_data.py:77-119
Attributes:
-
_rows: List of dictionaries, each mapping column headers to cell values -
_headers: List of column header names (case-sensitive, typically lowercase) -
_labels: List of row labels (usually numeric strings like "0", "1", "2"...)
Methods:
-
get_cell(row_index, column_header): Get cell value by row index and column header -
set_cell(row_index, column_header, value): Set cell value -
get_column(header): Get all values for a column -
add_row(label): Add a new row -
add_column(header): Add a new column
The TwoDARow class provides a convenient interface for accessing row data:
Reference: Libraries/PyKotor/src/pykotor/resource/formats/twoda/twoda_data.py:850-950
Attributes:
-
label: Row label string -
cells: Dictionary mapping column headers to cell values
All cell values ARE stored as strings in the 2DA file, but ARE interpreted as different types by the game engine:
-
Integers: Numeric strings parsed as
int32- used for numeric identifiers, counts, and enumerated values -
Floats: Decimal strings parsed as
float- used for calculations like damage multipliers, timers, and percentages - ResRefs: Resource references (max 16 characters, no extension) - point to other game resources like models, textures, or scripts
-
StrRefs: String references into
dialog.tlk(typically negative values like-1indicate no reference) - used for localized text display -
Boolean:
"0"or"1"(sometimes"TRUE"/"FALSE") - control feature flags and settings -
Empty Cells: Represented as
"****"- treated as null/undefined by the engine
The game engine parses cell values based on context and expected data type for each column. For example, the appearance.2da file uses integers for model indices, ResRefs for texture names, and StrRefs for race names.
The following 2DA files have been confirmed to be actively loaded and used by the KotOR game engine through reverse engineering analysis of the game binaries and engine reimplementations (reone, xoreos):
Core Game Systems:
-
classes.2da- Class definitions and progression -
[feat.2da](2DA-feat)- Feat definitions -
featgain.2da- Feat gain tables (referenced in engine error messages) -
skills.2da- Skill definitions -
spells.2da- Force power/spell definitions
Character & Appearance:
-
appearance.2da- Creature appearance definitions -
[racialtypes.2da](2DA-racialtypes)- Race definitions -
subrace.2da- Subrace definitions -
gender.2da- Gender definitions -
portraits.2da- Portrait definitions -
heads.2da- Head appearance definitions -
creaturespeed.2da- Creature movement speed definitions
Items & Equipment:
-
baseitems.2da- Base item type definitions
Objects & Areas:
-
placeables.2da- Placeable object definitions -
[genericdoors.2da](2DA-genericdoors)/doortypes.2da- Door type definitions -
[traps.2da](2DA-traps)- Trap definitions -
encdifficulty.2da- Encounter difficulty definitions
Audio & Visual:
-
guisounds.2da- GUI sound definitions -
footstepsounds.2da- Footstep sound definitions -
camerastyle.2da- Camera style definitions -
surfacemat.2da- Surface material definitions
Factions & Reputation:
-
repute.2da- Faction/reputation definitions
Note: Many other 2DA files documented below may be remnants from Neverwinter Nights (NWN) or may be used in ways not yet identified through reverse engineering. The files listed above ARE confirmed to be actively loaded and referenced by the game engine during normal gameplay.
This section documents all known 2DA files used in KotOR and KotOR 2, organized by category. Each entry includes engine usage, column definitions, and data structure details.
See appearance.2da for detailed documentation.
See baseitems.2da for detailed documentation.
See classes.2da for detailed documentation.
See feat.2da for detailed documentation.
See skills.2da for detailed documentation.
See spells.2da for detailed documentation.
See itemprops.2da for detailed documentation.
See iprp_feats.2da for detailed documentation.
See iprp_spells.2da for detailed documentation.
See iprp_ammocost.2da for detailed documentation.
See iprp_damagecost.2da for detailed documentation.
See placeables.2da for detailed documentation.
See genericdoors.2da for detailed documentation.
See doortypes.2da for detailed documentation.
See soundset.2da for detailed documentation.
Visual Effects & animations 2DA files
See visualeffects.2da for detailed documentation.
See portraits.2da for detailed documentation.
See heads.2da for detailed documentation.
See classpowergain.2da for detailed documentation.
See cls_atk_*.2da for detailed documentation.
See cls_savthr_*.2da for detailed documentation.
See humanfirst.2da for detailed documentation.
See humanlast.2da for detailed documentation.
Similar name generation files exist for other species:
-
twilekfirst.2da/twileklast.2da: Twi'lek names -
zabrakfirst.2da/zabraklast.2da: Zabrak names -
wookieefirst.2da/wookieelast.2da: Wookiee names -
rodianfirst.2da/rodianlast.2da: Rodian names -
droidfirst.2da/droidlast.2da: Droid names -
catharfirst.2da/catharlast.2da: Cathar names (KotOR 2) -
miralukafirst.2da/miralukalast.2da: Miraluka names (KotOR 2) -
miracianfirst.2da/miracianlast.2da: Miraluka names (KotOR 2, alternate spelling)
See ambientmusic.2da for detailed documentation.
See ambientsound.2da for detailed documentation.
See ammunitiontypes.2da for detailed documentation.
See camerastyle.2da for detailed documentation.
See footstepsounds.2da for detailed documentation.
See prioritygroups.2da for detailed documentation.
See repute.2da for detailed documentation.
See surfacemat.2da for detailed documentation.
See loadscreenhints.2da for detailed documentation.
See bodybag.2da for detailed documentation.
See ranges.2da for detailed documentation.
See regeneration.2da for detailed documentation.
animations.2da
See animations.2da for detailed documentation.
See combatanimations.2da for detailed documentation.
See weaponsounds.2da for detailed documentation.
See placeableobjsnds.2da for detailed documentation.
See creaturespeed.2da for detailed documentation.
See exptable.2da for detailed documentation.
See guisounds.2da for detailed documentation.
See dialoganimations.2da for detailed documentation.
See tilecolor.2da for detailed documentation.
See forceshields.2da for detailed documentation.
See plot.2da for detailed documentation.
See traps.2da for detailed documentation.
See modulesave.2da for detailed documentation.
See tutorial.2da for detailed documentation.
See globalcat.2da for detailed documentation.
See subrace.2da for detailed documentation.
See gender.2da for detailed documentation.
See racialtypes.2da for detailed documentation.
See upgrade.2da for detailed documentation.
See encdifficulty.2da for detailed documentation.
See itempropdef.2da for detailed documentation.
See emotion.2da for detailed documentation.
See facialanim.2da for detailed documentation.
See videoeffects.2da for detailed documentation.
See planetary.2da for detailed documentation.
See cursors.2da for detailed documentation.
The following 2DA files ARE used for item property parameter and cost calculations:
See iprp_paramtable.2da for detailed documentation.
See iprp_costtable.2da for detailed documentation.
See iprp_abilities.2da for detailed documentation.
See iprp_aligngrp.2da for detailed documentation.
See iprp_combatdam.2da for detailed documentation.
See iprp_damagetype.2da for detailed documentation.
See iprp_protection.2da for detailed documentation.
See iprp_acmodtype.2da for detailed documentation.
See iprp_immunity.2da for detailed documentation.
See iprp_saveelement.2da for detailed documentation.
See iprp_savingthrow.2da for detailed documentation.
See iprp_onhit.2da for detailed documentation.
See iprp_ammotype.2da for detailed documentation.
See iprp_mosterhit.2da for detailed documentation.
See iprp_walk.2da for detailed documentation.
See ai_styles.2da for detailed documentation.
See iprp_damagevs.2da for detailed documentation.
See iprp_attackmod.2da for detailed documentation.
See iprp_bonusfeat.2da for detailed documentation.
See iprp_lightcol.2da for detailed documentation.
See iprp_monstdam.2da for detailed documentation.
See iprp_skillcost.2da for detailed documentation.
See iprp_weightinc.2da for detailed documentation.
See iprp_traptype.2da for detailed documentation.
See iprp_damagered.2da for detailed documentation.
See iprp_spellres.2da for detailed documentation.
See rumble.2da for detailed documentation.
See musictable.2da for detailed documentation.
See difficultyopt.2da for detailed documentation.
See xptable.2da for detailed documentation.
See featgain.2da for detailed documentation.
See effecticon.2da for detailed documentation.
See itempropsdef.2da for detailed documentation.
See pazaakdecks.2da for detailed documentation.
See acbonus.2da for detailed documentation.
See keymap.2da for detailed documentation.
See soundeax.2da for detailed documentation.
See poison.2da for detailed documentation.
See feedbacktext.2da for detailed documentation.
See creaturesize.2da for detailed documentation.
See appearancesndset.2da for detailed documentation.
See texpacks.2da for detailed documentation.
See videoquality.2da for detailed documentation.
See loadscreens.2da for detailed documentation.
See phenotype.2da for detailed documentation.
See palette.2da for detailed documentation.
See bodyvariation.2da for detailed documentation.
textures.2da
See textures.2da for detailed documentation.
See merchants.2da for detailed documentation.
See actions.2da for detailed documentation.
See aiscripts.2da for detailed documentation.
See bindablekeys.2da for detailed documentation.
See crtemplates.2da for detailed documentation.
See environment.2da for detailed documentation.
See fractionalcr.2da for detailed documentation.
See gamespyrooms.2da for detailed documentation.
See hen_companion.2da for detailed documentation.
See hen_familiar.2da for detailed documentation.
See masterfeats.2da for detailed documentation.
See movies.2da for detailed documentation.
See stringtokens.2da for detailed documentation.
See tutorial_old.2da for detailed documentation.
See credits.2da for detailed documentation.
See disease.2da for detailed documentation.
See droiddischarge.2da for detailed documentation.
See minglobalrim.2da for detailed documentation.
See upcrystals.2da for detailed documentation.
See chargenclothes.2da for detailed documentation.
See aliensound.2da for detailed documentation.
See alienvo.2da for detailed documentation.
See grenadesnd.2da for detailed documentation.
See inventorysnds.2da for detailed documentation.
See areaeffects.2da for detailed documentation.
Reading: Libraries/PyKotor/src/pykotor/resource/formats/twoda/io_twoda.py:12-106
Writing: Libraries/PyKotor/src/pykotor/resource/formats/twoda/io_twoda.py:109-174
reone (C++):
- Reading:
vendor/reone/src/libs/resource/format/2dareader.cpp - Writing:
vendor/reone/src/libs/resource/format/2dawriter.cpp - data structure:
vendor/reone/src/libs/resource/2da.cpp
xoreos (C++):
- Reading:
vendor/xoreos/src/aurora/2dafile.cpp- Generic Aurora engine 2DA format parser (shared across KotOR, Neverwinter Nights, and other Aurora engine games). The format structure is the same, but specific 2DA files and their columns ARE KotOR-specific.
KotOR-Unity (C#):
- Reading:
vendor/KotOR-Unity/Assets/Scripts/FileObjects/2DAObject.cs:23-105- Complete 2DA reading implementation with column parsing, row indices, and cell data reading
TSLPatcher (Perl):
- Reading/Writing:
vendor/TSLPatcher/lib/site/Bioware/TwoDA.pm
KotOR.js (TypeScript):
- Reading:
vendor/KotOR.js/src/resource/TwoDAObject.ts:69-145- Complete 2DA reading implementation - Manager:
vendor/KotOR.js/src/managers/TwoDAManager.ts:21-37- 2DA table loading from game archives - Usage:
vendor/KotOR.js/src/talents/TalentFeat.ts:122-132- Feat loading fromfeat.2da
Kotor.NET (C#):
This documentation aims to provide a comprehensive overview of the KotOR 2DA file format, focusing on the detailed file structure and data formats used within the games.