.STR Archive Structure (EA Stream File)

Version: 1.0
Last Updated: 2025-02-17
Author(s): samarixum

The .str file is EA's streaming container format used by the RenderWare engine on PS3/Xbox 360. It contains a metadata header pointing to section descriptors and data, with support for compression (Refpack) and lazy-loading of resources.

Endianness: Big-Endian throughout.

Parsing Algorithm Overview

  1. Read and validate file header at offset 0x00
  2. Navigate to StreamFile struct at header offset pStreamFile
  3. Navigate to Section array at header offset pSectionArr
  4. For each section:
    1. Read section descriptor (6 × UInt32)
    2. Decompress data if CompressorID indicates Refpack (0xB9F0B9EC)
    3. Scan decompressed/raw section data for chunk markers (0x1607, 0x2207, 0x2307, 0x10FB)
    4. Parse each chunk based on its type

File Header Structure

Located at offset 0x00. Size: 16 bytes.

Offset Size Type Name Description
0x00 4 Char[4] Magic Must be SToc (0x53546F63 BE). If not, abort parsing.
0x04 4 UInt32 BE Version Format version. Typically expect a known version (e.g., 0x00000001).
0x08 1 UInt8 nSections Number of Section Descriptor entries to read. Validate: typically 1-4.
0x09 1 UInt8 PlatformID Target platform (e.g., 0x07 = PS3). Informational.
0x0A 2 Byte[2] Padding Unused, typically 0x00.
0x0C 4 Int32 BE pStreamFile Absolute offset to StreamFile struct. Validate: must be ≥ 0x14.
0x10 4 Int32 BE pSectionArr Absolute offset to Section Descriptor array. Validate: must be ≥ pStreamFile + 32.

StreamFile Struct

Located at file offset = header.pStreamFile. Size: ~48+ bytes (variable due to string).

Offset (Rel) Size Type Name Description
0x00 4 UInt32 BE GUID Unique ID, often SDBM hash of filename. Used to identify the stream asset.
0x04 4 Int32 BE pFileName Relative pointer to null-terminated filename string. Add current offset (0x04) to this value, then seek to read until null byte.
0x08 1 UInt8 nParents Number of parent/dependency stream files. Usually 0 or 1.
0x09 1 UInt8 nForceLoad Flags for force-load behavior. Typically 0.
0x0A 1 UInt8 nSections Duplicate of header.nSections. Verify consistency.
0x0B 1 UInt8 Flags Bitfield (flags). Meaning context-dependent.
0x0C 4 Int32 BE Unk Unknown/reserved field. Typically 0.
0x10 4 Int32 BE pRelatives Offset to related stream info. Often 0 (none).
0x14 4 Int32 BE pSectionInfo Offset to additional section metadata. Often 0 (none).

Section Descriptor Array

Located at file offset = header.pSectionArr. Array of nSections entries, each 24 bytes.

To parse: For i = 0 to nSections-1, seek to (pSectionArr + i*24) and read 24 bytes.

Offset (Rel) Size Type Name Description
0x00 4 UInt32 BE MemPolicyID Memory allocation policy. Informational; typically 0.
0x04 4 UInt32 BE CompressorID Critical: Determines if section data is compressed.
  • 0xB9F0B9EC = Refpack compression
  • 0x0EAC15C8 = Uncompressed (raw data)
0x08 4 Int32 BE DataSize Critical: Size of decompressed data (or raw data if uncompressed). Use this to allocate buffer or validate size.
0x0C 4 Int32 BE AllocSize Size to reserve in memory. Typically ≥ DataSize. May include padding.
0x10 4 Int32 BE ReadSize Critical: Amount of bytes to read from disk. If CompressorID is Refpack, this is compressed size; otherwise equals DataSize.
0x14 4 Int32 BE ReadOffset Critical: Absolute file offset where section data begins. Seek here before reading ReadSize bytes.

Section Data Decompression

Algorithm:

  1. Seek to file offset = ReadOffset
  2. Read ReadSize bytes into a buffer
  3. If CompressorID == 0xB9F0B9EC:
  4. If CompressorID == 0x0EAC15C8:
  5. If CompressorID is any other value:

Chunk Scanning and Parsing

After decompression/acquisition of section data, scan the data for embedded chunks. Chunks are identified by 2-byte type identifiers (Big-Endian UInt16).

Chunk Scanning Algorithm:

  1. current_pos = 0
  2. While current_pos < data.length:

Known Chunk Types

Type ID Hex Name Size Field Handling Notes
0x10FB 0x10, 0xFB Refpack Compressed Data After type: 4-byte size (BE) Raw Refpack-compressed payload. Decompress to get contents. Used for embedded asset data.
0x1607 0x16, 0x07 Embedded Asset After type: 4-byte size (BE) Most important. Contains resource filename, type, and binary data. Parse to extract game assets (textures, meshes, scripts, etc.). See Embedded Asset section below.
0x2207 0x22, 0x07 SimGroup After type: 4-byte size (BE) Contains entity definitions. Parse as SimGroup resource. See embedded format documentation.
0x2307 0x23, 0x07 Embedded Asset (Compact) After type: 4-byte size (BE) Variant of Embedded Asset with different layout. Handle similar to 0x1607 but with adjusted offset calculations.

Embedded Asset Chunk (0x1607)

Location: Within section data, identified by type marker 0x1607.

Structure:

  1. Offset +0x00: UInt16 BE = 0x1607 (type, already read during scan)
  2. Offset +0x02: UInt16 BE = padding (0x0000)
  3. Offset +0x04: UInt32 BE = chunk_payload_size (total size of data following this field)
  4. Offset +0x08: **Embedded Asset Header** (variable structure)

Parsing Pseudocode:


// At chunk start (0x00 = type marker 0x1607)
current = 0;
type = read_u16_be(current);  // Expect 0x1607
current += 2;
padding = read_u16_be(current);
current += 2;
chunk_size = read_u32_be(current);
current += 4;
chunk_end = current + chunk_size;

// Read filename
filename = read_null_terminated_string(current);
current += strlen(filename) + 1;

// Align to 4-byte boundary
while (current % 4 != 0) current++;

// Read resource type (varies, can peek ahead)
// Many resources have a magic/header at this point
resource_data_start = current;
resource_data_size = chunk_end - current;

// Extract and store resource (filename, type, binary data)
        

Summary: Parsing Workflow

  1. Validate magic: Read header, verify "SToc"
  2. Read header fields: nSections, pStreamFile, pSectionArr
  3. Iterate sections:
    1. Seek to section descriptor at (pSectionArr + i*24)
    2. Read descriptor (MemPolicyID, CompressorID, DataSize, AllocSize, ReadSize, ReadOffset)
    3. Seek to ReadOffset, read ReadSize bytes
    4. If Refpack: decompress to DataSize bytes
    5. If uncompressed: use buffer as-is
  4. Scan decompressed section data:
    1. Scan for chunk type markers (0x1607, 0x2207, 0x2307, 0x10FB)
    2. For each chunk found, parse based on type
  5. Validate and store results: Build list of extracted resources (filenames, types, binary data)