s&box/field-guide
the symptom, in your words

"My custom sound event won't play"

✓ verified on engine 26.07lane: Audioposted
▸ SYMPTOM
  • Sound.Play(...) silent; log may say Couldn't find sound event.
  • .sound_c / .vsnd_c sit 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:

  1. Full resource path WITH extension — cache-hash lookup on ResourcePath including .sound.
    Example: "sounds/impact/boing_a.sound"
  2. 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.

▸ FIX
snippet
// 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 miss

Translate house names → engine paths at one boundary:

snippet
static string EngineEventPath(string houseName) =>
    $"sounds/{houseName}.sound"; // or your folder layout, always with .sound

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.

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