Skip to content

Commit

Permalink
[GitHub Action] Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
actions-user committed May 1, 2024
1 parent 4acecf0 commit 97ee978
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 11 deletions.
22 changes: 20 additions & 2 deletions docs/Mod-Creation/Assets/Sounds/WWise/Custom-Music.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Custom Music

- Setup WWise with that [tutorial](https://github.com/risk-of-thunder/R2Wiki/wiki/Wwise---Custom-Sounds)
- Setup WWise with that [tutorial](https://www.youtube.com/watch?v=QtfYsdJFty4), note that version v2019.2.12.7544 is no longer available for download, you can get v2019.2.14.7616 as they are compatible.

- [Get the boilerplate music project for RoR2](https://cdn.discordapp.com/attachments/562704639569428506/885995425264463872/RoR2MusicTest.zip)
- [Get the boilerplate music project for RoR2](https://github.com/viliger2/RoR2MusicTest)

- Open it. Go to the SoundBanks tab, rename the soundbank to something unique and not shared by any other mods.

Expand Down Expand Up @@ -81,3 +81,21 @@ d.SceneDefToTracks.Add(logBookScene, new List<SoundAPI.Music.MainAndBossTracks>(

SoundAPI.Music.Add(d);
```

### Explanation on "magic numbers":

RoR2 comes with its own Init.txt file that can be found inside Risk of Rain 2_Data\StreamingAssets\Audio\GeneratedSoundBanks\Windows folder. What interests us the most are State Groups and States. If we loot at any game's MusicTrackDef with thunderkit we will see that most of them have two states - one that references the song itself and another references where the song is used

![image](https://github.com/risk-of-thunder/R2Wiki/assets/53978306/e11b39f3-3589-4b3a-894f-3e6859832ef8)

and while song reference can be pretty much anything, where it is used needs to match game's values so it can actually play. That's exactly what we did when we created CustomMusicTrackDef with two custom states, first pair of group and state ids reference our song, while second references needed game's music system. If we cross-reference second pair with game's Init.txt we discover that Group ID is State Group "Music_system" and State ID is Stats "Gameplay". There are 5 states in total

* Gameplay - 89505537
* Bossfight - 580146960
* None - 748895195
* SecretLevel - 778026301
* Menu - 2607556080

by changing second StateId to any of those values we change where the song plays.

Also, you need to make sure whether new song is "main" track or "boss" track. Each SceneDef has two field for music - mainTrack and bossTrack. All main stages have both of those fields populated, however some other scenes (such as main menu, logbook, bazaar, etc) can only have mainTrack. And depending where it plays it needs to have correct State ID. For example, for main menu, logbook, lobby, etc. it needs to be Menu (2607556080), for stages it needs to be Gameplay (89505537), for teleporter events (those are "boss" tracks) - Bossfight (580146960). SecretLevel (778026301) is only used for bazaar as far as I know, every other "Hidden Realm" uses Gameplay for its main track.
39 changes: 30 additions & 9 deletions docs/Mod-Creation/Assets/Sounds/WWise/Getting-Started.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Getting Started

## Requirements:
* [Wwise v2019.2.12.7544](https://www.audiokinetic.com/download/)
* [Wwise v2019.2.12.7544](https://www.audiokinetic.com/download/)
* NOTE: while SoTV version of RoR2 uses 2019.2.12.7544, Autokinetic removed the ability to download it (I've been told they do that from time to time) so instead you can download 2019.2.14.7616, they are compatible and the way you make sure if it is compatible or not is by checking what SchemaVersion and what SoundbankVersion you got in SoundbanksInfo.xml file after generating your soundbanks with Wwise. SoTV version of RoR2 uses SchemaVersion 12 and SoundbankVersion 135. You can find game's SoundbanksInfo.xml inside Risk of Rain 2_Data\StreamingAssets\Audio\GeneratedSoundBanks\Windows.
* An IDE (like Visual Studio 2022)
* Audio files in .wav format (will not work in any other format, convert using audacity if needed)

Expand All @@ -22,14 +23,34 @@ https://www.audiokinetic.com/library/edge/?source=InstallGuide&id=working_with_o
6. Wait for the Wwise Launcher to finish the integration process
7. Open the Project with Unity again
##### Remaining steps are only for ThunderKit users
8. Create an Assembly Definition in the Assets/Wwise folder and name it Wwise
9. Create an Assembly Definition in the Assets/Wwise/Editor folder and name it WwiseEditor
10. Install ThunderKit
11. Locate Risk of Rain 2 using the ThunderKit Settings window
12. Wait for import to finish
13. Delete Packages/Risk of Rain 2/Wwise.dll if it exists (.dll will not be visible in the name in Unity)
14. Delete Packages/Risk of Rain 2/plugins/AkSoundEngine.dll if it exists (.dll will not be visible in the name in Unity)
15. Delete Packages/Risk of Rain 2/plugins/AkWaapiClient.dll if it exists (.dll will not be visible in the name in Unity)
8. Backup your project before starting so you don't have to reintegrate Wwise in case Thunderkit fails to do its thing.
9. Create an Assembly Definition in the Assets/Wwise folder and name it Wwise
10. Create an Assembly Definition in the Assets/Wwise/Editor folder and name it WwiseEditor
11. Install ThunderKit
12. Install RoR2ImportExtensions
13. Locate Risk of Rain 2 using the ThunderKit Settings window
14. Wait for import to finish.
15. Delete Packages/Risk of Rain 2/Wwise.dll if it exists (.dll will not be visible in the name in Unity)
16. Delete Packages/Risk of Rain 2/plugins/AkSoundEngine.dll if it exists (.dll will not be visible in the name in Unity)
17. Delete Packages/Risk of Rain 2/plugins/AkWaapiClient.dll if it exists (.dll will not be visible in the name in Unity)

However, there is a chance that your import will get stuck (as in stops progressing), it is caused by conflicts between Wwise and Thunderkit. To solve this do the following steps:
* Delete both assembly definitions created on steps 9 and 10 and restart import process. Your best bet is to restore the backup that you surely made and start from step 11, ignoring 9 and 10 for now.
* After Thunderkit does its thing you will get error messaged described in steps 15 to 17. Ignore them for now.
* Go to Assets\Wwise and create Assembly Definition called Wwise, under Assembly Definition Reference add Unity.Timeline, click Apply.
* Go to Assets\Wwise\Editor, create Assembly Definition called WwiseEditor, under Assembly Definition References add Unity.Timeline and Wwise, under Platforms uncheck "Any Platform", click Deselect all and check "Editor" (**this is important, otherwise Thunderkit will attempt to compile editor scripts into assembly, resulting in errors**), click Apply.
* After this you will still get errors from steps 15 to 17, do those steps to fix the errors. You might need to restart the project after deleting dlls.

After doing all of this you should have a successful integration of Wwise and Thunderkit into your project. The easiest way to check whether integration was successful or not is to create MusicTrackDef (Create - RoR2 - MusicTrackDef) and if it looks like this

![image](https://github.com/risk-of-thunder/R2Wiki/assets/53978306/c619cbd6-d0e9-483f-9b2c-c81f3223c5af)

Then you did everything correctly. However if it looks like this

![image](https://github.com/risk-of-thunder/R2Wiki/assets/53978306/4b292886-5d44-446b-bec9-fde478c60db8)

then you messed up somewhere and have to retrace your steps.


### Process:
[The Whole process in video format up to the coding part.](https://www.youtube.com/watch?v=QtfYsdJFty4)
Expand Down
123 changes: 123 additions & 0 deletions docs/Mod-Creation/Assets/Stage.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ To find the scripting define symbols you need to go to ``Edit`` > ``Project Sett
- **[RoR2EditorKit](https://github.com/risk-of-thunder/RoR2EditorKit)** - A package that currently hosts the node placer and an abundance of other Unity editor utilites.
- **[R2API.Stages](https://thunderstore.io/package/RiskofThunder/R2API_Stages/)** - Not necessarily required but it is heavily urged to have your mod depend on this to make sure stages are implemented and balanced correctly, especially if you are making a variant.
- **[R2API.Addressables](https://thunderstore.io/package/RiskofThunder/R2API_Addressables/)** and **[R2API.Director](https://thunderstore.io/package/RiskofThunder/R2API_Director/)** - Not required but it hosts the Monster / Interactable Pool Addressable Scriptable objects explained later in the tutorial. Feel free to make your own means of making pools.
- **[R2API.Sound](https://thunderstore.io/package/RiskofThunder/R2API_Sound/)** - Not required but if you want to have custom music, it is required by this guide.
- **[LocationsOfPrecipitation](https://github.com/JaceDaDorito/jace-locationsofprecipitation/tree/main) (AKA "LoP")** - Required to populate certain fields (like the teleporter) or use certain prefabs (like newt statues). However, if you made an alternative to this that is also completely fine.
- Other usual Thunderkit project packages like **BepInEx** and **[RoR2MultiplayerHLAPI](https://thunderkit.thunderstore.io/package/RiskofThunder/RoR2MultiplayerHLAPI/)**.

Expand Down Expand Up @@ -483,6 +484,127 @@ After this, your DCCS and DP should be ready to be implemented into your scene.

With that, your stage should be fully functioning by now. However, there are still more topics to help improve your stages.

## Music

This section assumes that you use Jace's scripts for setting up the stage used in WaffleHouse.

Despite the fact that we use Thunderkit to create both assembly and asset bundles, we actually don't need to integrate Wwise into our project, since as of writing this section I've found no way to make `MusicTrackDefs` created in editor and filled with integrated Wwise to work. So instead we are going to do it in code.

Forst thing first, follow this [guide](https://risk-of-thunder.github.io/R2Wiki/Mod-Creation/Assets/Sounds/WWise/Custom-Music/) to get a Wwise project going. After generating soundbanks note State Group ID for your custom `gameplaySongChoice` and State IDs for your main and boss songs.

First we need to register our custom `Play_Music_System` to the game's `AkSoundEngine`.

```
private void Awake()
{
...
On.RoR2.MusicController.Start += MusicController_Start;
...
}
private void MusicController_Start(On.RoR2.MusicController.orig_Start orig, MusicController self)
{
orig(self);
AkSoundEngine.PostEvent("Play_Music_System2", self.gameObject);
}
```

This ensures that events are registered within the game and they will fire when needed.

Next, we need to load soundbanks with the sound engine.

```
internal const string SoundBankFileName = "WaffleHouseMusic.bnk";
internal const string InitSoundBankFileName = "WaffleHouseInit.bnk";
internal const string SoundbankFolder = "Soundbanks";
public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args)
{
...
var musicFolderFullPath = Path.Combine(Path.GetDirectoryName(typeof(ContentProvider).Assembly.Location), SoundbankFolder);
var akResult = AkSoundEngine.AddBasePath(soundbanksFolderPath);
if (akResult == AKRESULT.AK_Success)
{
Log.Info($"Added bank base path : {soundbanksFolderPath}");
}
else
{
Log.Error(
$"Error adding base path : {soundbanksFolderPath} " +
$"Error code : {akResult}");
}
akResult = AkSoundEngine.LoadBank(InitSoundBankFileName, out var _);
if (akResult == AKRESULT.AK_Success)
{
Log.Info($"Added bank : {InitSoundBankFileName}");
}
else
{
Log.Error(
$"Error loading bank : {InitSoundBankFileName} " +
$"Error code : {akResult}");
}
akResult = AkSoundEngine.LoadBank(SoundBankFileName, out var _);
if (akResult == AKRESULT.AK_Success)
{
Log.Info($"Added bank : {SoundBankFileName}");
}
else
{
Log.Error(
$"Error loading bank : {SoundBankFileName} " +
$"Error code : {akResult}");
}
...
}
```

And finally we need to fill `mainTrack` and `bossTrack` of our `StageDef`. We are gonna use `SoundAPI`'s `CustomMusicTrackDef` for that, since it allows us to just fill the ids and API will do the rest.

```
internal static IEnumerator LoadAssetBundlesAsync(AssetBundle scenesAssetBundle, AssetBundle assetsAssetBundle, IProgress<float> progress, ContentPack contentPack)
{
...
var mainCustomTrack = ScriptableObject.CreateInstance<SoundAPI.Music.CustomMusicTrackDef>();
mainCustomTrack.cachedName = "WaffleHouseCustomMainMusic";
mainCustomTrack.CustomStates = new List<SoundAPI.Music.CustomMusicTrackDef.CustomState>();
var cstate1 = new SoundAPI.Music.CustomMusicTrackDef.CustomState();
cstate1.GroupId = 487602916U; // gathered from the MOD's Init bank txt file
cstate1.StateId = 145640315U; // gathered from the MOD's Init bank txt file
mainCustomTrack.CustomStates.Add(cstate1);
var cstate2 = new SoundAPI.Music.CustomMusicTrackDef.CustomState();
cstate2.GroupId = 792781730U; // gathered from the GAME's Init bank txt file
cstate2.StateId = 89505537U; // gathered from the GAME's Init bank txt file
mainCustomTrack.CustomStates.Add(cstate2);
WHSceneDef.mainTrack = mainCustomTrack;
var bossCustomTrack = ScriptableObject.CreateInstance<SoundAPI.Music.CustomMusicTrackDef>();
bossCustomTrack.cachedName = "WaffleHouseCustomBossMusic";
bossCustomTrack.CustomStates = new List<SoundAPI.Music.CustomMusicTrackDef.CustomState>();
var cstate11 = new SoundAPI.Music.CustomMusicTrackDef.CustomState();
cstate11.GroupId = 487602916U; // gathered from the MOD's Init bank txt file
cstate11.StateId = 3403129731U; // gathered from the MOD's Init bank txt file
bossCustomTrack.CustomStates.Add(cstate11);
var cstate12 = new SoundAPI.Music.CustomMusicTrackDef.CustomState();
cstate12.GroupId = 792781730U; // gathered from the GAME's Init bank txt file
cstate12.StateId = 580146960U; // gathered from the GAME's Init bank txt file
bossCustomTrack.CustomStates.Add(cstate12);
WHSceneDef.bossTrack = bossCustomTrack;
// Don't forget to comment loading and assigning of game's tracks if you have them!
...
}
```
Note the second pair of ids, this [page](https://risk-of-thunder.github.io/R2Wiki/Mod-Creation/Assets/Sounds/WWise/Custom-Music/) at the bottom gives an explanation of what those ids are and how to fill them appropriately for each track.

After all this you should have custom music working within the game.

## Optimization

Optimization is **extremely** important to making your stage accessible to players. Currently, this topic isn't as fleshed out as I (JaceDaDorito) want it to be. Please, if you have any good information about stage optimization, message me @JaceDaDorito on discord and I will add it here. That being said, I will present what I know.
Expand Down Expand Up @@ -522,6 +644,7 @@ Line mentioned in screenshot:
## Credits

- **JaceDaDorito** - Wrote this documentation, made LoP, made R2API.Stages, and lead person pushing for easier stage making.
- **Viliger** - added music section, don't message Jace about it pls.
- **IDeathHD** - Helped get this started with initial code and general advice.
- **Nebby** - Helped create and clean code. Implemented a lot of the utilities detailed here into RoR2EditorKit and R2API.
- **GrooveSalad** - Made initial addressable DCCS/DP implementation, made cleaner stubbed shaders, and gave a lot of advice.
Expand Down

0 comments on commit 97ee978

Please sign in to comment.