FAQ
Everything extracted as @bytes(...) — why?
No schema. Pass --game-root pointing at the game install, and make sure it actually contains the
script packages (Core.u, Engine.u, the game's own .u files). Run
schema-resolve on a known class to check the index:
ue3-tools --game-root /path/to/game schema-resolve engine "Class Engine.Actor"
package 'x' not in --game-root
The import graph reached a package your root doesn't cover. Point --game-root higher up, or check
that DLC and patch directories are included. --verbose streams every miss as it happens.
Invalid file signature
Not a UE3 package, or it's encrypted/wrapped by the title. The tool requires the literal
0x9E2A83C1 tag at offset zero.
Corrupted pak
The header parsed but reported a non-positive name, export or import count. Usually a truncated
file or a wrong offset — try upk-header to see how far it got.
Decompression fails or panics
Only LZO is implemented. Zlib and LZX packages are recognised but hit an unimplemented path and abort. A panic inside LZO decompression means the chunk data didn't match its declared size — the file is likely truncated.
Textures extract with no .dds
Three common causes:
- Unmapped pixel format. Only
PF_DXT1,PF_DXT3,PF_DXT5,PF_A8R8G8B8,PF_G8,PF_BC5,PF_FloatRGBAare handled; anything else warns and skips. - Mips live in a
.tfcthat isn't under--game-root. LZO-compressed TFC payloads are inflated; zlib or LZX compression in a TFC hits the same unimplemented path as packages do. - No resolvable mips at all, which the warning states explicitly.
My replacement .dds is rejected
Its top mip has to match one of the original mips' dimensions. To change resolution, also update
SizeX and SizeY in the .uo to your DDS's top mip — that authorises replacing the whole mip
list.
Can I replace audio?
Yes. SoundNodeWave has an injector. Put a replacement next to the .uo; the filename picks which
payload slot it replaces:
| Filename contains | Slot |
|---|---|
.raw. |
Raw PCM |
.xbox360. |
Xbox 360 |
.ps3. |
PS3 |
| none of the above | PC compressed data (expects Ogg) |
On pack the sound's properties (NumChannels, SampleRate, Duration, RawPCMDataSize,
CompressionQuality) are synced from the new payload. A PC payload that doesn't start with OggS
is injected anyway, with a warning.
Can I replace a mesh?
Not yet. StaticMesh and SkeletalMesh extract to .glb for viewing and conversion, but there is
no injector.
Can I edit a class, add a function, or change UnrealScript?
No. Class, struct, enum and const .uo files are read-only reference material — pack-mod skips
them. Bytecode is located and skipped during schema parsing, never decompiled or re-emitted.
type mismatch: original is Int but edit is string
By design. The packer won't coerce types, because a wrong guess produces a package the game will
mis-deserialize. Match the original's form — quotes for strings, bare digits for numbers, 'name'
for names, Enum::Value for enums, &Ref for object references.
struct has no field 'X' in the original export
That field held its default value, so the engine never serialized it. With --game-root the packer
creates it from the schema; without one, it can't know the field's type and fails.
could not resolve object reference '&Foo'
The label was ambiguous or matched nothing. Use a fuller dotted path (Outer.Foo), or extern: for
imports. If the target genuinely doesn't exist yet, the packer reserves a slot and records it in
.newexports instead of failing.
Does pack-mod produce a modified .upk?
No. The output is per-export .bin blobs plus a .newnames file, intended for a runtime loader
such as CU3ML. Repacking a whole package is out of scope —
there is no pack command.
Do I have to ship the .newnames?
Yes. Property tags reference names by index, and almost any edit can append entries. Ship the
.newnames from the same run as the .bin files. It lists only the appended names with their
indices; it is not a full copy of the name table.
Can the GUI extract or build mods?
It can build mods. The mod workspace extracts the objects you select into a temporary directory,
then packs them into <key>/mod.toml, main.lua and overrides/. It doesn't write extracted
files out for hand-editing — use the CLI extract command for that.
Is it slow?
Yes, on large packages. Whole packages are held in memory, import resolution scans export tables
linearly, and resolving one import can pull in and decompress another package. Running
decompress once and working against the flattened file helps.
Will it work on my game?
Anything UE3-era with a package version inside the supported gate range should read. Console (byte-swapped) packages decompress, but console-cooked script layouts aren't handled, so their meta-objects will mis-parse. Expect to add version constants for anything far from the Dishonored-era target.