🎉 MkPFS 0.0.9 is released!
🤖 What's Changed
- Add full exFAT support: pure-Python exFAT writer/reader and a new pack exfat command (create raw .exfat images).
- Default pack folder now produces an exFAT-wrapped .ffpfsc (more compatible); keep --raw to opt out and pack PFS directly.
- Unpack/verify/tree now understand wrapped exFAT images:
- tree --deep lists files inside a wrapped exFAT
- unpack --deep --only lets you cherry-pick files/folders from a wrapped exFAT
- verify can compare/inspect exFAT images
- Performance improvements: multicore compression for the fused exFAT path and faster unpacking (zlib-ng backend).
- Stability and memory safety: bound in-flight blocks in the multi-worker PFSC encoder to cap memory usage.
- Sanity fixes: exclude OS-generated metadata from source/image verification comparisons.
- Quality-of-life: option to hide progress bars on some commands, various docs/README updates and dependency upgrades.
🚀 Quick Start
# Install/Update using pip
python -m pip install -U "mkpfs"
# Creating Images: Option 1: .exfat -> .ffpfsc (Works with ShadowMountPlus) (Maximum compatibility)
python -m mkpfs pack file './BREW1234.exfat' './BREW1234.ffpfsc'
# Creating Images: Option 2: .ffpkg -> .ffpfsc (Works with ShadowMountPlus)
python -m mkpfs pack file './BREW1234.ffpkg' './BREW1234.ffpfsc'
# Creating Images: Option 3: Game folder -> .ffpfsc in one pass (default: exFAT-wrapped, no temp file)
python -m mkpfs pack folder './BREW1234-app' './BREW1234.ffpfsc'
# Creating Images: Option 4: Game folder packed directly as PFS (advanced single-pass)
python -m mkpfs pack folder --raw './BREW1234-app/' './BREW1234.ffpfs'
# Creating Images: Option 5: Game folder wrapped twice into PFS (advanced two-pass)
python -m mkpfs pack folder --raw --no-compress --no-adjust-output-file-extension './BREW1234-app' './pfs_image.dat'
python -m mkpfs pack file './pfs_image.dat' './BREW1234.ffpfsc'
rm './pfs_image.dat'
# Extracting Existing Images (Reverse operation; --deep lists/extracts inside a wrapped exFAT)
python -m mkpfs unpack --deep './BREW1234.ffpfsc' './BREW1234-extracted/'⚠️ Limitations and Known Issues
exfat->ffpfscis the most stable format for compressed game backups.pack folderproduces this layout by
default: it wraps the folder in an exFAT image and compresses that into the.ffpfscin a single pass, with no
temporary.exfaton disk.pack folder --rawpacks the folder directly into a PFS image without the exFAT wrapper. When file compression is
enabled, the image is created and verification passes, but the console reads the files incorrectly due to technical
limitations, so this advanced option provides no practical benefit for game backups. Prefer the default wrapped
layout.- With the default
--block-size 65536, very small files can cause significant block-alignment waste, which may make
the resulting image larger than the source in corner cases.- For small-file-heavy folders, prefer the two-pass strategy (
raw-folder -> .dat -> .ffpfsc) or try a smaller
block size such as--block-size 16384or--block-size 32768.
- For small-file-heavy folders, prefer the two-pass strategy (
- Antivirus scanning can reduce conversion speed, especially during the write phase or when processing many loose
files. If you trust this software in your environment and need higher throughput, temporarily disabling real-time
scanning can help. If you are unsure, keep antivirus enabled and expect slower conversions.
💖 Sponsorship
MkPFS is easier to sustain when users who benefit from it help fund it.
☕ Contributions
Other changes
- Add an option to hide progress bar in some commands (#70) @RenanGBarreto
- Add support to unpack, verify, and list files from exfat images (#68) @RenanGBarreto
- Platform-independent exFAT: pure-Python writer/reader, one-pass pack folder, deep read (#65) @rdmrocha
- AMPR emulation automated index and OS-metadata exclusion for folder packing (#63) @rdmrocha
- Faster unpack compression backend (#62) @rdmrocha
- Fix pack file command defaults and documentation (#59) @RenanGBarreto
- Improved logging (#58) @RenanGBarreto
Full Changelog: 0.0.8...0.0.9