Jump to content

UPK file format


wghost81

Recommended Posts

Since wiki is still down, I'll start here. Don't like wiki formatting, anyway. :smile:

I want to document UPK file format, so it will be easier for anyone to implement their own tools. Here's what I know so far.

UPK format

UPK file consists of:

  1. package header
  2. name list
  3. object list (aka export list)
  4. import list
  5. actual objects data

Technically, lists are part of the header, as header size counts lists in.

 

Header structure

  • int32 Signature
  • int16 Version
  • int16 LicenseVersion
  • int32 HeaderSize
  • int32 FolderNameLength
  • null-terminated string FolderName
  • int32 PackageFlags
  • int32 NameCount
  • int32 NameOffset
  • int32 ExportCount
  • int32 ExportOffset
  • int32 ImportCount
  • int32 ImportOffset
  • int32 DependsOffset
  • int32 Unknown1 (seems to be equal to HeaderSize)
  • int32 Unknown2
  • int32 Unknown3
  • int32 Unknown4
  • int32x4 GUID
  • int32 GenerationsCount
  • int32x3xGenerationsCount generations
  • int32 EngineVersion
  • int32 CookerVersion
  • int32 CompressionFlags
  • variable size unknown data chunk

generations are int32x3 objects with following structure:

  • int32 ExportCount
  • int32 NameCount
  • int32 NetObjectCount

DependsOffset seems to point to some object inside import table (haven't checked yet).

 

Beginning with NameOffset there is a list of NameCount entries. Each entry is variable-size and has following format:

  • int32 NameLength
  • null-terminated string NameString
  • int32 Unknown1
  • int32 Unknown2

Beginning with ExportOffset there is a list of ExportCount entries. Each entry is variable-size and has following format:

  • int32 ObjType
  • int32 ParentClassRef
  • int32 OwnerRef
  • int32 NameListIdx
  • int32 Field5
  • int32 Field6
  • int32 PropertyFlags
  • int32 Field8
  • int32 ObjectFileSize
  • int32 DataOffset
  • int32 Field11
  • int32 NumAdditionalFields
  • int32 Field13
  • int32 Field14
  • int32 Field15
  • int32 Field16
  • int32 Field17
  • int32xNumAdditionalFields UnknownFields

Beginning with ImportOffset there is a list of ImportCount entries. Each entry is fixed-size and has following format:

  • int32 PackageID
  • int32 Unknown1
  • int32 ObjType
  • int32 Unknown2
  • int32 OwnerRef
  • int32 NameListIdx
  • int32 Unknown3

OwnerRef is positive value for Export objects and negative value for Import objects.

 

Object data chunks format depends on object type. For example, scripted function has 0x30 bytes of header, last 8 bytes are memory size and file size respectively. Then go fileSize bytes of actual code, ending with 0x53 and then some unknown data.

 

Hints, tips and notes on UPK format and object data formats are welcomed. :smile:

Edited by wghost81
Link to comment
Share on other sites

  • Replies 111
  • Created
  • Last Reply

Top Posters In This Topic

Link to comment
Share on other sites

One word on lists indexes.

 

I don't like the "subtract one" thing, as it is confusing and doesn't seems "native".

 

Name list is an array of data with zero starting index. Object lists are array of data with starting index equal to 1, as zero-reference indicates null-object. When unpacked to memory, object lists are prepended with null-object with zero starting index and then other objects from upk file are appended to the list. This way you don't need to subtract/add anything when reading/editing, which makes operations more transparent.

Link to comment
Share on other sites

One word on lists indexes.

 

I don't like the "subtract one" thing, as it is confusing and doesn't seems "native".

 

Name list is an array of data with zero starting index. Object lists are array of data with starting index equal to 1, as zero-reference indicates null-object. When unpacked to memory, object lists are prepended with null-object with zero starting index and then other objects from upk file are appended to the list. This way you don't need to subtract/add anything when reading/editing, which makes operations more transparent.

 

XMTS and I did the same thing in the Java code we are (still!) working on. It's a lot easier to add that initial null object to the list and be done with it.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...