| Home Page | Recent Changes

Package File Format/Data Details

Data details

Integer values

Integers are stored in low-endian byte order (that means, the least significant byte comes first; the standard byte order for Intel processors: see Wikipedia logo Endianness).

Index/CompactIndex values

Index values are signed integers stored in a compact format, occupying one to five bytes. In the first byte,

  • the most significant bit (bit 7) specifies the sign of the integer value;
  • the second-most significant bit (bit 6) is set if the value is continued in the next byte;
  • and the six remaining bits (bits 5 to 0) are the six least significant bits of the resultant integer value.

Each of the three following bytes (if applicable according to bit 6 of the first byte) contributes seven more bits to the final integer value (bits 6 to 0 of each byte), while its most significant bit (bit 7) is set if another byte must be read to continue the value. The fifth byte contributes full eight bits to the value. No more than five bytes are read for a compact index value.

The following chart demonstrates how compact index values are stored. The Range column specifies the range of values that can be stored with the given representation. s is the signum bit, and x are data bits.

            Byte  0         1         2         3         4
    Range   Bit   76543210  76543210  76543210  76543210  76543210
    
     6 bit        s0xxxxxx
    13 bit        s1xxxxxx  0xxxxxxx
    20 bit        s1xxxxxx  1xxxxxxx  0xxxxxxx
    27 bit        s1xxxxxx  1xxxxxxx  1xxxxxxx  0xxxxxxx
    35 bit        s1xxxxxx  1xxxxxxx  1xxxxxxx  1xxxxxxx  xxxxxxxx
// Sample C# code (can be easily ported to C/C++/VB/etc.)

/// <summary>Reads a compact integer from the FileReader.
/// Bytes read differs, so do not make assumptions about
/// physical data being read from the stream. (If you have
/// to, get the difference of FileReader.BaseStream.Position
/// before and after this is executed.)</summary>
/// <returns>An "uncompacted" signed integer.</returns>
/// <remarks>FileReader is a System.IO.BinaryReader mapped
/// to a file. Also, there may be better ways to implement
/// this, but this is fast, and it works.</remarks>
private int ReadCompactInteger()
{
    int output = 0;
    bool signed = false;
    for(int i = 0; i < 5; i++)
    {
        byte x = FileReader.ReadByte();
        // First byte
        if(i == 0)
        {
            // Bit: X0000000
            if((x & 0x80) > 0)
                signed = true;
            // Bits: 00XXXXXX
            output |= (x & 0x3F);
            // Bit: 0X000000
            if((x & 0x40) == 0)
                break;
        }
        // Last byte
        else if(i == 4)
        {
            // Bits: 000XXXXX -- the 0 bits are ignored
            // (hits the 32 bit boundary)
            output |= (x & 0x1F) << (6 + (3 * 7));
        }
        // Middle bytes
        else
        {
            // Bits: 0XXXXXXX
            output |= (x & 0x7F) << (6 + ((i - 1) * 7));
            // Bit: X0000000
            if((x & 0x80) == 0)
                break;
        }
    }
    // multiply by negative one here, since the first 6+ bits could be 0
    if(signed)
        output *= -1;
    return(output);
}

Name values

The Name type is a simple string type. The format does, although, differ between the package versions.

Older package versions (<64, original Unreal engine) store the Name type as a zero-terminated ASCII string; "UT2k3", for example would be stored as: "U" "T" "2" "k" "3" 0x00

Newer packages (>=64, UT engine) prepend the length of the string plus the trailing zero. Again, "UT2k3" would be now stored as: 0x06 "U" "T" "2" "k" "3" 0x00

Object References

The last custom type which can be found within package files is the ObjectReference. ObjectReferences can be imagined as pointers. Technically, they are stored as CompactIndices. Depending on their value, however, they can point to different objects.

Value Type Pointer-Value
< 0 pointer to an entry of the ImportTable entry-id = -value - 1
= 0 pointer to NULL NULL
> 0 pointer to an entry in the ExportTable entry-id = value - 1

The Unreal Engine Documentation Site

Wiki Community

Topic Categories

Recent Changes

Offline Wiki

Unreal Engine

Console Commands

Terminology

FAQs

Help Desk

Mapping Topics

Mapping Lessons

UnrealEd Interface

UnrealScript Topics

UnrealScript Lessons

Making Mods

Class Tree

Modeling Topics

Chongqing Page

Log In