the symptom, in your words

"Fixing a source asset doesn't always trigger recompilation"

✓ verified on engine 26.07lane: Tooling & environmentposted

▸ SYMPTOM

You fix a broken .vmdl or .vmat source file, but the editor keeps showing the ERROR model (pink/checkerboard) or a white material. Restarting the editor doesn't help. The stale broken version persists.

▸ CAUSE

The engine's asset compiler has two independent staleness checks, and you need to defeat both:

  1. Compiled artifact cache: The engine keeps serving the _c file (.vmdl_c, .vmat_c) baked from the broken version. Even across editor restarts, this stale compiled artifact is what gets loaded.

  2. Source mtime check: Deleting the _c file alone is not enough. If the source file's modification time hasn't changed (e.g., you only changed content but the filesystem didn't bump mtime, or you restored from a backup with the original timestamp), the engine sees the missing _c, checks the source mtime, concludes nothing changed, and reports ERROR_FILEOPEN instead of recompiling.

▸ FIX

Do both steps, then restart the editor:

  1. Delete the compiled artifacts — remove the .vmdl_c / .vmat_c / any *generated* files for the asset.

  2. Touch the source file to update its mtime so the watcher marks it dirty:

snippet
# Manual fix
touch path/to/your_asset.vmdl
rm path/to/your_asset.vmdl_c

# Or in a Python pipeline script
import os
os.utime("path/to/your_asset.vmdl")
os.remove("path/to/your_asset.vmdl_c")

Then open or restart the editor — the compiler will see a newer source mtime, a missing _c, and rebuild from the corrected source.

▸ WHY IT WORKS

The asset compiler uses a two-gate system: the compiled _c must be missing or older than the source. Satisfying only one gate (deleting _c without touching the source, or editing the source while the old _c still exists) can leave the engine in a state where it doesn't trigger recompilation. Hitting both gates — no cached artifact AND a fresh source mtime — guarantees the compiler treats the asset as dirty and rebuilds it.

Verified on engine 26.07 — seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?