Skip to content

Making a simple Sound‐Pack

LoafOrc edited this page Feb 18, 2024 · 5 revisions

Before we begin make sure you have enabled LogLevels to be All under [Logging.Console] and [Logging.Disk]. loaforcsSoundAPI will output valuable information on the debug channels. This tutorial will also assume you already have sounds you want to replace.

Important

loaforcsSoundAPI currently supports .ogg, .wav and .mp3 (experimental)! Make sure to convert your files!

Everything is case-sensitive! So make sure to check that you've got the correct case, most of the time it is lowercase_with_underscores

Getting a Sound-Pack to load

loaforcsSoundAPI automatically scans the BepInEx/plugins folder for potential Sound-Packs. It needs a sound_pack.json inside the root folder for it to be picked up correctly.

Example Folder structure:

BepInEx/
- plugins/
  - MySoundPack/
    - sound_pack.json

This will be picked up by loaforcsSoundAPI.

Now our sound_pack.json will contain more internal information about how our mod wants to be loaded and other settings. The following is the simplest sound_pack.json you need.

{
    "name": "MySoundPack"
}

The name value is required, but can be different to the folder name. Now if we run Lethal Company we should see:

You've successfully made a Sound-Pack! Continue with the tutorial to learn how to begin replacing sounds.

printed to the console. If not you should see a helpful error message; I'm going to be trying my best to make error messages legible and actually useful to cut down on time trying to just read them.

Replacing your first sound.

We'll need to add a few more folders into our Sound-Pack to start replacing sounds. We'll need to create the replacers and sounds folders under our root folder

BepInEx/
- plugins/
  - MySoundPack/
    - sounds/
    - replacers/
    - sound_pack.json

From here we can begin writing our first replacer!

For organisation purposes you can have as many replacers as you want, containing as few and as many sounds as you want to replace.

Important

Just because you can doesn't mean you should

Each replacer you add means: more start-up time and more memory usage

Let's create a replacer that will handle replacing all main menu/pause menu sounds. We're going to make a simple mod to replace the menu music. Let's call it menu.json, make sure to place it under the replacers folder.

replacers/
 - menu.json

Now what do we put in our menu.json file? Well all replacers will have a common structure:

{
    "replacements": [
        {
            "matches": "<lethalcompany_friendly_name>",
            "sounds": [
                {
                    "sound": "<path_to_replacement>"
                }
            ]
        }
    ]
}

First we have the required field of replacements. This is a list of every sound that this file will replace. Notice how matches and sounds are also surronded by { }. This is an object that will contain data for replacing sounds.

matches

Next is matches. This is how we tell loaforcsSoundAPI what sound we want to replace. Now here's where a major difference between loaforcsSoundAPI and CustomSounds appears. In CustomSounds you would find the name of the asset and save your file as Menu1.ogg somewhere in your file structure. In loaforcsSoundAPI Menu1 is still a part of what you put for matches but it requires more information. This extra information helps solve the issue of random unrelated sounds playing at the incorrect places, and that is the GameObject's name.

This is where it is vital that you have enabled debug logs. Bootup the game and you will see it display a lot of things like

[Debug  :me.loaforc.soundapi] Getting replacement for: 'Canvas:MenuManager:Menu1'

In the quotation marks is our matches. Here we want to replace the main menu music which is Menu1 but it's full name is Canvas:MenuManager:Menu1. Now in very rare cases do we need the very first argument here, so we are going to shorten this to MenuManager:Menu1. This will still resolve the same.

sounds

We also have the sounds data field. This is another list that contains all variations of the sound that is going to replace it. This points to our sounds folder.

Let's place our main menu music inside our mod:

sounds/
 - main_menu/
   - music.ogg

Notice how music.ogg is NOT the actual name of the ingame sound. With CustomSounds it was required that it was named Menu1.ogg, this is where loaforcsSoundAPI is different

Now we can point loaforcsSoundAPI to this by creating this sound def:

{
    "sound": "main_menu/music.ogg"
}

We also don't need to include sounds/, loaforcsSoundAPI will automatically add that for us.

Combining it all

We now have all the parts needed to create a sound replacement:

{
    "replacements": [
        {
            "matches": "MenuManager:Menu1",
            "sounds": [
                {
                    "sound": "main_menu/music.ogg"
                }
            ]
        }
    ]
}

Now restart Lethal Company and it should just replace it. You may notice the following warning:

No replacers were defined in `replacers` so every single replacer is being loaded on start-up. Consider adding some so that loaforcsSoundAPI can use multithreading.

You can ignore this for now.