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

ERF (Encapsulated Resource File)

ERFs are the heavy lifters for standard game modules (.mod) and save game architectures (.sav). Unlike BIFs, which rely entirely on an external KEY file to resolve their resource identities, ERFs are completely self-contained entities that carry their own internal file tables, localized descriptions, and asset payloads.

At a Glance

PropertyValue
Extension(s).erf, .mod, .hak, .sav
Magic SignaturesERF , MOD , HAK , SAV (version V1.0)
TypeSelf-Contained Archive
Rust ReferenceView rakata_formats::Erf in Rustdocs

Data Model Structure

Because ERF files share the exact same structural responsibility as RIM files (acting as self-contained module wrappers), the rakata-extract crate abstracts both ERF and RIM parsing directly behind the unified Capsule struct.

  • Capsule Generalization: Standard module extraction relies entirely on calling rakata_extract::Capsule::read_from_bytes(). This actively probes and dynamically mounts either ERF or RIM boundaries identically in memory, completely hiding the underlying structural container differences from the developer API.

Engine Audits & Decompilation

The following information documents the KOTOR engine’s exact load sequence and field requirements for genuine .erf capsule variants. All behavior was mapped natively from swkotor.exe during clean-room reverse engineering.

Capsule Header Initialization (CExoEncapsulatedFile::LoadHeader)

Mapped from 0x0040e1f0.

ActionEngine Behavior
Signature CheckExplicitly validates the header against exactly matching ERF , MOD , or HAK signatures, paired with the mandatory V1.0 version string.
Unchecked SavesThe engine completely lacks a validation branch for .sav files. If a file is loaded as a Save Game (param flag 1), the engine falls through the validation tree and explicitly mandates the file use the MOD magic string natively. An ERF file with SAV magic will physically crash or reject here!
Header TruncationThe loader explicitly pulls the entire 160-byte header into scope (CExoFile::Read(..., 0xa0)), but only evaluates offsets 0x00 through 0x1C. Offset 0x18 (Key List) and anything beyond 0x1C is entirely ignored during initialization.

Tip

The 116-Byte “Dead Zone” The giant block of bytes stretching from physical offsets 0x2C down to 0xA0 inside the 160-byte header is formally loaded into the engine’s active memory stack… and then completely discarded immediately. It is totally inert data containing old Bioware build metadata.