Skip to content

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*

Alt

Return to your project and right click on the C# project in the Solution Explorer.

Alt

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.

Alt

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.

Alt

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.

Alt

Double click on the function name and the program will bring you to the function itself.

Alt

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".

Alt

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".

Alt

There's a function that calls it called check_for_rolled_cr, so let's click on that to go to the function

Alt

If we scroll down, we can see how this function pulls the player instance and assigns to it.

Alt

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.

Alt

cs
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.