"My custom sound event won't play"
▸ SYMPTOM
Sound.Play(...)silent; log may sayCouldn't find sound event..sound_c/.vsnd_csit healthy on disk.- Partial paths copied from folder layout (
"impact/boing_a") never work. - Sounds compiled after the session started stay invisible until an editor kick.
▸ CAUSE
SoundEvent.Find (decompiled contract, engine ~26.07.08c) only accepts two name forms:
- Full resource path WITH extension: cache-hash lookup on
ResourcePathincluding.sound.
Example:"sounds/impact/boing_a.sound" - Bare filename: fallback compares
ResourceName(never contains/).
Example:"boing_a"
Resource.FixPath only normalizes slashes / strips _c. It never prepends sounds/ or appends .sound. So "impact/boing_a" fits neither form.
The install's Sound.Play("cardboard_rustle_loop") works via form 2: generalizing that to "family/name" is wrong.
Also: the editor builds its asset registry at session start. Assets compiled later exist on disk but won't resolve until re-index (editor kick). Mtime staleness is a red herring. Prove with a known-working control asset at identical mtimes before chasing clocks.
The miss is completely silent (re-verified 26.07.22): a name that fails to hash-match doesn't throw. Sound.Play just logs Couldn't find sound event, returns no handle, and a null-tolerant caller degrades straight to silence with no stack trace anywhere in the chain. Comparing asset_info on the failing name against a known-working one shows them identical in every compile/mount respect, which isolates the path string as the only variable, so treat the string, not the asset, as the suspect.
▸ FIX
// GOOD
Sound.Play("sounds/impact/boing_a.sound");
Sound.Play("boing_a");
// BAD - never resolves
Sound.Play("impact/boing_a");
Sound.Play("sounds/impact/boing_a"); // missing .sound - still form-1 missTranslate house names → engine paths at one boundary:
static string EngineEventPath(string houseName) =>
$"sounds/{houseName}.sound"; // or your folder layout, always with .soundNumbered variant suffixes go before the extension: "sounds/impact/boing_a_2.sound", never "...boing_a.sound_2" (not a form the resolver recognizes).
A library-mounted event needs no library-name prefix: reference it with the same project-relative sounds/... path a project would use for its own assets, extension and all.
Don't trust "Couldn't find sound event" to mean missing/uncompiled: distinguish name-form bugs from index/compile bugs (live editor probe if you have one).
After adding sounds mid-session: kick the editor / restart play so the registry picks them up. Zero-volume canary of a few known events at first SFX use turns "audio mysteriously dead" into one log line.
Retry policy for loops: once after ~2s, then disable, never per-frame retry a permanently missing event.
▸ WHY IT WORKS
Resource lookup is a hash on the exact path string or a bare-name equality check. Partial paths are a third shape the API does not implement. Session-start indexing means disk presence ≠ runtime visibility until the registry refreshes.
- Re-verified on 26.07.22: the miss never throws (a null-tolerant caller degrades straight to silence); asset_info on a failing vs working name is identical, isolating the path string; a library-mounted event needs no library-name prefix; variant suffixes go before the extension.
- Published