No description
  • Python 93.3%
  • Shell 6.6%
  • Dockerfile 0.1%
Find a file
2026-07-06 13:19:03 -05:00
docs default to system tools, then use vendored & update mkpfs 2026-06-07 15:22:13 -05:00
ps5_mountaneer update 2026-07-06 13:19:03 -05:00
tests default to system tools, then use vendored & update mkpfs 2026-06-07 15:22:13 -05:00
tools default to system tools, then use vendored & update mkpfs 2026-06-07 15:22:13 -05:00
vendor default to system tools, then use vendored & update mkpfs 2026-06-07 15:22:13 -05:00
.gitignore add image patching & add real sample tests 2026-06-07 12:37:58 -05:00
AGENTS.md add run logging, live progress, and general fixes 2026-06-07 10:10:59 -05:00
mkexfat_linux.sh add more formats 2026-06-03 09:42:46 -05:00
mkufs2_freebsd_docker.sh work on migrating to ps5 & cross-platform support 2026-06-05 09:22:05 -05:00
ps5-mountaneer work on migrating to ps5 & cross-platform support 2026-06-05 09:22:05 -05:00
ps5-mountaneer.cmd work on migrating to ps5 & cross-platform support 2026-06-05 09:22:05 -05:00
pyproject.toml work on migrating to ps5 & cross-platform support 2026-06-05 09:22:05 -05:00
README.md default to system tools, then use vendored & update mkpfs 2026-06-07 15:22:13 -05:00
THIRD_PARTY_NOTICES.md add fakelib staging, ampr auto-detect & mkpfs capability probing 2026-06-07 08:34:14 -05:00

ps5-mountaneer

Cross-platform image builders for ShadowMountPlus-targeted PS5 game dumps.

ShadowMountPlus accepts four image families, and this tool exposes all of them:

  • .ffpkg / UFS2: recommended ShadowMountPlus default. Built with UFS2Tool, native FreeBSD tools, host QEMU/FreeBSD, or Docker/Podman fallback.
  • .exfat: compatibility format for titles that behave better as external-drive-style content. Built with Linux, macOS, or Windows host tools.
  • .ffpfs: direct PFS image built with MkPFS. This is first-class here, but still experimental in ShadowMountPlus runtime compatibility.
  • .ffpfsc: MkPFS/PFSC container wrapping an existing .ffpkg or .exfat image. This is the recommended compression path; generated names include the nested base format, such as .ffpkg.ffpfsc or .exfat.ffpfsc.

The source folder must be the game root and contain:

eboot.bin
sce_sys/param.json

The generated .ffpkg, .exfat, and .ffpfs images place those files directly at image root, not under an extra top-level folder. .ffpkg.ffpfsc and .exfat.ffpfsc containers hold a nested .ffpkg or .exfat image instead.

See docs/format-contracts.md for the compatibility contract agents and contributors should preserve when changing format policy or backend behavior.

Requirements

Python 3.10+ is required for the CLI launcher.

Docker-free UFS2 path:

(cd ../UFS2Tool && dotnet build UFS2Tool.csproj)
./ps5-mountaneer --config ./mountaneer.ini config init
./ps5-mountaneer --config ./mountaneer.ini doctor

UFS2Tool creates/checks UFS2 image files on Linux, macOS, and Windows without root, Docker, or a FreeBSD VM. The auto policy now prefers UFS2Tool when it is available, then falls back to native FreeBSD, host QEMU/FreeBSD, and Docker/Podman FreeBSD paths.

Linux exFAT requirements:

sudo dnf install exfatprogs rsync

Optional Fedora fallback requirements for host QEMU or container UFS2:

sudo dnf install qemu-system-x86 qemu-img xorriso openssh-clients xz
sudo dnf install pv  # optional progress meter
sudo dnf install moby-engine
sudo systemctl enable --now docker

macOS exFAT uses built-in hdiutil, newfs_exfat, mount, and rsync. Windows exFAT uses OSFMount, format.com, and robocopy.exe; run the command from an Administrator shell.

MkPFS can also be used from a local checkout:

(cd ../MkPFS && uv sync --group dev)
MKPFS_BIN="../MkPFS/.venv/bin/mkpfs" ./ps5-mountaneer info ./PPSA12345.ffpkg.ffpfsc

Usage

Estimate local allocation-based formats:

./ps5-mountaneer estimate /path/to/APPXXXX
./ps5-mountaneer estimate --format ufs2 /path/to/APPXXXX ./PPSA12345.ffpkg
./ps5-mountaneer estimate --format pfs /path/to/APPXXXX ./PPSA12345.ffpfs

Recommend the balanced format:

./ps5-mountaneer recommend /path/to/APPXXXX
./ps5-mountaneer recommend --probe-pfsc /path/to/APPXXXX
./ps5-mountaneer recommend --base-format exfat --probe-pfsc /path/to/APPXXXX

Create by output suffix. --format is optional when the destination has a known ShadowMountPlus image suffix:

./ps5-mountaneer create /path/to/APPXXXX ./PPSA12345.ffpkg
./ps5-mountaneer create /path/to/APPXXXX ./PPSA12345.exfat
./ps5-mountaneer create /path/to/APPXXXX ./PPSA12345.ffpfs
./ps5-mountaneer create /path/to/APPXXXX ./PPSA12345.ffpkg.ffpfsc
./ps5-mountaneer create /path/to/APPXXXX ./PPSA12345.exfat.ffpfsc

Generate an AMPR resolver index while creating an image:

./ps5-mountaneer create --ampr-index /path/to/APPXXXX ./PPSA12345.ffpkg
./ps5-mountaneer create --ampr-index --base-format exfat /path/to/APPXXXX ./PPSA12345.exfat.ffpfsc

Generate or check an AMPR index directly:

./ps5-mountaneer ampr-index /path/to/APPXXXX
./ps5-mountaneer ampr-index --check --json /path/to/APPXXXX

Inject AMPR/PlayGo/DLC fakelib helpers while creating an image. This uses a temporary hardlink staging tree and leaves the source dump unchanged:

./ps5-mountaneer create --fakelib-preset ampr /path/to/APPXXXX ./PPSA12345.ffpkg
./ps5-mountaneer create --fakelib-preset all --fakelib-variant release /path/to/APPXXXX ./PPSA12345.ffpkg.ffpfsc
./ps5-mountaneer create --fakelib-preset all --dlc-config ./dlc_emu.ini --playgo-dat ./playgo_stub.dat /path/to/APPXXXX ./PPSA12345.ffpkg
./ps5-mountaneer prepare-fakelib --fakelib-preset ampr --ampr-index /path/to/APPXXXX

Inspect existing emulator files in a raw dump:

./ps5-mountaneer emulation-info /path/to/APPXXXX
./ps5-mountaneer emulation-info --json /path/to/APPXXXX

Create UFS2 / .ffpkg explicitly:

./ps5-mountaneer create --format ufs2 /path/to/APPXXXX ./PPSA12345.ffpkg

Create exFAT / .exfat explicitly:

./ps5-mountaneer create --format exfat /path/to/APPXXXX ./PPSA12345.exfat

Create direct PFS / .ffpfs explicitly:

./ps5-mountaneer create --format pfs /path/to/APPXXXX ./PPSA12345.ffpfs

Create PFSC / .ffpfsc from a game root explicitly. This creates an intermediate UFS2 .ffpkg by default, wraps it with MkPFS, and removes the intermediate file:

./ps5-mountaneer create --format pfsc /path/to/APPXXXX ./PPSA12345.ffpkg.ffpfsc
./ps5-mountaneer create --format pfsc --base-format exfat /path/to/APPXXXX ./PPSA12345.exfat.ffpfsc

Create the balanced auto format. With an extensionless stem, the tool writes .ffpkg, .exfat, .ffpkg.ffpfsc, or .exfat.ffpfsc after applying the selected policy. With --format auto and a final image suffix, the suffix constrains the output family:

./ps5-mountaneer create /path/to/APPXXXX ./PPSA12345
./ps5-mountaneer create --format auto /path/to/APPXXXX ./PPSA12345
./ps5-mountaneer create --format auto /path/to/APPXXXX ./PPSA12345.ffpkg
./ps5-mountaneer create --format auto --base-format exfat /path/to/APPXXXX ./PPSA12345
./ps5-mountaneer --progress never create --format auto /path/to/APPXXXX ./PPSA12345

Wrap an existing .ffpkg or .exfat as PFSC:

./ps5-mountaneer wrap --format pfsc ./PPSA12345.ffpkg ./PPSA12345.ffpfsc
./ps5-mountaneer wrap --format pfsc ./PPSA12345.ffpkg ./PPSA12345.ffpkg.ffpfsc
./ps5-mountaneer wrap --format pfsc ./PPSA12345.exfat ./PPSA12345.exfat.ffpfsc

Verify or inspect:

./ps5-mountaneer verify ./PPSA12345.ffpkg
./ps5-mountaneer verify ./PPSA12345.exfat
./ps5-mountaneer verify ./PPSA12345.ffpfs
./ps5-mountaneer verify ./PPSA12345.ffpkg.ffpfsc
./ps5-mountaneer info ./PPSA12345.ffpkg.ffpfsc

Inspect backend availability:

./ps5-mountaneer setup
./ps5-mountaneer setup --install-bundled --write-config
./ps5-mountaneer plan --json /path/to/APPXXXX ./PPSA12345
./ps5-mountaneer plan --json --jobs 2 --temp-dir /fast/tmp --verify full /path/to/APPXXXX ./PPSA12345.ffpkg.ffpfsc
./ps5-mountaneer doctor
./ps5-mountaneer doctor --format ufs2
./ps5-mountaneer doctor --format fakelib
./ps5-mountaneer doctor --json

Stage helper payloads from sibling checkouts into vendor/:

python3 tools/vendor_helpers.py
./ps5-mountaneer setup --install-bundled --write-config

The vendor layout is vendor/<platform>/bin for launchers/binaries, vendor/src for bundled source, and vendor/licenses for notices. Explicit config/env paths still override everything. Otherwise, system tools found on PATH are preferred, and bundled/cache helpers are used only as fallbacks.

Create and inspect a persistent config:

./ps5-mountaneer config path
./ps5-mountaneer config init
./ps5-mountaneer config show
./ps5-mountaneer --config ./mountaneer.ini config show --json

Behavior

UFS2:

  • Uses FreeBSD newfs -O 2 -b 65536 -f 65536 -m 0 -S 4096.
  • Auto-tunes -i from source file/directory count.
  • Adds SM_UFS2_EXTRA_PERCENT=2 headroom by default.
  • Preflights output free space and optional FreeBSD cache free space.
  • Auto backend order is: UFS2Tool, native FreeBSD, host QEMU/FreeBSD, then Docker/Podman FreeBSD. Set SM_UFS2_BACKEND=ufs2tool|freebsd-native|qemu|container, use --ufs-backend, or configure [ufs2] backend=....
  • UFS2Tool verification runs fsck_ufs -n plus root-file stat checks.
  • FreeBSD-backed verification runs fsck_ffs -n, mounts read-only, and checks eboot.bin plus sce_sys/param.json at image root.

exFAT:

  • Uses 64 KiB clusters.
  • Auto-sizes the image using 64 KiB allocation, metadata estimates, and safety margin.
  • Linux uses mkfs.exfat -F -c 64K, copies with rsync --info=progress2, and verifies with fsck.exfat -n.
  • Linux exFAT create/verify should be run as the normal user. The tool prompts with sudo -v only for mount/umount operations, so MkPFS and Python dependencies still resolve from the user's environment.
  • macOS uses hdiutil plus newfs_exfat -b 65536.
  • Windows uses OSFMount plus format.com /FS:exFAT /A:64K.
  • Set SM_EXFAT_BACKEND=linux-kernel|linux-fuse|macos-hdiutil|windows-osfmount or use --exfat-backend.

PFS/PFSC:

  • Delegates to MkPFS.
  • Requires a current MkPFS whose pack file -h and pack folder -h expose --skip-executable-compression, --max-compressed-ratio, --min-compress-size, and --temp-folder.
  • Detects newer MkPFS --no-spool and --no-adjust-output-file-extension support. Single-file PFSC wrapping uses no-spool mode when available to reduce peak temporary disk usage for very large .ffpkg or .exfat inputs.
  • Uses --compress --skip-executable-compression by default.
  • Uses SM_PFS_COMPRESSION_LEVEL=9, SM_PFS_MAX_COMPRESSED_RATIO=95, SM_PFS_MIN_COMPRESS_SIZE=65536, SM_PFS_BLOCK_SIZE=auto, SM_PFS_VERSION=PS5, and SM_PFS_INODE_BITS=32 by default.
  • Single-file PFSC wraps over 8 GiB default to MkPFS --cpu-count 6 unless --jobs / SM_PFS_CPU_COUNT is set. This avoids the current MkPFS block-parallel path being killed by memory pressure on huge .ffpkg or .exfat inputs. Tune with SM_PFS_SINGLE_FILE_SAFE_CPU_COUNT and SM_PFS_SINGLE_FILE_SAFE_CPU_THRESHOLD_GIB if you want a different default.
  • When SM_MKPFS_TEMP_DIR / --temp-dir is not set, each output gets its own .ps5-mountaneer-mkpfs-tmp.<output-name> temp directory and ps5-mountaneer removes it after the MkPFS child exits. Explicit temp directories are left alone unless you delete them yourself.
  • plan --json applies the same --jobs, --temp-dir, and --verify overrides as create, so the reported MkPFS profile and temp directory match the eventual packaging run.
  • Generated PFSC outputs use .ffpkg.ffpfsc or .exfat.ffpfsc to make the nested base format visible. Plain .ffpfsc output paths remain accepted for manual create/wrap commands.
  • create infers .ffpkg, .exfat, .ffpfs, .ffpkg.ffpfsc, .exfat.ffpfsc, and plain .ffpfsc output paths when --format is omitted. Explicit --format values are still accepted, but contradictory suffixes are rejected before any image work starts.
  • MkPFS post-pack verification is disabled by default because the current MkPFS verifier can materialize each decoded payload in memory. Large PFSC wrappers around .ffpkg files can therefore be killed after the image has already been written. Set SM_MKPFS_VERIFY=1 to opt into that upstream verifier.

AMPR index:

  • --ampr-index, SM_AMPR_INDEX=1, or [ampr] index=1 generates ampr_emu.index from the game root before packaging. The source file is restored afterward, so a previously absent index is removed and an existing one is put back.
  • SM_AMPR_INDEX=auto is the default. Auto mode enables the index only when the source already contains a strong AMPR signal such as fakelib/libSceAmpr.sprx, or when packaging-time injection uses --fakelib-preset ampr|all. PlayGo and DLC helpers alone do not trigger AMPR index generation.
  • --no-ampr-index, SM_AMPR_INDEX=0, or [ampr] index=0 disables index generation even if AMPR helpers are detected.
  • The generated index is included at image root, which AMPR treats as /app0/ampr_emu.index. Use it when creating AMPR-targeted .ffpkg, .exfat, or .ffpfsc images from a game root. wrap cannot add an index to an already-built base image.
  • ampr-index ftp://host/path/to/app0 --output ./ampr_emu.index --upload can build the same index from a console FTP view and upload it back to the FTP root. Omit --upload to generate a local file only.
  • Paths are matched case-insensitively. By default, files that differ only by case fail index generation; use --ampr-allow-case-collisions or SM_AMPR_ALLOW_CASE_COLLISIONS=1 to keep the first sorted entry.

Fakelib helpers:

  • --fakelib-preset none|ampr|playgo|dlc|all injects vendored helper SPRX files into fakelib/ while packaging. The default is none.
  • --fakelib-variant release|debug selects no-log/release payloads by default, or debug/log payloads when requested.
  • Packaging-time injection builds a temporary hardlink staging tree. The raw game folder is not modified. If hardlinks are not possible, use --allow-copy-staging or SM_FAKELIB_ALLOW_COPY_STAGING=1.
  • --playgo-dat PATH and SM_FAKELIB_PLAYGO_DAT stage a root-level /app0/playgo_stub.dat. If absent, the current PlayGo stub uses its default 1000 chunks and zero scenarios.
  • --dlc-config PATH and SM_FAKELIB_DLC_CONFIG stage a root-level /app0/dlc_emu.ini. Existing dlc_emu.ini files are preserved unless --force-fakelib is used for packaging-time staging.
  • emulation-info reports detected fakelib roles, hashes matched against vendor/ampr-lib/MANIFEST.json, AMPR index headers, PlayGo support-file status, and DLC mount-point warnings.
  • prepare-fakelib intentionally copies helpers into the raw dump for users who want to manage fakelib/ manually before packaging.
  • fakelib import --role ampr|playgo|dlc-entitlement|dlc-appcontent FILE replaces a vendored helper payload and updates vendor/ampr-lib/MANIFEST.json with the new SHA-256. The manifest keeps the redistribution warning unless you manually verify provenance and rights.
  • fakelib export --fakelib-preset all /path/to/global-fakelib writes helper SPRX files directly into a ShadowMountPlus global fakelib folder. This is the quickest way to test updated helpers without rebuilding existing images.
  • make-playgo-dat <game_root> ./playgo_stub.dat writes a PlayGo stub config. --chunks auto uses streaminginstall.ini when available and falls back to 1000 chunks.
  • dlc-config validate ./dlc_emu.ini --root <game_root> validates DLC emulator sections, content IDs, duplicate labels, and PSAC mount-point folders.
  • The current vendor/ampr-lib/MANIFEST.json records hashes and marks redistribution as unverified. Do not ship those helper blobs in public release bundles until provenance and redistribution rights are confirmed.

Patching existing images:

  • patch-image <image.ffpkg> --output <updated.ffpkg> --fakelib-preset all updates helper files by writing a patched copy. Use --in-place only when you intentionally want the original path atomically replaced after a successful patch.
  • Add --source-root <game_root> --ampr-index when the patch must refresh /app0/ampr_emu.index. The source root is required because the AMPR index must represent the whole final /app0 tree, not just the helper SPRX files.
  • .ffpkg patching uses UFS2Tool stat/add/replace with fsck_ufs -n before and after. .exfat patching mounts a copy read-write, writes only the payload files, unmounts, and runs fsck.exfat -n.
  • .ffpfsc patching is a rewrap workflow: ps5-mountaneer uses --base-image when provided, otherwise unpacks the PFSC, finds exactly one nested .ffpkg or .exfat, patches it, then wraps a new PFSC. Direct nested .ffpfs or pfs_image.dat payloads are rejected for patching; rebuild those from source.

Auto recommendation:

  • Uses UFS2 / .ffpkg as the default compatibility base because it is the ShadowMountPlus recommended default.
  • --profile balanced|compat|smallest|fast controls the auto tradeoff. balanced is the default, compat and fast keep the plain base image unless compression is forced, and smallest accepts any positive PFSC gain.
  • --compression auto|on|off controls PFSC wrapping. auto applies the selected profile, on wraps the base unconditionally, and off keeps the base format.
  • SM_AUTO_BASE_FORMAT=exfat or [auto] base_format=exfat can change the auto/recommendation base when you already know a title needs external-drive style behavior.
  • recommend is a fast estimate and policy report. It does not select PFSC unless --probe-pfsc is provided.
  • recommend --probe-pfsc and create --format auto build a temporary base image, run a MkPFS PFSC dry-run, then choose .ffpkg.ffpfsc or .exfat.ffpfsc only when MkPFS reports at least SM_AUTO_PFSC_MIN_SAVINGS_PERCENT=5 actual gain and at least one compressed file.
  • create <game_root> <extensionless_stem> is equivalent to create --format auto <game_root> <extensionless_stem>.
  • create --format auto <game_root> <final_image_path> treats the final suffix as a constraint: .ffpkg and .exfat produce plain base images, while .ffpkg.ffpfsc, .exfat.ffpfsc, and plain .ffpfsc force PFSC wrapping.
  • If PFSC does not meet the threshold, auto keeps the base as .ffpkg or .exfat.
  • Direct .ffpfs remains explicit/report-only because ShadowMountPlus runtime compatibility is still more experimental than .ffpkg, .exfat, or PFSC wrapping.
  • Set SM_PFSC_KEEP_BASE=1 or [auto] keep_base=1 with auto to keep the base image alongside a selected .ffpkg.ffpfsc or .exfat.ffpfsc.

Progress:

  • --progress auto|always|never controls ps5-mountaneer-managed progress output. auto enables progress when stderr is a terminal.
  • Source scans report file, directory, and byte totals when progress is enabled.
  • The long-running packaging steps render a live bar: UFS2Tool population, exFAT rsync copy, and MkPFS pack/wrap show a percentage/bytes/ETA bar when the tool reports progress, and fall back to a spinner with elapsed time and a final throughput summary when it does not.
  • The setting propagates to the FreeBSD helper, so --progress never disables the pv meter in QEMU/container UFS2 builds.

Logging:

  • Every create and wrap run writes a timestamped .log (mirroring console and sub-tool output) plus a machine-readable .json metrics summary capturing input/output sizes, compression savings, per-step timings, the chosen format/backend, and whether system or vendored helpers were used.
  • Logs default to the platform state directory: ${XDG_STATE_HOME:-~/.local/state}/ps5-mountaneer/logs on Linux, ~/Library/Logs/ps5-mountaneer on macOS, and %LOCALAPPDATA%\ps5-mountaneer\logs on Windows. Override with --log-file <path>, SM_LOG_DIR, or [logging] dir; disable with --no-log, SM_LOG_ENABLE=0, or [logging] enable=0.
  • Manage logs with ./ps5-mountaneer logs path, logs show (add --json for the metrics array), and logs clear --keep N (keep the N newest runs).
  • When invoked through sudo, log files are chowned back to the original user.

Sample integration tests:

  • samples/ is gitignored and must be supplied locally. The current real-sample test expects samples/PPSA17221-app with eboot.bin and sce_sys/param.json.
  • Run the default unit suite with python3 -m unittest discover -s tests; the real-sample tests are skipped unless explicitly enabled.
  • Run the Minecraft packaging matrix with:
sudo -v
SM_SAMPLE_INTEGRATION=1 python3 -m unittest tests.test_sample_packaging
  • The opt-in suite creates .ffpkg, .exfat, .ffpfs, .ffpkg.ffpfsc, and .exfat.ffpfsc outputs under /tmp/ps5-mountaneer-sample-*, verifies each output, and removes them on success. It also creates and patches --fakelib-preset all variants for .ffpkg, .exfat, .ffpkg.ffpfsc, and .exfat.ffpfsc, then checks that the AMPR, PlayGo, and DLC emulator SPRX files exist under fakelib/ inside the generated image. Set SM_SAMPLE_KEEP_OUTPUT=1 to keep the generated images for inspection.
  • exFAT coverage is mandatory when SM_SAMPLE_INTEGRATION=1; on Linux the test requires exFAT tooling plus root or cached sudo credentials.

Compatibility Wrappers

Old command style still works:

./mkufs2_freebsd_docker.sh /path/to/APPXXXX ./PPSA12345.ffpkg
./mkufs2_freebsd_docker.sh --estimate /path/to/APPXXXX ./PPSA12345.ffpkg
./mkufs2_freebsd_docker.sh --verify ./PPSA12345.ffpkg

sudo ./mkexfat_linux.sh /path/to/APPXXXX ./PPSA12345.exfat
./mkexfat_linux.sh --estimate /path/to/APPXXXX ./PPSA12345.exfat
sudo ./mkexfat_linux.sh --verify ./PPSA12345.exfat

Environment

CLI flags override environment variables; environment variables override config.ini; config values override built-in defaults. The default config path is ${XDG_CONFIG_HOME:-~/.config}/ps5-mountaneer/config.ini on Linux and other POSIX hosts, ~/Library/Application Support/ps5-mountaneer/config.ini on macOS, and %APPDATA%\ps5-mountaneer\config.ini on Windows. Set SM_CONFIG or pass --config <path> to use another file.

SM_PROGRESS=never ./ps5-mountaneer create --format ufs2 /path/to/APPXXXX ./PPSA12345.ffpkg
SM_LOG_DIR=/var/log/ps5-mountaneer ./ps5-mountaneer create --format auto /path/to/APPXXXX ./PPSA12345
SM_LOG_ENABLE=0 ./ps5-mountaneer create --format ufs2 /path/to/APPXXXX ./PPSA12345.ffpkg
SM_AUTO_BASE_FORMAT=exfat ./ps5-mountaneer recommend /path/to/APPXXXX
SM_AUTO_PFSC_MIN_SAVINGS_PERCENT=10 ./ps5-mountaneer create --format auto /path/to/APPXXXX ./PPSA12345
FORCE=1 ./ps5-mountaneer create --format ufs2 /path/to/APPXXXX ./PPSA12345.ffpkg
KEEP_PARTIAL_OUTPUT=1 ./ps5-mountaneer create --format ufs2 /path/to/APPXXXX ./PPSA12345.ffpkg
UFS2TOOL_BIN="../UFS2Tool/bin/Debug/net8.0/UFS2Tool" ./ps5-mountaneer create --format ufs2 /path/to/APPXXXX ./PPSA12345.ffpkg
SM_UFS2_BACKEND=qemu ./ps5-mountaneer create --format ufs2 /path/to/APPXXXX ./PPSA12345.ffpkg
FREEBSD_CACHE_DIR_HOST="$PWD/.ufs2-cache/freebsd-mkufs2" ./ps5-mountaneer create --format ufs2 /path/to/APPXXXX ./PPSA12345.ffpkg
SM_UFS2_EXTRA_MB=4096 ./ps5-mountaneer create --format ufs2 /path/to/APPXXXX ./PPSA12345.ffpkg
FREEBSD_MEMORY=8192 FREEBSD_CPUS=4 ./ps5-mountaneer create --format ufs2 /path/to/APPXXXX ./PPSA12345.ffpkg
SM_DOCKER_SELINUX_LABEL=0 ./ps5-mountaneer create --format ufs2 /path/to/APPXXXX ./PPSA12345.ffpkg
SM_EXFAT_BACKEND=linux-fuse ./ps5-mountaneer create --format exfat /path/to/APPXXXX ./PPSA12345.exfat
MKPFS_BIN="../MkPFS/.venv/bin/mkpfs" ./ps5-mountaneer create --format pfs /path/to/APPXXXX ./PPSA12345.ffpfs
SM_MKPFS_VERIFY=1 ./ps5-mountaneer wrap --format pfsc ./PPSA12345.ffpkg ./PPSA12345.ffpkg.ffpfsc
SM_PFS_CPU_COUNT=4 ./ps5-mountaneer wrap --format pfsc ./PPSA12345.exfat ./PPSA12345.exfat.ffpfsc
SM_PFSC_KEEP_BASE=1 ./ps5-mountaneer create --format pfsc /path/to/APPXXXX ./PPSA12345.ffpkg.ffpfsc
SM_AUTO_PFSC_MIN_SAVINGS_PERCENT=1 ./ps5-mountaneer create --format auto /path/to/APPXXXX ./PPSA12345
SM_AMPR_INDEX=auto ./ps5-mountaneer create /path/to/APPXXXX ./PPSA12345.ffpkg
SM_FAKELIB_PRESET=ampr ./ps5-mountaneer create /path/to/APPXXXX ./PPSA12345.ffpkg

Set FORCE=1 to overwrite an existing output file. Set SM_PFSC_KEEP_BASE=1 to keep the intermediate .ffpkg or .exfat file used by create --format pfsc. For very large single-file PFSC wraps, leave the safe default in place for reliability or set --jobs N or SM_PFS_CPU_COUNT=N after confirming your system has enough RAM. Set SM_MKPFS_VERIFY=1 only when you want MkPFS to run its full post-pack verifier; you can also run ./ps5-mountaneer verify later against the completed .ffpfs or .ffpfsc.