Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ata4/bspsrc/llms.txt
Use this file to discover all available pages before exploring further.
BSP files can contain embedded files in an internal ZIP archive called the pakfile. BSPSource can extract these files with optional smart filtering to exclude VBSP-generated content.
Understanding Pakfiles
The pakfile is a ZIP archive embedded in the BSP’s LUMP_PAKFILE lump. It typically contains:
- Custom materials (.vmt, .vtf)
- Custom models (.mdl, .vvd, .vtx, .phy)
- Custom sounds (.wav, .mp3)
- Particle manifests
- VBSP-generated files (cubemaps, lighting data)
config.unpackEmbedded = true;
config.smartUnpack = false; // Extract everything
This extracts the entire pakfile contents to the output directory.
You can also extract the raw pakfile ZIP:
PakFile pakFile = new PakFile(bspFile);
pakFile.unpack(outputPath, true); // Direct ZIP extraction
Smart Unpacking
Smart unpacking filters out files automatically generated by VBSP, keeping only custom content:
config.unpackEmbedded = true;
config.smartUnpack = true; // Default: filter VBSP files
VBSP-Generated Files
BSPSource automatically detects and excludes these patterns:
VHV Files (HDR lighting data):
sp_0.vhv
sp_1.vhv
sp_hdr_0.vhv
sp_hdr_1.vhv
Cubemap VTF Files:
c-64_128_256.vtf
c-64_128_256.hdr.vtf
Default Cubemaps:
cubemapdefault.vtf
cubemapdefault.hdr.vtf
Smart unpacking uses regex patterns to identify VBSP-generated files, preserving only mapper-created custom content.
Custom File Filtering
You can provide custom extraction filters:
PakFile pakFile = new PakFile(bspFile);
// Extract only materials
pakFile.unpack(outputPath, fileName ->
fileName.endsWith(".vmt") || fileName.endsWith(".vtf")
);
// Extract only models
pakFile.unpack(outputPath, fileName ->
fileName.endsWith(".mdl") ||
fileName.endsWith(".vvd") ||
fileName.endsWith(".vtx") ||
fileName.endsWith(".phy")
);
// Exclude specific directories
pakFile.unpack(outputPath, fileName ->
!fileName.startsWith("maps/")
);
Path Traversal Protection
BSPSource prevents malicious pakfiles from writing outside the extraction directory:
// Blocked: ../../../etc/passwd
// Allowed: materials/custom/wall.vtf
Files attempting path traversal are automatically skipped with warnings.
Invalid Path Handling
Files with invalid characters in their paths are skipped:
// Skipped: "file\x00name.txt" (contains null byte)
Duplicate File Protection
Existing files are never overwritten:
// If materials/wall.vtf exists, extraction is skipped
LZMA Compression Support
BSPSource supports LZMA-compressed pakfile entries (used in some Source 2007+ games):
- Automatic LZMA detection
- Proper decompression with EOS marker handling
- Fallback for unsupported compression methods
Detection Functions
You can check if a file is VBSP-generated:
boolean isGenerated = PakFile.isVBSPGeneratedFile("c-64_128_256.vtf");
// Returns: true
boolean isGenerated = PakFile.isVBSPGeneratedFile("materials/custom/wall.vtf");
// Returns: false
Detection patterns:
// VHV pattern: sp(_hdr)?_\d+\.vhv
Pattern.compile("sp(_hdr)?_\\d+\\.vhv")
// Cubemap pattern: c(-?\d+)_(-?\d+)_(-?\d+)(\.hdr)?\.vtf
Pattern.compile("c(-?\\d+)_(-?\\d+)_(-?\\d+)(\\.hdr)?\\.vtf")
// Exact matches:
// - cubemapdefault.vtf
// - cubemapdefault.hdr.vtf
Configuration Examples
BspSourceConfig config = new BspSourceConfig();
config.unpackEmbedded = true;
config.smartUnpack = true; // Filter out VBSP files
BspSourceConfig config = new BspSourceConfig();
config.unpackEmbedded = true;
config.smartUnpack = false; // Include VBSP files
BspSourceConfig config = new BspSourceConfig();
config.unpackEmbedded = false;
Pakfile Structure
Typical pakfile contents:
pakfile.zip
├── materials/
│ ├── custom/
│ │ ├── wall.vmt
│ │ └── wall.vtf
│ └── maps/
│ └── mapname/
│ ├── c-64_128_256.vtf (VBSP)
│ └── cubemapdefault.vtf (VBSP)
├── models/
│ └── props/
│ ├── custom.mdl
│ ├── custom.vvd
│ └── custom.vtx
├── sound/
│ └── custom/
│ └── sound.wav
└── sp_0.vhv (VBSP)
With smartUnpack = true, only the custom files are extracted (excluding VBSP-generated files).
Error Handling
Missing Pakfile
try (ZipFile zip = pakFile.getZipFile()) {
// Extract files
} catch (IOException ex) {
// Pakfile broken or missing
}
Unsupported Compression
Files with unsupported compression methods are logged:
Cannot extract unsupported: file.txt| method: IMPLODE(6)| encryption: false
Invalid Entry Names
Skipped invalid_chars\x00.txt (contains invalid characters)
After extraction, custom content is organized by type:
output/
├── materials/
│ └── custom/
├── models/
│ └── props/
└── sound/
└── custom/
You can then:
- Copy to your game’s directory structure
- Package into a custom content pack
- Include in a recompiled map
Advanced Usage
PakFile pakFile = new PakFile(bspFile);
// Materials only
pakFile.unpack(materialsPath, name ->
(name.endsWith(".vmt") || name.endsWith(".vtf")) &&
!PakFile.isVBSPGeneratedFile(name)
);
// Models only
pakFile.unpack(modelsPath, name ->
name.startsWith("models/") &&
(name.endsWith(".mdl") || name.endsWith(".vvd") ||
name.endsWith(".vtx") || name.endsWith(".phy"))
);
Get ZipFile for Manual Processing
PakFile pakFile = new PakFile(bspFile);
try (ZipFile zip = pakFile.getZipFile()) {
for (Enumeration<ZipArchiveEntry> e = zip.getEntries(); e.hasMoreElements();) {
ZipArchiveEntry entry = e.nextElement();
// Custom processing
}
}
Some protected maps may include encrypted entity data (entities.dat) in the pakfile. See Protection Detection for details.