Expand description
This module provides support for reading and writing ESF (Empire Save File) files.
§Overview
ESF files are hierarchical binary files used extensively in Total War games to store structured game data. They are found in various contexts including:
- Campaign save games (
.save,.save_multiplayer) - Campaign startup positions (startpos)
- Character save files (
.twc) - Composite Scene files (
.csc) - Campaign Effect Object files (
.ccd) - General ESF data (
.esf)
§File Structure
An ESF file consists of:
- Header: Contains the signature, unknown field, creation date, and offset to string tables.
- Node Tree: A recursive tree structure starting from a root record node, containing all the actual data organized hierarchically.
- String Tables: Three separate tables at the end of the file:
- Record names: Names used by record nodes (e.g., “CAMPAIGN_SAVE_GAME”, “FACTION”)
- UTF-16 strings: String values referenced by UTF-16 string nodes
- UTF-8/ASCII strings: String values referenced by ASCII string nodes
§Supported Signatures
ESF files come in several format versions identified by their signature:
| Signature | Status | Notes |
|---|---|---|
| CAAB | ✅ Supported | Older format, uses u16 for string sizes |
| CBAB | ✅ Supported | Newer format, uses u32 for string sizes |
| CEAB | ❌ Unsupported | Rare format |
| CFAB | ❌ Unsupported | Rare format |
§Node Types
The ESF format supports a rich set of node types organized into categories:
§Primitive Types
- Boolean, signed/unsigned integers (8/16/32/64-bit), floats (32/64-bit)
- 2D and 3D coordinates (pairs/triplets of f32)
- UTF-16 and ASCII strings (stored as indices into string tables)
- Angles (i16)
§Optimized Primitives
Many primitive types have optimized encodings for common values to reduce file size:
BOOL_TRUE/BOOL_FALSE: Single byte instead of marker + valueU32_ZERO/U32_ONE: Single byte for 0 or 1U32_BYTE/U32_16BIT/U32_24BIT: Smaller encodings when value fits- Similar optimizations exist for i32 and f32 (zero)
§Arrays
All primitive types have corresponding array variants that store multiple values with a length prefix. Arrays also support optimized encodings.
§Record Nodes
Record nodes are container nodes that hold other nodes. They have:
- A name (from the record names table)
- A version number
- Flags controlling encoding behavior
- Children organized into groups (for nested blocks) or a single list
§Compression
Large ESF files (particularly campaign startpos files) may contain compressed sections.
Nodes with specific names (e.g., CAMPAIGN_ENV) are automatically compressed using LZMA1
during encoding. The compressed data is stored in special COMPRESSED_DATA and
COMPRESSED_DATA_INFO record nodes.
During decoding, these compressed sections are automatically decompressed and the contained ESF data replaces the outer structure.
§Usage
use rpfm_lib::files::esf::ESF;
use rpfm_lib::files::{Decodeable, Encodeable};
use std::io::Cursor;
// Decode an ESF file
let mut reader = Cursor::new(esf_bytes);
let esf = ESF::decode(&mut reader, &None)?;
// Access the root node and traverse the tree
let root = esf.root_node();
// Encode back to bytes
let mut output = Vec::new();
esf.encode(&mut output, &None)?;§Internal Submodules
caab: CAAB format-specific reading and writing logiccbab: CBAB format-specific reading and writing logicutils: Shared utilities for node reading/writing across formats
Structs§
- Bool
Node - Boolean node with optimization tracking.
- Coordinates2D
Node - 2D coordinate node storing X and Y position values.
- Coordinates3D
Node - 3D coordinate node storing X, Y, and Z position values.
- ESF
- Represents a complete ESF file decoded in memory.
- F32Node
- 32-bit floating point node with optimization tracking.
- I32Node
- Signed 32-bit integer node with optimization tracking.
- Record
Node - A record node that contains other nodes as children.
- Record
Node Flags - Flags that control how a record node is encoded in the ESF binary format.
- U32Node
- Unsigned 32-bit integer node with optimization tracking.
- VecI32
Node - Array of signed 32-bit integers with optimization tracking.
- VecU32
Node - Array of unsigned 32-bit integers with optimization tracking.
Enums§
- ESFSignature
- Identifies the format version of an ESF file.
- Node
Type - Represents all possible node types in an ESF file.
Constants§
- EXTENSIONS
- File extensions associated with ESF files.
- INVALID
- Invalid marker - encountering this during parsing is always an error.
- SIGNATURE_
CAAB - Magic bytes identifying the CAAB ESF format (older format with u16 string sizes).
- SIGNATURE_
CBAB - Magic bytes identifying the CBAB ESF format (newer format with u32 string sizes).
- SIGNATURE_
CEAB - Magic bytes identifying the CEAB ESF format (unsupported).
- SIGNATURE_
CFAB - Magic bytes identifying the CFAB ESF format (unsupported).