Create an Effect
WARNING
Our MelonLoader plugin is no longer being developed. Please instead check out our new BepInEx plugin. We apologise for the incomplete documentation at this time.
This section will go over creating a custom effect for Cuphead.
Attach The Game
Locate your Unity game's folder. You will need to find the Assembly-CSharp.dll which is usually located in *(GameName)_Data\Managed*
Return to your project and right click on the C# project in the Solution Explorer.
In the Reference Manager, click the Browse button and locate your DLL. Also, attach the UnityEngine.dll and UnityEngine.CoreModule.dll found in the same folder.
Click "OK". You'll be able to reference the game's assembly.
Download dnSpy
You can find dnSpy here: https://github.com/dnSpy/dnSpy/releases/latest
This will be used to look into Cuphead's assembly and find the appropriate variables and functions to reference and change.
Finding the Reference
In this example, let’s create a new effect to heal the player. In the bottom right window of your screen, search for 'health'. Browse through the results to find anything related to player's health.
As you scroll through the list, you'll find a function named SetHealth in the PlayerStatsManager. It seems like a fitting choice to modify the player's health during runtime.
Double click on the function name and the program will bring you to the function itself.
We've ran into luck, because this is a public function we can reference inside of the PlayerStatsManager class. Right clicking on the function name and click on "Analyze".
The bottom window displays what the function uses and what uses it. We want to find an example of how the code references this function properly, so we'll click on "Used By".
There's a function that calls it called check_for_rolled_cr, so let's click on that to go to the function
If we scroll down, we can see how this function pulls the player instance and assigns to it.
We can then use this example and apply it to our own code. Return to Visual Studio and we can now write a function that will increase the player's health if they're alive and not at max health.
public override EffectResult OnTriggerEffect(CCEffectInstance effectInstance)
{
PlayerStatsManager stats = PlayerManager.GetPlayer(PlayerId.PlayerOne).stats;
if (stats.Health == stats.HealthMax || stats.Health == 0) {
return EffectResult.Retry;
}
stats.SetHealth(stats.Health + 1);
return EffectResult.Success;
}
If everything's right, this effect will heal the player by 1 point if they're alive and not fully healed. Next, we'll add a Harmony Patch to our game to handle the effects.