Skip to content

fix(mod-loader): support subdir streaming entries (ped head_ ydd/ytd) in mods/ - #4193

Open
chocomintw wants to merge 2 commits into
citizenfx:masterfrom
chocomintw:feat/head-replacement
Open

chocomintw wants to merge 2 commits into
citizenfx:masterfrom
chocomintw:feat/head-replacement

Conversation

@chocomintw

@chocomintw chocomintw commented Sep 11, 2026

Copy link
Copy Markdown

Goal of this PR

Make OpenIV-style mod packages in mods/ able to replace ped component files that live in a subdirectory of a streaming rpf — most notably head_*.ydd / head_diff_*.ytd in x64v.rpf/models/cdimages/streamedpeds_mp.rpf/mp_m_freemode_01/ (and streamedpeds_players.rpf/player_zero/). Today such entries are silently dropped.

How is this PR achieving the goal

The game registers these assets under a directory-prefixed slot name (mp_m_freemode_01/head_000_r), which is why resource stream/ uses the dir^file convention. The mod loader lost that directory at three points:

  1. ModVFSDevice only mapped entries whose last archive is update.rpf, a top-level x64N.rpf, or common.rpf; nested archives fell through.
  2. MountModStream required slashCount == 0, so mp_m_freemode_01/head_000_r.ydd was never registered as a streaming file.
  3. The ^/ subdir mapping in LoadStreamingFile.cpp is gated on the server policy [subdir_file_mapping], which doesn't exist at OnInitialMount (no server yet).

Changes:

  • gta-streaming-five: GetBaseName() takes an isMod flag; mod_ / faux_pack tags get subdir mapping without the server policy. Resource behaviour is unchanged. Small IsModTag() helper replaces the inline check.
  • citizen-mod-loader-five: nested-archive entries with a subdirectory target are exposed by ModVFSDevice as stream/<dir>^<file> and registered from MountModStream as modVfs_<guid>:/stream/<dir>^<file>, so the streaming slot keeps its directory. Flat entries and textures/ overrides register exactly as before.

Not covered: a whole streamedpeds_*.rpf dropped in as an .rpf target (MountFauxStreamingRpf is non-recursive, and a packfile can't serve a ^ name).

This PR applies to the following area(s)

FiveM

Successfully tested on

Compiles (Release x64, no new warnings). Not yet tested in-game — will update once verified.

Game builds: ..

Platforms: Windows

Checklist

  • Code compiles and has been tested successfully.
  • Code explains itself well and/or is documented.
  • My commit message explains what the changes do and what they are for.
  • No extra compilation warnings are added by these changes.

Fixes issues

None.

Local mod and faux_pack assets were being treated as flat paths during startup because the server policy was not available yet. This patch adds a mod-tag helper and passes it through streaming file registration/removal so '^' paths are converted for local mod content even without [subdir_file_mapping]. Debug builds also keep subdir mapping enabled to preserve the expected behavior.

Signed-off-by: chocomintw <97966408+chocomintw@users.noreply.github.com>
Add StreamName helper to convert streaming paths (e.g. mp_m_freemode_01/head_000_r.ydd -> mp_m_freemode_01^head_000_r.ydd). Expose subdir streaming entries under "stream/<dir^file>" in ModVFSDevice and register those entries in MountModStream using a modVfs_<guid>:/stream/<dir^file> path so the streaming slot preserves its directory. Also refactor MountModStream logic to always fetch page flags before registering the streaming entry.

Signed-off-by: chocomintw <97966408+chocomintw@users.noreply.github.com>
@github-actions github-actions Bot added triage Needs a preliminary assessment to determine the urgency and required action invalid Requires changes before it's considered valid and can be (re)triaged and removed triage Needs a preliminary assessment to determine the urgency and required action labels Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

invalid Requires changes before it's considered valid and can be (re)triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant