UT Package File Format
UT Package File Format
Version 1.6
Color Meaning
Blue This color flags any comment that could be wrong.
Violet This color flags unknown fields.
Red This color is used for messages that flag differences between package versions.
Thanks to:
Half (from Unreal Services).
Erik de Neve & Tim Sweeney from Epic Games.
Scott Martin from Ion Storm.
Revision History
1.6
• Fixed type of AnimSeqs_Count in Mesh class.
• Fixed Sound class in packages with version >=63 (thanks to Richard Wynne).
• Some small changes about compressed textures.
• Made clearer the use of LODMesh data.
• Added SkeletalMesh and Animation classes.
• Added two script opcodes for old version packages.
1.5
• Changes in package header. Added LicenseeMode value and clarified the
meaning of some fields.
• Changed property interpretation.
• Changed Null Class interpretation and added Field, Struct, Function, State,
Property (and its different types) classes.
• Added script decompilation section.
Global Header
DWORD Signature 0x9E2A83C1
DWORD PackageVersion Low order WORD is the file
version, high order WORD is the
LicenseeMode in newer versions
(seems unused).
DWORD Package Flags See “Package Flags”
DWORD NameCount Number of names in the Name
Table
DWORD NameOffset Offset of the Name Table from the
beginning of the file
DWORD ExportCount Number of objects in the Export
Table
DWORD ExportOffset Offset of the Export Table from the
beginning of the file
DWORD ImportCount Number of objects in the Import
Table
DWORD ImportOffset Offset of the Import Table from the
beginning of the file
If PackageVersion<68 then
DWORD HeritageCount Number of values in the Heritage
Table
DWORD HeritageOffset Offset of the Heritage Table from
the beginning of the file
Else
16 Bytes GUID
DWORD GenerationCount Unknown meaning of “Generation”.
Seems to be related to
recompilation.
For each generation
DWORD ExportCount
DWORD NameCount
EndIf
Name Table
NameCount elements with this format:
Import Table
ImportCount elements with this format:
INDEX Class Package Package of the Class. It’s an index into the Name Table.
INDEX Class Name The Class of the Object. It’s an index into the Name Table.
DWORD Package The Package this object resides in. See “object references”.
INDEX Object Name The Object name. It’s an index into the Name Table.
Heritage Table
HeritageCount elements with this format:
16 Bytes GUID
Package Flags
PKG_AllowDownload 0x0001 Allow downloading package
PKG_ClientOptional 0x0002 Purely optional for clients
PKG_ServerSideOnly 0x0004 Only needed on the server side
PKG_BrokenLinks 0x0008 Loaded from linker with broken import links
PKG_Unsecure 0x0010 Not trusted
PKG_Need 0x8000 Client needs to download this package
Object Flags
RF_Transactional 0x00000001 Object is transactional.
RF_Unreachable 0x00000002 Object is not reachable on the object graph.
RF_Public 0x00000004 Object is visible outside its package.
RF_TagImp 0x00000008 Temporary import tag in load/save.
RF_TagExp 0x00000010 Temporary export tag in load/save.
RF_SourceModified 0x00000020 Modified relative to source files.
RF_TagGarbage 0x00000040 Check during garbage collection.
RF_NeedLoad 0x00000200 During load, indicates object needs loading.
RF_HighlightedName 0x00000400 A hardcoded name which should be syntax-
Or highlighted.
RF_EliminateObject(?)
RF_InSingularFunc 0x00000800 In a singular function.
Or
RF_RemappedName(?)
RF_Suppress 0x00001000 Suppressed log name.
Or RF_StateChanged(?)
RF_InEndState 0x00002000 Within an EndState call.
RF_Transient 0x00004000 Don't save object.
RF_PreLoading 0x00008000 Data is being preloaded from file.
RF_LoadForClient 0x00010000 In-file load for client.
RF_LoadForServer 0x00020000 In-file load for client.
RF_LoadForEdit 0x00040000 In-file load for client.
RF_Standalone 0x00080000 Keep object around for editing even if
unreferenced.
RF_NotForClient 0x00100000 Don't load this object for the game client.
RF_NotForServer 0x00200000 Don't load this object for the game server.
RF_NotForEdit 0x00400000 Don't load this object for the editor.
RF_Destroyed 0x00800000 Object Destroy has already been called.
RF_NeedPostLoad 0x01000000 Object needs to be postloaded.
RF_HasStack 0x02000000 Has execution stack.
RF_Native 0x04000000 Native (UClass only).
RF_Marked 0x08000000 Marked (for debugging).
RF_ErrorShutdown 0x10000000 ShutdownAfterError called.
RF_DebugPostLoad 0x20000000 For debugging Serialize calls.
RF_DebugSerialize 0x40000000 For debugging Serialize calls.
RF_DebugDestroy 0x80000000 For debugging Destroy calls.
Object References
Some indices do not refer to a name in the Name Table, but to other objects in the
Export or Import tables. They work in this way:
But if PackageVersion>=64 then the type also saves first the length of the string plus
one for the zero byte. So for example, the name “Unreal” would be saved:
0x07 “U” “n” “r” “e” “a” “l” 0x00
0x00003039 (in positive, the sign is flagged at the end of the conversion)
0000001 1000000 111001 (grouping, 6 bits for the most significant byte, 7 bits for
others)
0x01 0xC0 0xF9 (added the bits for the sign and for the continuation flags)
An object usually have a header, a list of properties (ended with property “None”) and
specific data.
Properties format
A property starts with an INDEX that specify its name (in the Name Table). If the name
is “None” the properties list has finalized. The next BYTE is an info byte for the
property (includes its type).
The info byte is composed of several parts. Bits 0 to 3 is the type, bits 4 to 6 is the size
and bit 7 is the array flag.
It bit 7 is set and its not a boolean property, the property is part of an array and the index
in this array is specified just at this point. This only happens for array indices greater
than 0, that is, the first element (0-based) of the array does not have bit 7 set. The array
index value is coded in this way: If i<128 then it is saved as a byte. If i<16384 then it is
saved as a word with the most significant byte OR-ed with 0x80. With a greater value, it
is saved as an integer with the most significant byte OR-ed with 0xC0.
Some examples:
Class Field
This is an abstract class, but we need it to explain the following classes since they
inherit from it. It is also the ancestor for Const, Enum and all Property classes. It
inherits from the generic object.
Class Const
This class inherits from Field.
Class Enum
This class inherits from Field.
INDEX ArraySize
For each element
INDEX ElementName Name Reference.
Class Property
This class inherits from Field.
WORD ArrayDimension
WORD ElementSize
DWORD PropertyFlags
INDEX Category Name Reference.
WORD ReplicationOffset Only if PropertyFlags include CPF_Net
Property Flags
Another one is the “private” flag that is however saved in the object flags (!RF_Public).
Class ByteProperty
This class inherits from Property.
INDEX EnumType 0 if it is a normal byte, other for a reference to the Enum type
object.
Class ObjectProperty
This class inherits from Property.
Class FixedArrayProperty
This class inherits from Property.
Class ArrayProperty
This class inherits from Property.
Class MapProperty
This class inherits from Property.
INDEX Key
INDEX Value
Class ClassProperty
This class inherits from ObjectProperty.
If Class is “Object” then the type is the inherited object else the type is object<class>.
Class StructProperty
This class inherits from Property.
Class Struct
This is the class for UnrealScript struct definitions. It inherits from Field.
The real script size is not exactly the same as the value above since some statements
count more than they actually occupy (any index counts four instead of the real index
size). To know where the Script ends it is necessary to traverse it (decompile).
To know its parameters, result type and local variables you should traverse its children
objects.
Function Flags
QWORD ProbeMask
QWORD IgnoreMask
WORD LabelTableOffset Offset of the Label Table into the script.
DWORD StateFlags
State Flags
This class is the main object in any package, excluding other native classes. All other
objects are structured inside them.
Class Flags
If the Format property exists it tell which format the mipmaps have, else use TEXF_P8
(see below).
Some textures have compressed MipMaps after the normal MipMaps. This happens
when the bHasComp property is True. The structure is the same as in the above table
except that the MipMapData has a data format based on the CompFormat property.
Class Palette
This is a native class that does not inherit from the generic object header.
The Font objects describe the position and size of each font in a texture object.
Class TextBuffer
This is a native class that does not inherit from the generic object header.
Class Sound
This is a native class that does not inherit from the generic object header.
Music packages have only one Music object inside them, or at least this is the case for
the original UT packages (UnrealED does not allows more than one object per
package). The Music format (file extension) is the first name in the Name Table. The
format is one of the several Tracker formats (IT, XM, MOD, etc). This objects do not
have properties.
WORD ChunkCount? Always 1. Could also be the index into the name
table for the format.
DWORD Unknown If package version>61 it’s the position of the byte
next to ChunkData.
INDEX ChunkSize
ChunkSize ChunkData
BYTEs
Type Vector
Float X
Float Y
Float Z
Type Rotator
Float Pitch
Float Yaw
Float Roll
Type BoundingBox
Vector Min
Vector Max
BYTE IsValid
Type BoundingSphere
Vector Position
Float W Only if Package Version > 61
Class Mesh
This is a native class that does not inherit from the generic object header.
INDEX CollapsePointThus_Count
WORD CollapsePointThus
INDEX FaceLevel_Count
WORD FaceLevel
INDEX Faces_Count
WORD WedgeIndex1
WORD WedgeIndex2
WORD WedgeIndex3
WORD MaterialIndex
INDEX CollapseWedgeThus_Count
WORD CollapseWedgeThus
INDEX Wedges_Count
WORD VertexIndex
BYTE S =U
BYTE T =255-V
INDEX Materials_Count
DWORD Flags
DWORD TextureIndex
INDEX SpecialFaces_Count Weapon?
WORD WedgeIndex1
WORD WedgeIndex2
WORD WedgeIndex3
WORD MaterialIndex
DWORD ModelVerts
DWORD SpecialVerts
FLOAT MeshScaleMax
FLOAT LODHysteresis
FLOAT LODStrength
DWORD LODMinVerts
FLOAT LODMorph
FLOAT LODZDisplace
INDEX ReMapAnimVerts_Count
WORD ReMapAnimVerts
DWORD OldFrameVerts
To read the mesh you will need to get the Verts, Textures, Wedges, Faces and Materials
arrays and the FrameVerts, AnimFrames and SpecialVerts values.
The WedgeIndex1, 2, 3 values of the Faces array tell you which Wedges uses the face.
Each Wedge has a VertexIndex that added to SpecialVerts+selected_frame*FrameVerts
gives you the vertex index into the Verts array.
The SpecialFaces array has the weapon polygon. The WedgeIndex1, 2, 3 of this face
has to be used a bit differently because in this case we don’t have to add the
SpecialVerts value. So to find the correct vertex index just add
selected_frame*FrameVerts to the VertexIndex value.
The wedge S and T values give you the texture coordinates (U=S/255, V=1-T/255) and
the faces MaterialIndex points you to the TextureIndex value in the Materials array that
points you to the Texture object in the Textures array.
The AnimFrames value gives you the number of frames. And you can also read the
AnimSeqs array to get sequence names, position and duration.
Class SkeletalMesh
This class inherits from LodMesh.
INDEX ExtWedges_Count
WORD iVertex
WORD Flags
FLOAT U
FLOAT V
INDEX Points_Count
FLOAT X
FLOAT Y
FLOAT Z
INDEX RefSkeleton_Count
INDEX Name Name reference.
DWORD Flags
FLOAT BonePos.Orientation.X
FLOAT BonePos.Orientation.Y
FLOAT BonePos.Orientation.Z
FLOAT BonePos.Orientation.W
FLOAT BonePos.Position.X
FLOAT BonePos.Position.Y
FLOAT BonePos.Position.Z
FLOAT BonePos.Length
FLOAT BonePos.Xsize
FLOAT BonePos.Ysize
FLOAT BonePos.Zsize
DWORD NumChildren
DWORD ParentIndex
INDEX BoneWeightIdx_Count
WORD WeightIndex
WORD Number
WORD DetailA
WORD DetailB
INDEX BoneWeights_Count
WORD PointIndex
WORD BoneWeight
INDEX LocalPoints_Count
FLOAT X
FLOAT Y
FLOAT Z
DWORD SkeletalDepth
INDEX DefaultAnimation Object Reference.
DWORD WeaponBoneIndex
FLOAT WeaponAdjust.Origin.X
FLOAT WeaponAdjust.Origin.Y
FLOAT WeaponAdjust.Origin.Z
FLOAT WeaponAdjust.Xaxis.X
FLOAT WeaponAdjust.Xaxis.Y
FLOAT WeaponAdjust.Xaxis.Z
FLOAT WeaponAdjust.Yaxis.X
FLOAT WeaponAdjust.Yaxis.Y
FLOAT WeaponAdjust.Yaxis.Z
FLOAT WeaponAdjust.Zaxis.X
FLOAT WeaponAdjust.Zaxis.Y
FLOAT WeaponAdjust.Zaxis.Z
This mesh can be interpreted as a LodMesh except that instead of the Verts array you
have to use the Points array for the vertices.
Also, you don’t have frames here, just the reference model, because the animation is at
the assigned Animation object that animates the bone skeleton.
Class Animation
Properties (see above to decode)
INDEX RefBones_Count
INDEX Name Name reference
DWORD Flags
DWORD ParentIndex
INDEX Moves_Count
FLOAT RootSpeed3D.X
FLOAT RootSpeed3D.Y
FLOAT RootSpeed3D.Z
FLOAT TrackTime
DWORD StartBone
INDEX BoneIndices_Count
DWORD BoneIndex
INDEX AnimTracks_Count Array of
AnalogTracks
DWORD Flags
INDEX KeyQuat_Count
FLOAT KeyQuat.X
FLOAT KeyQuat.Y
FLOAT KeyQuat.Z
FLOAT KeyQuat.W
INDEX KeyPos_Count
FLOAT KeyPos.X
FLOAT KeyPos.Y
FLOAT KeyPos.Z
INDEX KeyTime_Count
FLOAT KeyTime
DWORD RootTrack.Flags
INDEX RootTrack.KeyQuat_Count
FLOAT RootTrack.KeyQuat.X
FLOAT RootTrack.KeyQuat.Y
FLOAT RootTrack.KeyQuat.Z
FLOAT RootTrack.KeyQuat.W
INDEX RootTrack.KeyPos_Count
FLOAT RootTrack.KeyPos.X
FLOAT RootTrack.KeyPos.Y
FLOAT RootTrack.KeyPos.Z
INDEX RootTrack.KeyTime_Count
FLOAT RootTrack.KeyTime
This object contains the animations for skeletal meshes. The RootTrack is the same type
as the elements of the previous array AnimTracks.
Script Format
The format of a struct, function, state or class script is complex. The code statements are
compiled into tokens. Here are the tokens and their interpretation:
Any offset is in Script units, that is, taking into account that any INDEX value in the
tokens adds four bytes instead of the real serialized size.