-
-
Notifications
You must be signed in to change notification settings - Fork 1
generator guide
Complete guide to using the CyberPatchMaker generator tool for creating delta patches.
The generator tool creates efficient binary patches between software versions. It compares two complete directory trees and generates a small patch file containing only the changes.
The most common use case - generate patches from all existing versions to your new release:
patch-gen --versions-dir ./versions --new-version 1.0.3 --output ./patchesThis will:
- Scan the new version directory (versions/1.0.3)
- Auto-detect the key file (program.exe, game.exe, app.exe, or main.exe)
- Register the new version
- Find all existing versions in the versions directory
- Generate a patch from EACH existing version to 1.0.3
- Save patches as
{from}-to-{to}.patch
Example Output:
Generating patches for new version 1.0.3
Scanning version 1.0.3...
Using key file: program.exe
Version 1.0.3 registered: 156 files, 12 directories
Processing version 1.0.0...
Generating patch from 1.0.0 to 1.0.3...
5 files added
12 files modified
3 files deleted
2 directories added
Patch saved to: patches/1.0.0-to-1.0.3.patch (2.1 MB)
Processing version 1.0.1...
Generating patch from 1.0.1 to 1.0.3...
2 files added
8 files modified
1 file deleted
Patch saved to: patches/1.0.1-to-1.0.3.patch (1.5 MB)
Processing version 1.0.2...
Generating patch from 1.0.2 to 1.0.3...
1 file added
4 files modified
Patch saved to: patches/1.0.2-to-1.0.3.patch (0.8 MB)
Successfully generated 3 patches
To create one patch between two specific versions:
patch-gen --versions-dir ./versions --from 1.0.0 --to 1.0.3 --output ./patchesThis registers both versions automatically during the generation process.
--versions-dir <path>
- Directory containing version folders
- Each subfolder should be a version (e.g., 1.0.0/, 1.0.1/, 1.0.2/)
- Required when using
--new-version
--new-version <version>
- Version number of the new release
- Must match a folder name in
--versions-dir - Example:
1.0.3 - Required when using
--versions-dir
--output <path>
- Directory where patch files will be saved
- Directory is created if it doesn't exist
- Patches named automatically:
{from}-to-{to}.patch
--versions-dir <path>
- Directory containing version folders
- Required to locate source and target version directories
- Example:
./versions
--from <version>
- Source version number
- Must match a folder name in
--versions-dir - Example:
1.0.0
--to <version>
- Target version number
- Must match a folder name in
--versions-dir - Example:
1.0.3
--output <path>
- Full path to the output directory for patch files
- Directory is created if it doesn't exist
- Patches named automatically:
{from}-to-{to}.patch
--compression <type>
- Compression algorithm to use
- Options:
zstd(default),gzip,none - zstd provides best compression ratio and speed
- gzip is more universally compatible
- none is fastest but largest patches
--key-file <filename>
- Specify a custom key file to use for version identification
- Overrides auto-detection of key file (program.exe, game.exe, app.exe, main.exe)
- Example:
--key-file my_app.exeor--key-file custom_executable.exe - Useful when the main executable has a non-standard name
- Default: Auto-detects from standard key file names
--level <1-4>
- Compression level (applies to zstd and gzip)
- zstd: Levels 1-4 (1 = fastest/largest, 4 = slowest/smallest)
- gzip: Levels 1-3 (1 = fastest/largest, 3 = slowest/smallest)
- Default: 3 (balanced, recommended)
- Higher levels take longer but save bandwidth
--verify
- Verify patches after creation
- Re-loads and validates patch metadata
- Recommended for production patches
- Adds time to generation process
- Note: Verification is always enabled during patch generation regardless of this flag
--create-exe
- Create self-contained CLI executable
- Embeds patch data into a standalone
.exefile - Creates both
.patchfile and.exefile - Uses CLI applier (console interface)
- See Self-Contained Executables Guide for details
- Works with all generation modes (single, batch, custom paths)
--silent
- Embed silent mode flag into generated self-contained executables
- Only works with
--create-exeflag (no effect without it) - When embedded, executable automatically applies patch without user prompts
- Overrides interactive console menu - patch applies immediately on launch
- Creates log file
log_<epochtime>.txtwith execution details - Perfect for distributing automated patches to end users
- Example:
patch-gen --create-exe --silent --from-dir v1 --to-dir v2 --output patches - Users run:
1.0.0-to-1.0.1.exe(no flags needed, applies automatically) - See Self-Contained Executables Guide for details
--crp (Create Reverse Patch)
- Automatically create reverse patch for downgrades
- Generates both forward patch (A→B) and reverse patch (B→A)
- Enables easy version rollback without manual patch creation
- Works with
--create-exeto generate reverse executables too - Example: Generates
1.0.0-to-1.0.1.patchAND1.0.1-to-1.0.0.patch - Compatible with all generation modes (single, batch, custom paths)
- See Downgrade Guide for usage details
--savescans (Enable Scan Caching)
- Save directory scan results to cache for faster subsequent patch generation
- Cache stored in
.data/directory (or custom location with--scandata) - First generation: Scans and caches (normal speed)
- Subsequent generations: Loads from cache (instant, no rescanning)
- Performance: Small projects (5-10ms saved), Large projects (15+ minutes → <1 second)
- Example: War Thunder (34,650 files) - 15 minute scan → instant cache load
- Cache validates key file hash to prevent using stale data
- Works with all generation modes (batch, single, custom paths)
--scandata <directory>
- Specify custom directory for scan cache storage
- Default:
.data(in current working directory) - Useful for shared cache locations or specific storage needs
- Only meaningful when used with
--savescans - Cache files named:
scan_<version>_<hash>.json
--rescan
- Force fresh directory scan, ignoring cached data
- Updates cache with latest file data
- Useful when files changed but need to rebuild cache
- Only meaningful when used with
--savescans - Ensures cache is up-to-date after file modifications
--jobs <n> (Parallel Processing)
- Number of parallel workers to use for file hashing and processing
-
0= Auto-detect CPU cores (default, recommended) -
1= Single-threaded (useful for debugging) -
2+= Specific number of workers - Performance: Significantly faster on multi-core systems (especially for large projects)
- Example: 4-core system can process 4 files simultaneously
- Scales based on available CPU cores and I/O bandwidth
- Works with all generation modes and compression options
--splitsize <size> (Multi-Part Split Size)
- Custom size for splitting large patches into multiple parts
- Format: Number followed by unit (M/MB for megabytes, G/GB for gigabytes)
- Examples:
2G,2GB,500M,500MB - Default:
4GB(4 gigabytes) - Minimum recommended:
100MB(requires confirmation if below) - Use cases:
- Hosting platforms with file size limits
- Email attachments or transfer services with restrictions
- Memory-constrained systems during patch application
- See Multi-Part Patches Guide for details
--bypasssplitlimit
- Bypass the 100MB minimum split size confirmation prompt
- Only meaningful when used with
--splitsizebelow 100MB - Without this flag: Generator prompts for confirmation if split size < 100MB
- With this flag: Generator proceeds without asking
- Warning: Very small split sizes create many parts (not recommended)
- Use case: Automated scripts where confirmation prompts would block execution
--version
- Display version information for the generator tool
- Prints version string and exits
- Example:
patch-gen --version
--help
- Display usage information
- Shows all available options
--from-dir <path>
- Full path to source version directory
- Overrides
--versions-dirand--from - Use when source version is not in versions directory
- Example:
D:\builds\old-version - Takes priority over
--versions-dir/--from/--to(provides custom source path directly)
--to-dir <path>
- Full path to target version directory
- Overrides
--versions-dirand--to - Use when target version is not in versions directory
- Example:
C:\projects\new-release - Takes priority over
--versions-dir/--from/--to(provides custom target path directly)
Custom Path Example:
# Generate patch from arbitrary locations
patch-gen --from-dir D:\old\1.0.0 --to-dir C:\new\1.0.3 --output ./patchesWhen to Use Custom Paths:
- Versions stored on different drives
- Network shares or external storage
- Build output directories
- Testing without copying files
Your versions directory should look like this:
versions/
├── 1.0.0/ # Version folder
│ ├── program.exe # Key file (main executable)
│ ├── data/
│ │ ├── config.json
│ │ └── assets/
│ │ └── textures/
│ └── libs/
│ └── core.dll
├── 1.0.1/ # Another version
│ ├── program.exe
│ ├── data/
│ └── libs/
└── 1.0.2/ # Yet another version
├── program.exe
├── data/
└── libs/
Key Points:
- Each version must have its own folder
- Folder name should be the version number
- Each version must contain a key file (program.exe, game.exe, app.exe, or main.exe)
- Complete directory tree is scanned and hashed
The generator automatically detects your key file by looking for:
-
program.exe(most common) -
game.exe(for games) -
app.exe(for applications) -
main.exe(alternative)
Priority: Checked in the order above, first one found is used.
Key File Purpose:
- Uniquely identifies the version
- Prevents applying patches to wrong versions
- Verified before patch application
If none of these files exist, generation will fail with an error.
Pros:
- Best compression ratio (smallest patches)
- Very fast compression and decompression
- Modern algorithm optimized for binary data
- Industry standard (used by Facebook, kernel.org)
Cons:
- Requires zstd library (included)
Use When:
- Default choice for production
- Bandwidth is a concern
- Fast patching is important
Example: 5MB of changes → 1.2MB patch file
Pros:
- Universally compatible
- Widely supported
- Decent compression ratio
Cons:
- Slower than zstd
- Larger patches than zstd
- Older algorithm
Use When:
- Compatibility is critical
- Target systems may not have modern libraries
Example: 5MB of changes → 1.8MB patch file
Pros:
- Fastest generation
- No compression overhead
- Useful for testing
Cons:
- Largest patch files
- Wastes bandwidth
- Not recommended for production
Use When:
- Local testing only
- Network speed not a concern
- Debugging patch generation
Example: 5MB of changes → 5MB patch file
You have versions 1.0.0, 1.0.1, 1.0.2 and just built 1.0.3:
# Copy new version to versions directory
mkdir versions\1.0.3
xcopy /E C:\builds\v1.0.3\* versions\1.0.3\
# Generate all patches
patch-gen --versions-dir ./versions --new-version 1.0.3 --output ./patches --verifyResult:
-
patches/1.0.0-to-1.0.3.patch(users on 1.0.0) -
patches/1.0.1-to-1.0.3.patch(users on 1.0.1) -
patches/1.0.2-to-1.0.3.patch(users on 1.0.2)
Upload these patches to your update server.
Generate a specific patch with gzip compression:
patch-gen --versions-dir ./versions --from 1.0.0 --to 1.0.2 --output ./patches --compression gzip --verifyGenerate patches with maximum compression for slow internet users:
patch-gen --versions-dir ./versions --new-version 1.0.3 --output ./patches --compression zstd --level 4Note: Level 4 takes longer but creates smallest patches.
Generate downgrade patch to roll back from 1.0.3 to 1.0.2:
patch-gen --from 1.0.3 --to 1.0.2 --versions-dir ./versions --output ./patches/downgrade --verifyGenerate all downgrade paths from current version:
# From 1.0.3 to each previous version
patch-gen --from 1.0.3 --to 1.0.2 --versions-dir ./versions --output ./patches/downgrade
patch-gen --from 1.0.3 --to 1.0.1 --versions-dir ./versions --output ./patches/downgrade
patch-gen --from 1.0.3 --to 1.0.0 --versions-dir ./versions --output ./patches/downgradeResult:
patches/downgrade/
├── 1.0.3-to-1.0.2.patch
├── 1.0.3-to-1.0.1.patch
└── 1.0.3-to-1.0.0.patch
Key Points:
- Downgrade patches work exactly like upgrade patches
- Simply swap the
--fromand--toparameters - The generator creates a patch that reverses all changes
- Users can safely rollback to previous versions
- See Downgrade Guide for complete documentation
Generate patches quickly without compression for local testing:
patch-gen --versions-dir ./versions --new-version 1.0.3 --output ./patches --compression noneCreate standalone executables with embedded patches for easy distribution:
# Single patch with self-contained executable
patch-gen --from-dir "C:\releases\1.0.0" --to-dir "C:\releases\1.0.1" --output ./patches --create-exe
# Batch mode with executables for all versions
patch-gen --versions-dir ./versions --new-version 1.0.3 --output ./patches --create-exe --verifyResult:
patches/
├── 1.0.0-to-1.0.3.patch ← Standard patch file
├── 1.0.0-to-1.0.3.exe ← Self-contained CLI executable
├── 1.0.1-to-1.0.3.patch
├── 1.0.1-to-1.0.3.exe ← Self-contained CLI executable
├── 1.0.2-to-1.0.3.patch
└── 1.0.2-to-1.0.3.exe ← Self-contained CLI executable
User Experience:
- Users download the
.exematching their version - Double-click to run - shows interactive console menu
- Choose "Dry Run" to simulate, or "Apply Patch" to update
- Can toggle 1GB bypass mode if needed
- No need to download separate patch files or tools
See Self-Contained Executables Guide for complete documentation.
Automatically generate reverse patches to enable version rollback:
# Single patch with reverse patch
patch-gen --from-dir "C:\releases\1.0.0" --to-dir "C:\releases\1.0.1" --output ./patches --crp --create-exe
# Batch mode with reverse patches for all versions
patch-gen --versions-dir ./versions --new-version 1.0.3 --output ./patches --crp --create-exeResult:
patches/
├── 1.0.0-to-1.0.1.patch ← Forward patch (upgrade)
├── 1.0.0-to-1.0.1.exe ← Forward executable
├── 1.0.1-to-1.0.0.patch ← Reverse patch (downgrade)
├── 1.0.1-to-1.0.0.exe ← Reverse executable
├── 1.0.2-to-1.0.3.patch
├── 1.0.2-to-1.0.3.exe
├── 1.0.3-to-1.0.2.patch ← Reverse patch
└── 1.0.3-to-1.0.2.exe ← Reverse executable
Benefits:
- Users can easily rollback if issues occur
- No need to manually create downgrade patches
- Both upgrade and downgrade executables ready to distribute
- Automatic version safety net for production deployments
See Downgrade Guide for complete documentation.
Available since v1.0.9: The SimpleMode field in the Patch struct and runSimpleMode() function exist in the codebase. When enabled, Simple Mode provides a fully automated patching experience (automatic dry-run validation followed by patch application with no user interaction).
Current status: No generator code path currently sets SimpleMode = true. The field exists in the patch structure and the applier respects it, but it is reserved for future use. Silent Mode (--silent flag) is the currently available automation option for self-contained executables.
Note: Simple Mode is different from the --silent flag (Simple Mode = automated two-step flow with verbose output; Silent Mode = minimal-output automation for scripting).
Available since v1.0.11: Create self-contained executables that automatically apply patches without user interaction.
The --silent flag embeds silent mode into generated executables, making them perfect for automated deployments where you want users to simply run the file and have it patch automatically.
Create Silent Mode Executable:
# Single patch with embedded silent mode
patch-gen --from-dir "C:\releases\1.0.0" --to-dir "C:\releases\1.0.1" --output ./patches --create-exe --silent
# Batch mode with silent executables for all versions
patch-gen --versions-dir ./versions --new-version 1.0.3 --output ./patches --create-exe --silent --verifyResult:
patches/
├── 1.0.0-to-1.0.3.patch ← Standard patch file
├── 1.0.0-to-1.0.3.exe ← Silent mode embedded executable
├── 1.0.1-to-1.0.3.patch
├── 1.0.1-to-1.0.3.exe ← Silent mode embedded executable
├── 1.0.2-to-1.0.3.patch
└── 1.0.2-to-1.0.3.exe ← Silent mode embedded executable
User Experience:
- User downloads
1.0.0-to-1.0.3.exe - User double-clicks the executable
- Patch applies automatically (no prompts, no menus)
- Creates log file
log_<epochtime>.txtwith complete execution details - Returns exit code 0 on success, 1 on failure
Difference from Applier --silent Flag:
-
Generator --silent: Embeds silent mode INTO the executable itself
- User runs:
1.0.0-to-1.0.1.exe(applies automatically) - No command-line flags needed by end user
- Silent behavior is built into the file
- User runs:
-
Applier --silent: Command-line flag for interactive executables
- User runs:
1.0.0-to-1.0.1.exe --silent(requires flag) - Works with any self-contained executable
- Silent behavior activated by user
- User runs:
Combined with --crp for Bidirectional Silent Patches:
# Create both upgrade and downgrade silent executables
patch-gen --from-dir "C:\releases\1.0.0" --to-dir "C:\releases\1.0.1" --output ./patches --create-exe --silent --crpResult:
patches/
├── 1.0.0-to-1.0.1.patch ← Forward patch
├── 1.0.0-to-1.0.1.exe ← Forward silent executable (auto-upgrade)
├── 1.0.1-to-1.0.0.patch ← Reverse patch
└── 1.0.1-to-1.0.0.exe ← Reverse silent executable (auto-downgrade)
When to Use Embedded Silent Mode:
- Distributing to end users for one-click automated updates
- Enterprise deployments with minimal user interaction
- Kiosk or unattended systems that need automatic patching
- Game patches where users just want updates to "work"
- Any scenario where you want simplest possible user experience
When NOT to Use Embedded Silent Mode:
- Users need to review patch details before applying
- Testing environments where control is needed
- Situations where backup/dry-run decisions should be user-controlled
- When users need to specify custom target directories
Log File Details: When a silent mode executable runs, it creates a timestamped log file:
- Filename:
log_<unix_timestamp>.txt - Location: Same directory as executable
- Contents: Patch info, target directory, success/failure status, error messages
- Enables audit trails for automated deployments
Security Note: Silent mode executables apply patches immediately without confirmation. Ensure:
- Patches are from trusted sources
- Users understand what the executable does
- Files are distributed through secure channels
- Digital signatures verify authenticity
See Self-Contained Executables Guide for complete documentation on silent mode behavior and log file formats.
-
Amount of Changes
- More changed files = larger patch
- Larger changed files = larger patch
-
Type of Changes
- Text files compress very well
- Binary files (images, videos) compress poorly
- Executables vary based on changes
-
Compression Settings
- zstd level 4: smallest, slowest
- zstd level 1: larger, fastest
- gzip: medium size, medium speed
- none: no reduction
For a 5GB application:
- Few bug fixes (10MB changed): ~2-5MB patch
- Feature update (50MB changed): ~10-20MB patch
- Major overhaul (500MB changed): ~100-200MB patch
- Use Default Settings: zstd level 3 is well-optimized
- Sufficient RAM: Generation uses ~500MB max
- Fast Storage: SSD recommended for large version folders
Enable scan caching for massive time savings on projects with many files:
# First generation: Enable caching (scans and saves to cache)
patch-gen --versions-dir ./versions \
--new-version 1.0.3 \
--output ./patches \
--savescans
# Subsequent generations: Load from cache (instant)
patch-gen --versions-dir ./versions \
--new-version 1.0.4 \
--output ./patches \
--savescansPerformance Benefits:
- Small projects (< 1,000 files): 5-10ms saved (minimal benefit)
- Medium projects (1,000-10,000 files): 1-5 seconds saved
- Large projects (10,000+ files): 15+ minutes → <1 second (massive improvement)
- Example: War Thunder (34,650 files) - 15 minute scan → instant cache load
How it Works:
- Cache stored in
.data/directory as JSON files - Cache file format:
scan_<version>_<hash>.json - Validates key file hash before using cache (prevents stale data)
- Works with all generation modes (batch, single, custom paths)
Custom Cache Location:
# Shared cache for multiple developers
patch-gen --versions-dir ./versions \
--new-version 1.0.3 \
--output ./patches \
--savescans \
--scandata /shared/cacheForce Rescan (Update Cache):
# Files changed, need to update cache
patch-gen --versions-dir ./versions \
--new-version 1.0.3 \
--output ./patches \
--savescans \
--rescanIf you have 10+ versions:
- Generation scales linearly
- Each patch is independent
- No extra memory usage
- Time = (number of versions) × (time per patch)
- Use scan cache to speed up each patch dramatically
Problem: None of the expected key files exist
Solution:
- Ensure your version has: program.exe, game.exe, app.exe, or main.exe
- If using different name, rename it to one of the above
- File must be in root of version directory
Problem: Specified version doesn't exist
Solution:
- Check folder name matches version number exactly
- Verify
--versions-dirpath is correct - Use absolute paths if having issues
Problem: Cannot scan version directory
Solution:
- Check directory is readable
- Verify no permission issues
- Ensure directory is not empty
- Check disk is not full
Problem: Patch file is bigger than anticipated
Solution:
- Check what files actually changed (use file comparison tool)
- Binary files (images, videos) don't compress well
- Consider what changed - large files = large patches
- Verify compression is enabled (not
--compression none)
- Keep All Versions: Never delete old version folders
- Consistent Structure: Use same directory layout across versions
- Clean Builds: Generate from clean, tested builds
- Version Numbers: Use semantic versioning (major.minor.patch)
-
Always Verify: Use
--verifyflag for production patches - Default Compression: Stick with zstd unless you have a reason not to
- Test First: Generate and test patches before distributing
- Document Changes: Keep changelog for each version
- Multiple Paths: Generate patches from all recent versions
- Legacy Support: Keep patches for last 3-4 versions
- Server Storage: Upload patches to reliable servers
- Checksums: Provide SHA-256 checksums for patch files
- Applier Tool Guide - Applying patches
- How It Works - Understanding the patch system
- Compression Guide - Detailed compression info
- Version Management - Managing versions
- Backup System - Understanding backup behavior during patching