Source Engine BSP Compiler Incremental Rebuild Limitation After Texture Changes
0 reputation · 27 Jul 2020, 05:28 UTC
0 reputation · 27 Jul 2020, 05:28 UTC
The Source engine's standard compile pipeline (VBSP, VVIS, VV) processes entire map geometry and lighting models during each build. When a single texture's scale or material parameter is modified, the compiler does not recognize this as an isolated change and instead rebuilds all lighting data from scratch.
This behavior prevents repeatable development iterations, as level designers cannot rely on incremental updates to reflect minor texture adjustments. The compile cache generated during prior builds does not track source texture metadata, meaning stale lightmap resolutions persist across rebuilds unless intermediate files are manually cleared.
The issue affects all Source engine variants including GoldSrc and Source 2013, creating a consistent bottleneck in modding workflows where rapid iteration on materials is required.
Which specific texture or material metadata changes trigger a full rebuild versus being handled incrementally, and how can developers identify when a clean rebuild is actually necessary versus when intermediate file management is sufficient?
34775 reputation · 27 Jul 2020, 12:17 UTC
Only changes that alter a face's lightmap scale (lightmap resolution per face) force a full lighting rebuild, because that value is baked into the BSP face structure itself. Everything else that lives purely in the material VMT — $basetexture, $surfaceprop, $detail, $color2, shader proxies, texture alignment/offset — can be handled incrementally, because VBSP emits identical face geometry and the cached visibility/radiosity data stays valid.
The compile pipeline (VBSP → VVIS → VRAD) caches visibility (.prt, .vvis) and radiosity transfer data, but it stores no texture metadata. It cannot diff "what changed" between builds. What it can detect is structural: when a face's lightmap scale changes, VBSP rewrites that face's lightmap UVs and allocates a new lightmap page. That invalidates the radiosity solution for the affected cluster, so VRAD must relight from scratch.
Pure VMT edits never touch the BSP at all — the material is looked up at runtime. Texture offsets/alignment shift the diffuse texture mapping but not the lightmap UV layout, so they're also incremental-safe.
| Change | Rebuild needed |
|---|---|
| Face lightmap scale (e.g., 16 → 8) | Full VRAD (cluster invalidated) |
| $basetexture, $surfaceprop, $detail, $color2, proxies | None — VMT only, no recompile |
| Texture alignment/offset (texture lock) | Incremental-safe |
| Light entity moved/added (Source 2013) | VRAD -incremental |
| Any geometry/brush change | Full VBSP + VVIS + VRAD |
Compile with VBSP verbose output and check the log:
vbsp.exe -verbose mapname.vmf 2>&1 | findstr /i "lightmap scale changed lightmap page"Lines like Face X: lightmap scale changed or Created new lightmap page confirm a full relight is unavoidable. Their absence means vrad -incremental is sufficient.
.bsp/.prt while keeping .vvis/.rad; if cluster boundaries shifted you'll get lighting artifacts. When in doubt, clear all intermediates.func_detail; their lightmap pages are separate, narrowing the invalidation scope.Note: exact log strings vary by engine branch; verify against your toolchain's VBSP output before scripting around them.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.