Skip to main content

.streamdb File Extension

.streamdb stands for stream database. The .streamdb files contain the majority of game data in Doom Eternal. 

As a general rule, any struct with _t appended to the end is an actual struct used by the game engine. Any other struct names have been created by the wiki author for organization/convenience purposes only.purposes.

File Signature

Doom Eternal ".streamdb" files can be identified by the first 8 bytes of the file header, which is always: 0x50A5C2292EF3C761.

Basic Structure

The .streamdb file consists of 3 parts. An INDEX section, which is a list of all the files contained within, followed by a PREFETCH section, and finally the DATA section, which contains data referenced by the index.

struct STREAM_DB_FILE
{
	INDEX index;
    PREFETCH prefetch;
    DATA data;
};

The INDEX contains a list of hashed IDs rather than plaintext names. All files contained within the .streamdb are stored in a headerless format, and are usually compressed via Oodle Kraken or Oodle Leviathan compression technology.

Files embedded in the .streamdb are impossible to identify by looking at the .streamdb alone. Instead, they are referenced via data contained in .resources files.

Index Structure

The .streamdb INDEX structure is of varying length. It consists of a 32-byte header, followed by a variable number of 16-byte entries. The overall structure is described as follows:

struct INDEX
{
	streamDatabaseHeader_t header;					// File signature + metadata
	streamDatabaseEntry2_t streamdbEntries[];		// One 16-byte entry for each header.numEntries
};

The streamDatabaseHeader_t struct is a 32-byte sequence:

struct streamDatabaseHeader_t
{		
	uint64 magic;							// 50 A5 C2 29 2E F3 C7 61
	uint32 headerLength;	
	uint32 pad0;							// null padding
	uint32 pad1;							// null padding
	uint32 pad2;							// null padding
	uint32 numEntries;						// Total entries, not including prefetch IDs
	uint32 flags;							// Always 3
};

The streamDatabaseEntry2_t struct is a 16-byte sequence. It will be repeated n times, where n = streamDatabaseHeader_t.numEntries. Therefore, the total length of the INDEX section can be calculated as length = 32 + (16 * streamDatabaseHeader_t.numEntries) 

struct streamDatabaseEntry2_t
{		
	uint64 identity;						// Shuffled version of .resources ID
	uint32 offset16; 						// Multiply by 16 for data offset within .streamdb
	uint32 length;							// Size of the file in .streamdb (usually compressed)
};

After the last entry, the INDEX section ends and the PREFETCH section begins.

Prefetch Structure

The .streamdb PREFETCH structure is of varying length. It consists of a 16-byte header, followed (optionally) by either one or two 16-byte prefetchBlocks, and a number of 8-byte prefetchIDs.

The overall PREFETCH structure is described as follows:

struct PREFETCH 
{
    streamDatabasePrefetchHeader_t prefetchHeader;	// Prefetch section header
    streamDatabasePrefetchBlock_t prefetchBlock[];	// (Optional) Between 0-2 prefetch "blocks"
	uint64 prefetchEntries[];						// (Optional) 0 or more prefetch file IDs.
};

The streamDatabasePrefetchHeader_t struct is a 16-byte sequence. It is always present in the .streamdb file, even if this .streamdb does not contain any prefetch entries.

struct streamDatabasePrefetchHeader_t
{
	uint32 numPrefetchBlocks;
	uint32 totalLength;						// Total length of prefetch header, blocks, entries
};

If streamDatabasePrefetchHeader_t.numPrefetchBlocks = 0, then the PREFETCH section ends here. Otherwise, it is followed by the number of streamDatabasePrefetchBlock_t structs specified. 

The number of streamDatabasePrefetchBlock_t structs is always between 0-2. Each of these has a "name" which is a uint64 hash. The "name" is a hash of either the word AI or FirstPerson. [add hash algorithm]

THIS SECTION INCOMPLETE, WIP

010 Editor Template

A 010 Editor template for use with Doom Eternal's .streamdb files can be found here: https://github.com/brongo/eternal-010-templates/blob/main/templates/DoomEternalStreamDB.bt