0. Provenance and confidence
Three tiers of claim in this document. Treat them differently.
| Tier | Meaning | Marker |
|---|---|---|
| Verified | Read out of CodeWalker source or a primary format spec. Trust it. | (no marker) |
| Community RE | Reverse-engineered by the modding community, widely used, no official confirmation. Mostly Dekurwinator's flag research (credits: dexyfex, Carl Johnson, kirill_mapper, DPS, Disquse, Mellowtri, Monky, Dekurwinator). | π‘ |
| Folklore | Repeated in tutorials, plausible, unverified. Test before relying on it. | π΄ |
| Pack-verified | Confirmed in-game on this machine via the working eastsidetrailers pack (v8, 2026-07-16) and its v1-v7 failure cycle. Full test cycle: Β§15. | β |
CodeWalker (CodeWalker.Core/GameFiles/) is the de facto spec for everything in this document. When this doc and CodeWalker disagree, CodeWalker is right.
13. Sources
Primary (verified)
github.com/dexyfex/CodeWalker:CodeWalker.Core/GameFiles/RpfFile.cs(RPF7 header, entry layouts, offset masks, per-entry encryption),Utils/GTACrypto.cs(AES-256/ECB/1-round),MetaTypes/MetaTypes.cs(assetType, lodType, priorityLevel enums),FileTypes/YmapFile.cs(LodInParentYmap, parentIndex resolution),Resources/ResourceBuilder.cs(RSC7 ident, gen9 flag)- gtamods.com/wiki/RPF_archive: RPF version table
- gtamods.com/wiki/Cryptography: GTA IV crypto (not V; 16-round figure lives here)
- github.com/Bobrokus/rpf7-docs: RPF7 header/encryption, independent of CodeWalker
- github.com/VIRUXE/rpf-rs: RPF0-RPF8 version/game mapping
Community RE (π‘)
dekurwinator-mods.bitrix24.site/flags/: the source for ytyp flags, entity flags, specialAttribute, MLO portal/room flags, light flags, cargen flags, collision flags. Odd host, but it's the canonical research, credited to dexyfex, Carl Johnson, kirill_mapper, DPS, Disquse, Mellowtri, Monky, Dekurwinatoraltv.stuyk.com/docs/mapping/ytyp-flags.html: partial mirror of the above- github.com/gtasnail/gta5-meta-fileTypes: full fileType enum
- github.com/Sollumz/Sollumz: Blender pipeline + format docs
docs.gta.clothing(Durty Cloth Tool docs): the clothing/tattoo engine limits in Β§16 (ymt slots per game build, the 128/255 component and prop index boundaries, TxdStore pool), plus confirmation of the drawable/texture naming grammar. Those figures are theirs, not our testing; Rockstar moves them every update
Gen9
- gta5-mods.com/tools/openrpf-openiv-asi-for-gta-v-enhanced: OpenRPF, version compat, Gen8/Gen9 warning
- gta5-mods.com/tools/oiv-package-installer
Sections 18 to 27 (drawable internals, ped materials, rendering laws)
- The shipped shaders themselves:
common.rpf/shaders/win32_40_final/*.fxc, sliced on theDXBCmagic and disassembled with the Windows SDKfxc.exe /dumpbin. Every colour law in §19 through §24 is read from a disassembly or from engine code, never inferred from appearance - The game's own data files, read out of a current install:
timecycle/visualsettings.dat,clouds.xml,cloudkeyframes.xml,pedalternatevariations.meta,tint_data.meta, and the ped variation.ymts - Measurements over real assets on this machine: shader censuses across the installed drawable index, texture statistics on real ped/hair/overlay dictionaries, strand-axis and bone-displacement measurements on real hair and rigs. Where a figure came from our own measurement it says so in that section's provenance line
CodeWalker.Corefor struct layouts and the.ydd.xmlschema. Both were corroborated against the engine's own structures before being copied, since CodeWalker carries a few render-side fudges and omits some fields (both called out in §25 and §26)
These sections describe how the shipped game behaves, so that tools can read and render GTA assets the way GTA does. No game code, shader source or asset is reproduced beyond the short excerpts needed to state each law.
14. Corrections log
Changes from the previous revision, with cause.
| Β§ | Was | Now |
|---|---|---|
| 1 | RPF0 = RDR1; RPF3 = GTA IV/EFLC; RPF4 = MP3/RDR1; RPF6 = MP3 | RPF0 = Table Tennis; RPF3 = GTA IV Audio/MCLA; RPF4 = MP3; RPF6 = RDR. Per gtamods + rpf-rs |
| 1 | Magic 0x37465052 |
0x52504637. Old value was byte-swapped |
| 1 | 0x04E45504F |
0x4E45504F. Nine hex digits, inherited from a typo in CodeWalker's comment |
| 1 | AES-128 | AES-256, ECB, no padding, 1 round. The 16-round figure is GTA IV |
| 1 | "Individual files are not encrypted, only compressed" | False. Per-entry EncryptionType; data decrypted before inflate. This is why NG keys on filename+size |
| 1 | "Hard 4 GB practical limit" | Real, and explained: resource-entry offsets mask to 23 bits (~4 GB); binary entries get 24 (~8 GB) |
| 3 | "y = win64/PC; consoles use x/w/c" |
Cut. That's GTA IV (wdr/xdr/cdr). GTA V uses .ydr everywhere |
| 2 | (absent) | New section. Gen8/Gen9 split, OpenRPF, conversion requirement |
| 5 | Archetype flags table | Replaced. Only 2 (DONT_FADE) and 32 (IS_FIXED) survived. 4β don't-write-Z (that's 64); tree is 65536 not 1048576; SUPPRESS_HD_TXDS is 16 not 67108864 |
| 5 | specialAttribute: 1=ladder, 3=SA_DOOR, 31=SA_STREET_LIGHT |
Replaced. Ladder=2, traffic light=3, street light=32. The SA_* names were GTA IV IDE attributes |
| 6 | Entity flags: "1572864 = common for scripted" |
1572864 = LIGHTS_CAST_STATIC_SHADOWS + LIGHTS_CAST_DYNAMIC_SHADOWS. Full table added |
| 6 | parentIndex: doc said same ymap, review said parent ymap |
Both half-right. Depends on entity flag bit 3 (FLAG_ATTACH_LOD_IS_IN_PARENT_MAPDATA / CodeWalker's LodInParentYmap) |
| 6 | lodLevel list, no numbers | Numbered. ORPHANHD=5 sits between SLOD3 and SLOD4, which explains CodeWalker's root-check special case |
| 6 | "vertex-paint LODs or they glow at night" | Real mechanism is FLAG_USE_AMBIENT_SCALE (536870912) |
| 8 | "embedded ignores ymap scale; standalone respects nothing either" | Clarified: entity scale never applies to collision, period |
| 9 | Garbled "Sollumz-Blender / GIMS Evo (3ds Max)" row | Split. OpenRPF/OIV Installer added |
| 13 | bitrix24 site dismissed as non-citable | Reinstated. It's the canonical community flag research. The host is ugly; the data is the best available |
| N/A | All XML examples empty | Reconstructed |
| 5,6,8 | (absent) | MLO portal flags, MLO room flags, light flags, cargen flags, collision include-flags added |
2026-07-16b: pack-verified pass (findings from building the working eastsidetrailers DLC; full failure cycle v1βv8 in Β§15):
| Β§ | Was | Now |
|---|---|---|
| 0 | three tiers | Added β Pack-verified tier |
| 4 | ytyp listed under _metadata.rpf universally |
β
Working variant ships ytyp WITH the models (map_props.rpf); meta rpf needs CONTENTS_DLC_MAP_DATA; one-rpf builds silently fail |
| 4 | Only a generic GROUP_STARTUP example | β
Added the map-DLC pattern: CCS_*_NG_STREAMING_MAP under GROUP_UPDATE_STREAMING with $level=MO_JIM_L11 |
| 4 | isLevelPack "full new levels only (rare, fragile)" |
β LEVEL_PACK + isLevelPack=true is the proven map-add-on pattern (template1, BLSM, eastsidetrailers) |
| 4 | "Every ytyp needs a DLC_ITYP_REQUEST" | β
Optional when the manifest declares imapβityp deps; device-root .ytyp form = CTD; in-rpf path or device-root .ityp are the valid forms |
| 7 | Manifest example filled only imapDependencies_2 |
β Both dep forms (pair + array) required/shipped by working packs |
| 9 | CodeWalker.Core row bare | β
dev48 binary bug + the GetFileData headerless-export trap documented |
| 11 | (absent) | β
Added: binary-entry ERR_SYS_INVALIDRESOURCE_5, silent no-load causes, ityp-request/double-enable CTDs |
2026-08-13: drawable internals and rendering laws (§18 through §27 added; each correction below is something published tooling or community guidance still gets wrong):
| Β§ | Common belief | What the game does |
|---|---|---|
| 18 | grcTexture DataPointer at 0x60 |
0x70. 0x60 decodes to noise on every real file |
| 19 | Hair tint multiplies the diffuse | Replaces it: mp_hair_tint.Sample(diffuse.r, index). Multiplying renders every blonde muddy brown |
| 19 | Palette-component diffuse alpha is opacity | A palette index, 32..160, in bucket 0 which ignores alpha. Treating it as opacity is why exported gloves come out half-transparent |
| 19 | All head overlays composite the same way | Two shapes: tinted masks alpha-composite; neutral-grey detail maps (blemishes, ageing, complexion) blend in encoded space around 128. Split on pixels, never on DXT format |
| 20 | Hair layers: drop orderNumber > 0, or draw them all |
Both are wrong for some family. Only ped_hair_spiked* order 1 is a normals-only pass; cutout hair never reads the field |
| 20 | The shipped vertex tangent follows the strand | It follows U. The strand axis is UV dP/dv (|cos| 0.95 to 0.97, against 0.20 to 0.31) |
| 21 | hair_NNN_u_1 is what the engine swaps in under a hat |
Hats deform hair via expressionMods β MH_Hair_Scale/MH_Hair_Crown. Alternates are sourced from other components, never a prop anchor |
| 22 | The ped spec map's blue is gloss | Material ID. R = intensity, G = exponent, both squared; B never lights anything |
| 23 | GTA skin SSS is a material parameter | A 13-tap screen-space diffusion blur in the deferred pass, radius β 1/depth |
| 24 | cloth_* shaders mean fabric type |
No fabric model exists. The cloth flag flips normals for back faces; translucency reuses the skin SSS pass |
| 26 | Drawable lights fall off inverse-square with a cone exponent | (1 β dΒ²/rΒ²)^e, hard zero at the range; cone is linear in cosine with no exponent |
2026-08-14: the RPF size ceiling (this document's own error, found while answering whether the limit can be lifted):
| § | Was | Now |
|---|---|---|
| 1 | Binary entries get 24 offset bits, so about 8.0 GB addressable | Wrong. The top bit of the 24-bit FileOffset is the binary-vs-resource tag, the same bit the reader branches on. A binary entry must leave it clear, so it gets 23 usable bits like a resource entry. Both cap at 4.0 GB; the 8 GB figure was never reachable |
| 1 | "CodeWalker masks resource-entry offsets to 23 bits", implying a tool-side choice | The mask is correct parsing of a tagged field. The ceiling is in the 16-byte entry layout, and both layouts use all 16 bytes, so there is no spare bit to widen the offset with |
| 1 | (absent) | Added: measured retail evidence (nothing in a current install crosses 4 GB; the largest is mpbattle/dlc.rpf at 92.7% of the ceiling; mpheist4 splits into dlc.rpf + dlc1.rpf rather than exceeding it), that the ceiling is per archive rather than per project, and what raising it would actually require |
2026-08-14b: read from the engine (the ceiling claims were checked against a
decrypted memory image of a running GTA5.exe, so several yellow-tier items moved up
a tier and one documented field turned out to be wrong):
| § | Was | Now |
|---|---|---|
| 1 | π‘ The bit-level entry layout, inferred from CodeWalker plus the retail archives | Measured. The engine loads the literal 0x7FFFFF itself, extracts the offset with shr 0x28 and tests bit 63 as the type tag, in at least two independent decoders. The ceiling is the engine's arithmetic, not a tool's |
| 1 | NamesLength is "size of the name table in bytes" |
Incomplete. It is 28 bits of length plus a 3-bit field and a flag. The engine masks with 0xFFFFFFF and stores the top four bits separately. Reading it flat works only because those bits are zero in retail archives |
| 1 | (absent) | Added: an all-ones offset is a sentinel the engine tests separately from the range, so it is not merely a large offset |
| 1 | "raising the ceiling would need an ASI patch", cost unquantified | Quantified: 11 correlated offset decoders exist, so a patch has no single place to change. Some may be inlined copies; distinguishing them needs control-flow analysis not yet done |
| 1 | Over-size archives blamed on the packer alone | Root cause added: RpfBinaryFileEntry.Write in CodeWalker writes the offset with no bounds check, so a packer with no ceiling of its own inherits a silent type change instead of an error |
2026-08-15: the unverified claims, swept (every π‘ and π΄ marker in this reference was pushed against a primary source β the decrypted image, RAGE engine source, or CodeWalker. Some moved up, one was refuted, and the ones that did not move now record where the answer would have to come from):
| § | Was | Now |
|---|---|---|
| 1 | The 512-byte block unit, unexamined | Measured. The byte offset is shr rax,0x28 then shl eax,9 β a 32-bit shift, so the tag bit is truncated and the ceiling is enforced a second time by operand width, with no constant to pattern-match on. The 9 is an immediate at all five sites, so there is nowhere in the format to declare a different block size |
| 1 | Header dword 3 carries a 3-bit field of unknown meaning | Identified. It is the left-shift applied to every entry's 16-bit NameOffset, read at six sites, and it is how a name heap exceeds 64 KB. Zero in every retail archive. CodeWalker neither writes nor checks it, so it is a latent writer bug of the same family as the offset one |
| 1 / 12 | π΄ "oversized RPF β ERR_FIL_PACK_3" |
Refuted. Nothing range-checks the offset, so an over-size archive mounts and reads wrong instead of raising a packfile error. Expect ERR_SYS_INVALIDRESOURCE_5 or ERR_GEN_ZLIB_2. The real RAGE packfile codes, ERR_STR_PACK_1/2, are missing-file conditions |
| 1 / 12 | π΄ ERR_GEN_ZLIB_2 β corrupt entry |
Confirmed, with scope. RAGE raises it from zlibInflater::InflateBegin on any negative inflate() return. Generic to any inflated stream, not RPF-specific; retail builds blank the filename from the message |
| 12 | π΄ DLC_ITYP_REQUEST missing β crash |
Confirmed. A real CDataFileMgr type with its own mounter, registered eDFMI_UnloadLast, and the loader only verifies the file exists |
| 12 | π΄ gameconfig pool exhaustion | Confirmed, and explained. RAGE names gameconfig.xml in four separate limit messages, but every one is an Assertf that compiles out of the shipped build β so the retail game overruns the limit silently, which is why the symptom is an unexplained crash rather than a named pool |
| 3 | π‘ specialAttribute |
Engine-confirmed as an enum, not a bitfield (RAGE tests it with ==), and all six attribute names that appear in engine code are already in the table. The numeric mapping is still community research |
| 6 | π‘ Light flags | 21 of the 30 match a RAGE LIGHTFLAG_* name exactly; nine have no counterpart and are flagged as the least certain. Bit ordering still community research |
| 8 | π‘ Unk VertOffset 0.002 / 0.02 | Refined. It is the collision margin: default 0.04 for geometry bounds, clamped to the bound's half-extent when it is too thin to shrink. The two quoted figures are observations of that clamp, not rules |
| 6 | π‘ Render mask | Unchanged, but searched: the field is RenderMaskFlags at DrawableModel + 0x2C and no available engine source assigns its bits |