Runtime Material Invalidation
The Source Engine material system cannot automatically invalidate cached VMT/VTF data at runtime because it records modification timestamps only during the initial load phase and lacks a native file-system watcher. To implement this without stalling the render thread or breaking mod overrides, you must decouple the file-system monitoring from the material reload process.
Proposed Implementation Strategy
To avoid frame hitches, the system should use a background watcher rather than a synchronous check on the render thread. The following architecture is recommended:
- Asynchronous Monitoring: Implement a lightweight file-system watcher (or a periodic poll every 2–3 seconds) on a separate thread. This thread monitors timestamps for VMT/VTF files.
- Deferred Invalidation: When a change is detected, the background thread should not modify the cache directly. Instead, it should queue a "Reload Material" task.
- Safe Execution: The render thread consumes this queue at a safe synchronization point (e.g., the start of a frame), reloading only the specific affected material rather than flushing the entire cache.
Handling Mod Overrides and Performance
To maintain visual consistency and performance, the implementation must adhere to these constraints:
| Constraint |
Resolution Method |
| Mod Priority |
The invalidation logic must verify the mod load order. A change to a base game VMT should not trigger a reload if a higher-priority mod override is currently active in the cache. |
| Frame Budget |
A timestamp check typically costs <0.5μs per file. By polling in the background, the impact on the main render thread is limited to the time taken to swap a pointer or reload a single texture, well within a 1ms per-frame budget. |
| Thread Safety |
Use a double-buffered cache swap or a mutex-protected queue to prevent race conditions between the watcher thread and the renderer. |
Verification Steps
To verify this implementation, perform the following tests:
- Latency Test: Measure frame times using a high-resolution timer while triggering multiple VMT edits to ensure no spikes exceed 1ms.
- Override Test: Load a mod that overrides
concrete.vmt. Edit the base concrete.vmt file and verify that the modded version remains visible.
- Stress Test: Monitor memory usage when rapidly editing files to ensure the background queue does not leak or overflow.
Missing Diagnostic: Are you targeting a specific branch of the engine (e.g., Source 1, Source 2, or a specific mod SDK)? The availability of thread-safe task queuing varies significantly between versions.