A collection of Python scripts and tools for creating texture mods and TPF files for DirectX 9 games using OpenTexMod.
TexModTools provides a complete workflow for processing and packaging game textures into TPF files. The tools are based on the usage of OpenTexMod, allowing you to create texture replacement mods for classic DirectX 9 games. This script is faster than the original TexMod and creates files that should be compatible with both TexMod and OpenTexMod.
I found OpenTexMod to be the most reliable in injecting tpf's into games. As it lacks tooling for creating tpf's, made sure to include that functionality in here. We also include OpenTexMod files, because no reliable maintained download source was found. Our license does not apply to the OpenTexMod files.
- TexModTools
- First published 2022 - Copyright, Jakob Wapenhensch
- Check LICENSE.md for full license text
- https://creativecommons.org/licenses/by-nc/4.0/
- https://creativecommons.org/licenses/by-nc/4.0/legalcode
- OpenTexMod - Modern OpenTexMod beta_v1_r21, hosted here because no maintained download source was found
- Python Scripts - Automated tools for texture processing and TPF creation
Install the required Python packages using pip:
pip install Pillow numpy zipencrypt coloramaOr install from requirements.txt:
pip install -r requirements.txtPackage Details:
Pillow- Image processing for alpha channel detectionnumpy- Numerical operations for alpha variance calculationzipencrypt- ZipCrypto encryption library (fallback for TPF format encryption)numba- Recommended - High-performance JIT compiler for optimized ZipCrypto encryption and custom ZIP file operations (significantly faster than native Python implementations)colorama- Colored terminal output (optional, falls back gracefully if not installed)
Zip Encryption Performance:
- With numba: The script uses a Numba-optimized ZipCrypto implementation for significantly faster TPF file creation
- Without numba: The script automatically falls back to
zipencryptlibrary (works correctly but slower) - The script will display a warning if numba is not installed, but execution continues normally with the fallback
- Recommendation: Install numba for better performance:
pip install numba
Note: For the optional DDS compression feature in TexturesToTpf.py, ImageMagick must be installed separately on your system (download from ImageMagick's official website) and the magick command must be in your system PATH.
TexModTools uses a config.ini file for customizable settings. The config file is automatically created with default values if it doesn't exist.
Place config.ini in the same directory as TexturesToTpf.py to customize behavior.
input_formats- Comma-separated list of supported image formats (default: png,jpg,jpeg,bmp)
generate_mipmaps- Generate mipmaps for DDS textures (default: True)channel_variance_threshold- Threshold for detecting color channel variance (default: 0.001)normal_variance_threshold- Threshold for detecting normal map variance (default: 0.01)enable_compression- Enable automatic DDS compression (default: True)
[FileFormats]
input_formats = png,jpg,jpeg,bmp
[DDS]
generate_mipmaps = True
channel_variance_threshold = 0.001
normal_variance_threshold = 0.01
enable_compression = TrueNote: When enable_compression = True, the script will automatically compress PNG textures to DDS format during TPF creation. Set to False to skip compression and use PNG files directly.
Converts .dds texture files extracted from games to .png format while preserving the alpha channel.
Usage:
- Place
1toPng.pyin a folder containing.ddsfiles - Run:
python 1toPng.py - The script converts all
.ddsfiles to.pngand removes the original.ddsfiles
Features:
- Preserves alpha channel (BGRA → RGBA conversion)
- Batch processes all DDS files in the directory
- Automatically removes source files after conversion
Separates alpha channels from PNG textures, creating separate alpha mask files when needed.
Usage:
- Place
splitAlpha.pyin a folder containing.pngfiles with alpha channels - Run:
python splitAlpha.py - For textures with non-constant alpha:
- RGB version overwrites the original file
- Alpha channel saved as
*_a.png(grayscale)
Features:
- Detects constant alpha channels (discards if uniform)
- Creates separate alpha mask files (
*_a.png) for textures with varying transparency - Preserves RGB data while separating alpha for editing workflows
Automatically scans a directory for texture files matchiingg the filename pattern, extracts hexadecimal IDs from filenames, and creates a TPF (TexMod Package File) format archive.
Filename Pattern:
Textures must follow the pattern: *_0X[hexadecimal].ext or *_0x[hexadecimal].ext where ext is png, jpg, jpeg, or bmp
Usage:
- Place
TexturesToTpf.pyin a folder containing texture files following the filename pattern - Run:
python TexturesToTpf.pyor double-clickRun_TexturesToTpf.bat - The script will:
- Auto-detect the texture directory (or prompt for selection)
- Scan for valid texture files matching the ID pattern
- Validate all files exist
- Generate
texmod.defdefinition file - Create encrypted ZIP archive with ZipCrypto
- Apply XOR obfuscation
- Output a
.tpffile ready for use
Examples:
ACBSP_T_0X3263C677.png✓texture_0xABC123.png✓file_0X12345678.png✓
Features:
- Auto-detection of texture directories
- Optional DDS compression: Converts PNG to DXT1 (no alpha) or DXT5 (with alpha variance) format using ImageMagick; generates mipmaps by default for better performance
- Alpha channel detection: Uses variance threshold to decide compression type (avoids DXT5 for uniform alpha to save space)
- Progress indicators for large texture sets (>10 files)
- Validation of texture files before packaging
- Duplicate ID detection and warnings
- Full TPF format compliance (high-performance NumPy vectorized XOR obfuscation + Numba-optimized ZipCrypto encryption)
- Detailed build summary with file size comparisons (PNG vs. DDS vs. TPF)
- Automatic cleanup of temporary DDS files
- Compression cache: Stores converted DDS textures in a
compressed/subdirectory withcache.jsonto track file hashes and avoid recompressing unchanged textures - Fallback to original PNG if compression fails
Use OpenTexMod to extract .dds texture files from your game:
- Launch
OpenTexMod.exe - Select Main -> Use Global hook
- Start your game
- Use the hotkeys from OpenTexMod to dump textures
- Textures are saved as
.ddsfiles with filenames ending in_0X[hexadecimal](the texture ID that must be preserved)
- Place
1toPng.pyin the folder with extracted.ddsfiles - Run:
python 1toPng.py - All
.ddsfiles are converted to.pngformat
Edit your textures using Photoshop, GIMP, or any image editor. Important: Keep the _0X[hex].ext suffix intact from the underscore to the end of the filename!
If you need to edit alpha channels separately:
- Place
splitAlpha.pyin your texture folder - Run:
python splitAlpha.py - Alpha masks are saved as
*_a.pngfiles
- Ensure all textures follow the
*_0X[hex].extnaming pattern - Configure compression settings in
config.ini(optional - defaults to enabled) - Place
TexturesToTpf.pyin the texture folder (or run from anywhere) - Run:
python TexturesToTpf.pyor double-clickRun_TexturesToTpf.bat - The script creates a
.tpffile ready for use (automatically compresses to DDS if enabled in config)
- Launch OpenTexMod.exe
- Select Main -> Use Global hook
- Start your game
- Select Open texture/package and select your
.tpffile - Select Main -> Set as Template
- Press Main -> Update (Reload)
From now on for every game start:
- Start openTexMod
- Start your game That's it!
The TPF (TexMod Package File) format is a specialized archive format:
- Outer Layer: XOR obfuscation with key
0x3FA43FA4 - Container: Standard ZIP archive
- Encryption: Legacy ZipCrypto with hardcoded password
- Contents:
texmod.defdefinition file + texture images
The TexturesToTpf.py script handles all format requirements automatically, ensuring compatibility with both TexMod and OpenTexMod. The ZipCrypto encryption uses a Numba-optimized implementation when available (recommended for performance), or automatically falls back to the zipencrypt library if numba is not installed.
Texture IDs are extracted from filenames using the pattern _0X[hex] or _0x[hex] at the end of the filename (before the extension). These IDs correspond to CRC32 hashes computed by TexMod/OpenTexMod during texture extraction.
If TexturesToTpf.py fails during DDS compression with 'magick' errors:
- Ensure ImageMagick is installed and in your system PATH
- Verify installation:
magick -version - If compression fails for specific files, the script falls back to using the original PNG (check the console output for warnings)
- Command not found: Install ImageMagick if prompted during compression.
- Conversion failures: Some PNGs may not convert due to format issues; the script skips them and uses PNG fallback. Review the build summary for failed counts.
- Verify compression: Check the final summary for DXT1/DXT5 counts and size reductions. Test the TPF in OpenTexMod to ensure textures load correctly.
Note: The TexturesToTpf.py script includes comprehensive validation and will automatically detect most issues. However, these troubleshooting steps address edge cases like file permission problems or external factors that the script cannot control.
- XOR Performance Optimization: Implemented custom high-performance XOR obfuscation for significantly faster TPF file creation
- Performance Enhancement: Added Numba-optimized ZipCrypto implementation for significantly faster TPF file creation
- Automatic Fallback: Script automatically uses
zipencryptlibrary if numba is not installed (works correctly but slower) - User-Friendly Warnings: Script displays helpful warnings and installation advice when numba is missing, without halting execution
- Both implementations provide reliable TPF format compliance with OpenTexMod
- Enhanced
TexturesToTpf.pywith optional DDS compression for smaller TPF files - Added intelligent alpha channel variance detection (DXT1 for uniform/no alpha, DXT5 for varying alpha)
- Automatic mipmap generation for improved texture performance
- Improved compression statistics and file size reporting (PNG vs compressed vs TPF)
- Fixed size calculation bug when compression fails (now includes fallback PNGs in totals)
- Added
1toPng.py- Improved DDS to PNG conversion - Added
splitAlpha.py- Alpha channel separation tool - Added
TexturesToTpf.py- Automated TPF creation with full format compliance - Added
Run_TexturesToTpf.bat- Convenient batch launcher - Replaced legacy
DdsToPng.pyandCreateLog.pyscripts - Enhanced workflow documentation
- Added OpenTexMod files (no maintained download source available)
- Fixed various issues
- Initial release
- Added DdsToPng.py
- Added CreateLog.py
This project is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License. See LICENSE.md for details.
- OpenTexMod - Open-source implementation by the modding community
- TexModTools Scripts - Jakob Wapenhensch (2022, 2025 updates)