content_version
Per-path content-version counters — a cheap, synchronous "has this file changed?" token. An assetType behavior memoizes its parse in the ref's `runtime` keyed by the counter `get(path)` returned when it parsed, then serves every later read as an integer compare instead of re-read…
content_version
Per-path content-version counters — a cheap, synchronous "has this file
changed?" token. An assetType behavior memoizes its parse in the ref's
runtime keyed by the counter get(path) returned when it parsed, then serves
every later read as an integer compare instead of re-reading and re-parsing the
file.
Why it exists
A .data() behavior that re-reads and re-parses its source on every call is
pure overhead when the file hasn't changed. This module gives it a version
token to gate the rebuild on:
get(path)when the parse ran, stored alongside the parsed value.- On every later call, compare
get(path)to the stored value — equal means the cache is still valid (novfs.read, no parse); a bump means rebuild.
Exports
M.get(path: string) -> number— the path's current version counter (0if never written this VM).M.bump(path: string)— bumppath's counter, invalidating every reader memoized against its previous value. Content code rarely calls this directly.
What bumps a counter
Two write surfaces feed it, so the token reflects a change no matter where it originated:
vfs.write/vfs.move/vfs.removebump synchronously, in the same call — so a script that writes a file and reads it back in the same tick sees the new content immediately (the asset-changeonChangedispatch fires a frame later, too late for a same-tick read).- the generic asset-change dispatcher bumps on every source write it routes,
including peer-synced and engine-originated writes that never pass through the
Luau
vfs.*surface — with the engine's normalized path, the canonical form a reader keys on.
Per-path, not a global epoch
Counters are per path, not one global epoch. The per-frame dirty-entity writer churns scene-dirty paths every frame during play; a global epoch would let that churn invalidate every unrelated cache. Per-path isolation means only a change to the file a reader depends on rebuilds it.
The counter map lives on _G (__zero_content_versions), installed once before
the global table is sealed at boot, so a single map is shared across every copy
of this module that a require-cache reset (vfs.reload) might create. A
module-upvalue map would let a bumper and a reader that landed on different
module copies diverge, and the reader would serve stale content. Per-VM.
Scoped to this part · feeds back into the world's score.