4. DLC packs
Folder structure
mods/update/x64/dlcpacks/mypack/
└─ dlc.rpf
├─ setup2.xml
├─ content.xml
├─ common/data/ # handling.meta, carcols.meta, …
├─ data/ # alternative meta location
└─ x64/
├─ levels/gta5/
│ ├─ mypack.rpf # ydr/ydd/ybn/ytd
│ └─ mypack_metadata.rpf # ymap/ytyp/ymf
├─ vehicles.rpf
└─ vehiclemods/foo_mods.rpf
Convention (Rockstar's):
_metadata.rpf→.ymap,.ytyp,_manifest.ymf.rpf(main) →.ydr,.ydd,.yft,.ybn,.ytd
✅ Pack-verified variant (Dekurwinator template1 / eastsidetrailers): the .ytyp
travels with the models, not the metadata:
map_props.rpf(no<contents>tag) →.ydr.ydd.yft.ytd+.ytypmap_meta.rpf(<contents>CONTENTS_DLC_MAP_DATA</contents>) →.ymap.ybn_manifest.ymf
✅ Putting models+ytyp inside the CONTENTS_DLC_MAP_DATA rpf (or everything in one rpf)
mounts fine but the props silently never load, a verified failure mode, twice (v4/v5).
Splitting metadata out is not inherently fatal: the pack-verified template (§4) puts ymap/ybn/
_manifest.ymfinmap_meta.rpf, separate from the models, and loads fine in SP. The crash reports (documented as a caveat on the gta5-mods DLC Pack Creator tool page) trace to a specific broken arrangement, usually a missing manifest ityp dependency or aDLC_ITYP_REQUESTaimed at the wrong rpf. Fix the dependency, not the split.✅ Counterpoint from the working pack: the split is what made props load. If a split pack misbehaves, check first: models/ytyp misplaced into the map-data rpf, missing
CONTENTS_DLC_MAP_DATA, or resources imported as binary entries (§11). Don't merge the rpfs as a first resort.
setup2.xml
<?xml version="1.0" encoding="UTF-8"?>
<SSetupData>
<deviceName>dlc_mypack</deviceName>
<datFile>content.xml</datFile>
<timeStamp>05/06/2026 00:00:00</timeStamp>
<nameHash>mypack</nameHash>
<contentChangeSets/>
<contentChangeSetGroups>
<Item>
<NameHash>GROUP_STARTUP</NameHash>
<ContentChangeSets>
<Item>mypack_AUTOGEN</Item>
</ContentChangeSets>
</Item>
</contentChangeSetGroups>
<startupScript/>
<scriptCallstackSize value="0"/>
<type>EXTRACONTENT_COMPAT_PACK</type>
<order value="80"/>
<minorOrder value="0"/>
<isLevelPack value="false"/>
<dependencyPackHash/>
<requiredVersion/>
<subPackCount value="0"/>
</SSetupData>
| Field | Meaning |
|---|---|
deviceName |
Virtual mount point. dlc_mypack:/ is how content.xml refers to files. Must be unique. |
nameHash |
Pack identity used by changesets. Usually matches folder name. |
type |
EXTRACONTENT_COMPAT_PACK (safe default) or EXTRACONTENT_LEVEL_PACK. ✅ LEVEL_PACK is the proven choice for map/props add-ons (template1, BLSM, eastsidetrailers) |
order |
Mount priority: higher = later = overrides earlier. Order comes from this value and the dlclist.xml entry sequence, not from any number in the folder name. Numbering mod packs 80+ is just a filing habit; the engine parses no digit from the folder. |
isLevelPack |
✅ true on every working map add-on pack examined (template1, BLSM, eastsidetrailers, order 2). The "full new levels only, fragile" claim didn't hold up |
startupScript / scriptCallstackSize |
Only if you ship a .ysc |
subPackCount |
✅ How many extra archives the pack ships beyond dlc.rpf. The loader mounts dlc1.rpf, dlc2.rpf … up to this count, so files on disk = subPackCount + 1. This is the supported way past the 4 GB per-archive ceiling. Verified against all 45 packs in a retail install: mpheist4 declares 2 and ships three archives, mpbattle and mpsecurity declare 1 and ship two, everything else declares 0. Sub-packs carry no setup2.xml or content.xml of their own and mount into the same deviceName, so content.xml addresses every file the same way regardless of which archive holds it. Two early packs (mpchristmas2, mpheist) omit the field; absent reads as 0 |
content.xml
<?xml version="1.0" encoding="UTF-8"?>
<CDataFileMgr__ContentsOfDataFileXml>
<disabledFiles/>
<includedXmlFiles/>
<includedDataFiles/>
<dataFiles>
<Item>
<filename>dlc_mypack:/%PLATFORM%/levels/gta5/mypack_metadata.rpf</filename>
<fileType>RPF_FILE</fileType>
<overlay value="false"/>
<disabled value="true"/>
<persistent value="true"/>
</Item>
<Item>
<filename>dlc_mypack:/%PLATFORM%/levels/gta5/mypack.rpf</filename>
<fileType>RPF_FILE</fileType>
<overlay value="false"/>
<disabled value="true"/>
<persistent value="true"/>
</Item>
<Item>
<filename>dlc_mypack:/%PLATFORM%/levels/gta5/mypack_metadata.rpf/mypack.ytyp</filename>
<fileType>DLC_ITYP_REQUEST</fileType>
<overlay value="false"/>
<disabled value="true"/>
<persistent value="false"/>
</Item>
<Item>
<filename>dlc_mypack:/common/data/handling.meta</filename>
<fileType>HANDLING_FILE</fileType>
<overlay value="true"/>
<disabled value="true"/>
</Item>
</dataFiles>
<contentChangeSets>
<Item>
<changeSetName>mypack_AUTOGEN</changeSetName>
<filesToInvalidate/>
<filesToDisable/>
<filesToEnable>
<Item>dlc_mypack:/%PLATFORM%/levels/gta5/mypack_metadata.rpf</Item>
<Item>dlc_mypack:/%PLATFORM%/levels/gta5/mypack.rpf</Item>
<Item>dlc_mypack:/%PLATFORM%/levels/gta5/mypack_metadata.rpf/mypack.ytyp</Item>
<Item>dlc_mypack:/common/data/handling.meta</Item>
</filesToEnable>
<txdToLoad/>
<txdToUnload/>
<residentResources/>
<unregisterResources/>
<executionConditions/>
</Item>
</contentChangeSets>
<patchFiles/>
</CDataFileMgr__ContentsOfDataFileXml>
Rules of thumb:
%PLATFORM%expands tox64on PC. Don't hardcode.- Anything with
<disabled value="true"/>must appear in a changeset'sfilesToEnable, or it never loads. overlay="true"= merge into the existing global list (metas).overlay="false"= plain mount (rpfs).persistent="true"= never unloaded once mounted.- Every
.ytypneeds its ownDLC_ITYP_REQUESTentry, path pointing inside the rpf. ✅ Nuance: with correct_manifest.ymfimap→ityp deps, map-streamed ytyps work with no request at all (template1 ships none); keeping one is harmless belt-and-braces. Valid forms: full in-rpf path to the physical.ytyp(✅ working pack), or device-root with.itypextension (R/gtawprops style). 💥 Device-root with.ytyp= CTD at startup* (verified). - Ordering inside
dataFilesmatters for metas: later overlays win.
✅ Map DLC content.xml: the pack-verified pattern
The generic example above (GROUP_STARTUP changeset, disabled=true/persistent=true)
is the props-pack pattern (gtawprops etc.), which loads ityps for object spawners but
does not stream ymaps (verified failure v1). A map DLC needs the streaming changeset
with a level condition:
<dataFiles>
<Item>
<filename>dlc_mypack:/%PLATFORM%/levels/gta5/props/map_props.rpf</filename>
<fileType>RPF_FILE</fileType>
<overlay value="false"/> <disabled value="false"/> <persistent value="false"/>
</Item>
<Item>
<filename>dlc_mypack:/%PLATFORM%/levels/gta5/props/map_meta.rpf</filename>
<fileType>RPF_FILE</fileType>
<overlay value="false"/> <disabled value="false"/> <persistent value="false"/>
<contents>CONTENTS_DLC_MAP_DATA</contents>
</Item>
<Item>
<filename>dlc_mypack:/%PLATFORM%/levels/gta5/props/map_props.rpf/mypack.ytyp</filename>
<fileType>DLC_ITYP_REQUEST</fileType>
<overlay value="false"/> <disabled value="true"/> <persistent value="true"/>
</Item>
</dataFiles>
<contentChangeSets>
<Item>
<changeSetName>CCS_MYPACK_NG_STREAMING_MAP</changeSetName>
<filesToEnable>
<Item>dlc_mypack:/%PLATFORM%/levels/gta5/props/map_props.rpf</Item>
<Item>dlc_mypack:/%PLATFORM%/levels/gta5/props/map_meta.rpf</Item>
<Item>dlc_mypack:/%PLATFORM%/levels/gta5/props/map_props.rpf/mypack.ytyp</Item>
</filesToEnable>
<executionConditions>
<activeChangesetConditions>
</activeChangesetConditions>
<genericConditions>$level=MO_JIM_L11</genericConditions>
</executionConditions>
</Item>
</contentChangeSets>
$level=MO_JIM_L11= GTA V's main SP map level; the changeset fires when it loads.- Pair with setup2: changeset under
GROUP_UPDATE_STREAMING,EXTRACONTENT_LEVEL_PACK,isLevelPack=true,order 2(template1 verbatim).
fileType values (the common ones)
Archives / map
RPF_FILE, RPF_FILE_PRE_INSTALL, RPF_FILE_PRE_INSTALL_ONLY, PERMANENT_ITYP_FILE, DLC_ITYP_REQUEST, IPL_FILE, IDE_FILE, DELAYED_IDE_FILE, EXTRA_FOLDER_MOUNT_DATA, ZONED_ASSET_FILE
Vehicles
VEHICLE_METADATA_FILE, HANDLING_FILE, CARCOLS_FILE, CARGRP_FILE, VEHICLE_VARIATION_FILE, VEHICLE_LAYOUTS_FILE, VEHICLE_POPULATION_FILE, VEHICLE_CAMERA_OFFSETS_FILE, VEHICLEEXTRAS_FILE, VFXVEHICLEINFO_FILE
Peds
PEDSTREAM_FILE, PEDGRP_FILE, PED_METADATA_FILE, PED_PERSONALITY_FILE, PED_VARS_FILE, PED_BOUNDS_FILE, PED_HEALTH_FILE, PED_COMPONENT_SETS_FILE, PED_OVERLAY_FILE, PED_TASK_DATA_FILE, PED_BRAWLING_STYLE_FILE, PED_FIRST_PERSON_ASSET_DATA
Weapons
WEAPONINFO_FILE, WEAPONINFO_FILE_PATCH, WEAPON_METADATA_FILE, WEAPONCOMPONENTSINFO_FILE, LOADOUTS_FILE, PICKUPS_FILE, EXPLOSION_INFO_FILE
World / population
POPGROUP_FILE, DLC_POP_GROUPS, SCENARIO_INFO_FILE, SCENARIO_POINTS_FILE, AMBIENT_ZONE_FILE, TRAFFIC_LIGHT_FILE, POPSCHED_FILE
Audio
AUDIO_SOUNDDATA, AUDIO_WAVEPACK, AUDIO_GAMEDATA, AUDIO_SYNTHDATA, AUDIO_DYNAMIXDATA, AUDIO_SPEECHDATA
Text / misc
TEXTFILE_METAFILE, GXT2_FILE, SCALEFORM_PREALLOC_FILE, SCALEFORM_VALID_METHODS_FILE, CONDITIONAL_ANIMS_FILE, CLIP_SETS_FILE, EXPRESSION_DLC_FILE, SHOP_PED_APPAREL_META_FILE, TATTOO_SHOP_DLC_FILE
(Full enumeration: github.com/gtasnail/gta5-meta-fileTypes)
Registration (SP)
mods/update/update.rpf/common/data/dlclist.xml:
<Item>dlcpacks:/mypack/</Item>
mods/update/update.rpf/common/data/extratitleupdatedata.meta, required if your DLC needs a device mount:
<Item>
<deviceName>dlc_mypack</deviceName>
<datFile>dlcpacks:/mypack/dlc.rpf</datFile>
</Item>
Also: mods/update/update.rpf/common/data/gameconfig.xml, bump pool sizes when you add lots of archetypes/props (ConfigArchetypeManager, MaxNoOfVisibleEntities, fwStaticBoundsStore). Separately, the "worked fine until my Nth DLC" crash is ERR_FIL_PACK_1: the exe has a fixed cap on how many packfiles (RPFs) it will mount, and enough dlcpacks exhausts it. Raise it with the Packfile Limit Adjuster. The count that trips it varies with how many RPFs each pack ships, so there is no fixed "40".
15. Appendix: the pack-verified test cycle
The ✅ claims in this document come from building a real standalone SP add-on
(eastsidetrailers, two ymaps + six custom trailer props extracted from a larger map
pack into a self-contained dlc.rpf). It took eight builds to get a working pack; every
failure and its root cause:
| Build | Loader / structure | Symptom | Root cause |
|---|---|---|---|
| v1 | props-pack pattern (GROUP_STARTUP enable, device-root .ytyp ityp request) |
loads, maps never appear | props loaders don't stream ymaps |
| v2 | + overlay=true + GROUP_MAP mapChangeSetData enabling the same rpf again |
CTD at startup | double-enable; .ytyp device-root ityp request |
| v3 | ityp request .ityp; empty cache-loader map changesets |
CTD | wrong changeset combo (latent: binary-entry ydrs) |
| v4 | single rpf, CONTENTS_DLC_MAP_DATA, $level changeset, LEVEL_PACK |
no CTD, nothing loads | models+ytyp inside the map-data rpf |
| v5 | full map-overhaul clone (overlay + GROUP_MAP + useCacheLoader) |
no CTD, nothing loads | same split violation |
| v6 | template1: map_props.rpf + map_meta.rpf split, one $level changeset |
streams! CTD on approach: ERR_SYS_INVALIDRESOURCE_5 |
the .ydrs were binary entries, extracted headerless, mis-imported |
| v7 | + in-rpf ityp request, re-saved ymaps | same CTD | same binary ydrs |
| v8 | proper RSC7 export (Compress + AddResourceHeader), byte-original ytyp/ymaps |
✅ works | N/A |
The validation gates that would have caught all of it before launch:
- Every
.y*file in the built rpf is a resource entry, never a binary entry. - RSC7 magic + version per type (
ydr165,yft162,ytd13,ybn43,ymap/ytyp2). - Every ymap entity archetype resolves against bundled ytyps ∪ the vanilla game.
- Manifest imap names match bundled ymaps; ityp deps match bundled ytyps; both dep forms present.
- Every
disabled=truecontent.xml entry appears in a changeset'sfilesToEnable. - No models/ytyps inside the
CONTENTS_DLC_MAP_DATArpf, no ymaps outside it. - Extraction fidelity: re-extracted bytes equal the source (compared through the same API form).
- Total rpf size below 4 GB.
In-game triage, once it's installed:
- Crash at startup → content.xml / setup2.xml (changesets, ityp requests, double-enables).
- Loads, nothing appears → streaming pattern, props/meta split, or manifest deps.
- Loads, crash on approach → a streamed resource is invalid (entry type, header, version).
- Appears untextured → txd reference; no collision → physicsDictionary / ybn list.