Check a custom sound as a chain: the SoundID name, its sounds.txt entry, the sample file, and a request from a realized room. Testing only the last call can hide a missing table entry or a file at the wrong path.

Start with one distinct trigger name. Its text must match the registered SoundID name used by the code. In build 22785462, global::SoundLoader.LoadSounds() compares registered trigger names against the resolved soundeffects/sounds.txt entries without case sensitivity. Give the name a mod prefix anyway, because another active mod can define a similar name.

Add one table line in the normal sound-table form:

myexample_dash_start : myexample_dash_start/vol=0.35

The text before : is the trigger. The text before /vol= is the sample name. Put the sample at one of the loose-file paths checked by global::SoundLoader.CheckIfFileExistsAsExternal(System.String):

soundeffects/myexample_dash_start.wav
soundeffects/myexample_dash_start.ogg

The loader also probes _1.wav and _1.ogg after the base name. Use one base sample for the first test. Add variations after that clip plays. The inspected source finds external samples during sound-table loading. It does not establish custom enum registration, mod merge results, or reload timing, so keep those as separate tests.

Request the trigger from a room with a known player position. A positioned one-shot is enough to prove the gameplay route:

self.room.PlaySound(
    dashStartSound,
    self.mainBodyChunk.pos,
    0.35f,
    1f);

dashStartSound is the registered SoundID for the table name. global::Room.PlaySound(global::SoundID,UnityEngine.Vector2,System.Single,System.Single) forwards to cameras currently in that room. It does not turn a missing trigger into a playable one. Sound playback has guards for a hook that requests a built-in cue.

Use this order when checking the package in game:

  1. Enable only the required mods and start a room where the request can occur.
  2. Trigger the action once and inspect the log for a missing sound or loader error.
  3. Confirm that the effect occurs once per action, rather than once per update while an input remains held.
  4. Check the same copied package after a restart.
  5. Add one numbered variation, then repeat the check and listen for selection changes.

If code runs but no sound is heard, first compare the exact SoundID string, table trigger, sample name, and path. Next check whether the source package supplied sounds.txt through the resolved path described in Asset resolution. A file under loadedsoundeffects follows a different override route for clips already classified as asset-bundle clips. Do not move a new loose sample there to solve a missing soundeffects entry.

Do not use this checklist for procedural music or new room ambience. Music uses asset bundles, and ambience has room-settings ownership and a separate loader path. Sound assets identifies those boundaries. Test the final package’s audible level beside ordinary game sounds. The 0.35f value is only an example request level.

Sources

  • Rain World v1.11.8, Steam build 22785462: global::SoundID, global::SoundLoader.LoadSounds(), global::SoundLoader.CheckIfFileExistsAsExternal(System.String), and global::Room.PlaySound(global::SoundID,UnityEngine.Vector2,System.Single,System.Single) in the assembly identified by Runtime reference.
  • Sound assets and Sound playback