Modding: API

Updated 5 days ago

Modding API

Grenade Launcher 2.0.2 includes a small public API for mods that create their own RocketLauncher weapons.

The API lets another mod use Grenade Launcher's grenade primary fire and custom weapon model on one specific weapon without changing the player's normal Grenade Launcher loadout.

It can also be used in the opposite direction: a mod can force one of its weapons to remain a normal Rocket Launcher even if the player has selected the Grenade Launcher alternate form in the terminal.

Before You Start

The public API is in:

GrenadeLauncherMod.GrenadeLauncherIntegration

The examples on this page assume your mod has a normal dependency on Grenade Launcher and references GrenadeLauncher.dll.

The BepInEx plugin GUID is:

docvalentyne.ultrakill.grenadelauncher

For example:

[BepInDependency("docvalentyne.ultrakill.grenadelauncher")]

If Grenade Launcher is meant to be an optional dependency instead, you will need to handle the possibility that its assembly is not installed. The direct examples below are intended for normal required-dependency integrations.


The Simple Case: Give Your Weapon Grenade Launcher Primary Fire

If your mod has its own RocketLauncher instance and you want its primary fire to use Grenade Launcher's grenade behavior:

using GrenadeLauncherMod;

RocketLauncher launcher = GetComponent<RocketLauncher>();

GrenadeLauncherIntegration.RegisterExternalLauncher(launcher);

That's the basic integration.

This registration affects only that exact RocketLauncher instance.

It does not change the player's terminal selection, and it does not turn every launcher of the same color into a Grenade Launcher.

By default, registering an external launcher also tells Grenade Launcher:

"My mod owns this weapon's secondary fire."

That prevents the normal Rocket Launcher or Grenade Launcher Alt-Fire from also activating when your mod reads Fire2.


Who Owns Alt-Fire?

The second argument to RegisterExternalLauncher controls secondary-fire ownership.

GrenadeLauncherIntegration.RegisterExternalLauncher(
    launcher,
    externalSecondary: true
);

externalSecondary: true

Your mod owns Alt-Fire.

Grenade Launcher suppresses the launcher's normal Fire2 behavior so your own secondary can use the input without both attacks activating.

This is the default.

externalSecondary: false

Grenade Launcher does not take Fire2 away from the weapon.

Use this if you want the launcher to retain its normal secondary behavior.

You can change this later:

GrenadeLauncherIntegration.SetExternalSecondaryOwnership(
    launcher,
    true
);

Force One Weapon to Stay a Normal Rocket Launcher

Sometimes the opposite problem happens.

Your mod may clone a vanilla Rocket Launcher for a custom weapon, but the player has selected Grenade Launcher for that same vanilla variation.

If your custom weapon should always keep normal rocket primary fire:

GrenadeLauncherIntegration.RegisterExternalNativeLauncher(launcher);

This affects only that exact launcher.

You can also have a native rocket primary while your mod owns the Alt-Fire:

GrenadeLauncherIntegration.RegisterExternalNativeLauncher(
    launcher,
    externalSecondary: true
);

You can switch an already registered weapon between the two primary types:

GrenadeLauncherIntegration.SetExternalPrimaryMode(
    launcher,
    GrenadeLauncherPrimaryMode.Grenade
);

or:

GrenadeLauncherIntegration.SetExternalPrimaryMode(
    launcher,
    GrenadeLauncherPrimaryMode.Native
);

Custom Grenade Launcher Colors

Grenade Launcher's custom weapon model has four paint groups:

  • Orange
  • Silver
  • Black
  • Deep Black

An external weapon can supply its own colors without changing the player's normal Grenade Launcher color settings.

GrenadeLauncherPaintPalette palette =
    new GrenadeLauncherPaintPalette(
        orange: Color.red,
        silver: Color.white,
        black: Color.black,
        deepBlack: new Color(0.02f, 0.02f, 0.02f)
    );

GrenadeLauncherIntegration.RegisterExternalLauncher(
    launcher,
    palette,
    externalSecondary: true
);

If the weapon is already registered:

GrenadeLauncherIntegration.SetExternalPalette(launcher, palette);

To return that weapon to Grenade Launcher's normal colors:

GrenadeLauncherIntegration.ClearExternalPalette(launcher);

The palette applies to Grenade Launcher's custom viewmodel. It does not change the player's saved global color settings.


Change Grenade Projectile Appearance

An external launcher can choose which authored grenade texture its normal primary grenades use.

Available appearances are:

GrenadeLauncherProjectileAppearance.Default
GrenadeLauncherProjectileAppearance.Orange
GrenadeLauncherProjectileAppearance.Blue
GrenadeLauncherProjectileAppearance.Green
GrenadeLauncherProjectileAppearance.Red

For example:

GrenadeLauncherIntegration.SetExternalPrimaryProjectileAppearance(
    launcher,
    GrenadeLauncherProjectileAppearance.Blue
);

That changes ordinary primary grenades from this launcher.

Default returns to Grenade Launcher's normal profile-based appearance.

Change Only the Next Grenade

If your custom Alt-Fire calls RocketLauncher.Shoot() but needs a special projectile color for only that shot:

GrenadeLauncherIntegration.SetNextExternalProjectileAppearance(
    launcher,
    GrenadeLauncherProjectileAppearance.Red
);

launcher.Shoot();

Only the next grenade from that launcher receives the override.

Afterward, its normal projectile appearance is used again.

This is useful for custom secondary attacks without permanently recoloring the weapon's primary fire.


Use the Custom Alt-Fire Animation

If your mod owns Fire2, you can tell the custom Grenade Launcher model to play its authored alternate-fire animation:

GrenadeLauncherIntegration.PlayExternalSecondaryAnimation(launcher);

This only handles the presentation.

It does not fire a projectile or perform your attack for you.

Your mod remains responsible for the actual secondary mechanic.

This function is intended for launchers registered with:

externalSecondary: true

Control the Cooldown Dial

External Alt-Fires can also use the cooldown display on Grenade Launcher's custom model.

Pass a value from 0 to 1:

GrenadeLauncherIntegration.SetExternalSecondaryCooldownProgress(
    launcher,
    progress
);

Where:

0 = completely empty / just used
1 = completely charged / ready

For example, for a four-second cooldown:

float progress = Mathf.Clamp01(
    (Time.time - cooldownStartedAt) / 4f
);

GrenadeLauncherIntegration.SetExternalSecondaryCooldownProgress(
    launcher,
    progress
);

Grenade Launcher handles positioning and rotating its custom cooldown dial. Your mod only needs to provide the progress.


A Typical Custom Weapon

A mod that wants:

  • Grenade Launcher primary fire
  • its own Alt-Fire
  • a custom weapon color
  • blue primary grenades

could initialize the weapon like this:

using GrenadeLauncherMod;
using UnityEngine;

void SetupWeapon(RocketLauncher launcher)
{
    GrenadeLauncherPaintPalette palette =
        new GrenadeLauncherPaintPalette(
            new Color(0.3f, 0.8f, 1f),
            Color.white,
            new Color(0.1f, 0.1f, 0.1f),
            new Color(0.02f, 0.02f, 0.02f)
        );

    GrenadeLauncherIntegration.RegisterExternalLauncher(
        launcher,
        palette,
        externalSecondary: true
    );

    GrenadeLauncherIntegration.SetExternalPrimaryProjectileAppearance(
        launcher,
        GrenadeLauncherProjectileAppearance.Blue
    );
}

Then when the custom Alt-Fire activates:

void FireCustomAlt(RocketLauncher launcher)
{
    GrenadeLauncherIntegration.PlayExternalSecondaryAnimation(launcher);

    // Your custom attack goes here.
}

And while its cooldown recharges:

GrenadeLauncherIntegration.SetExternalSecondaryCooldownProgress(
    launcher,
    cooldownProgress
);

Dual Wield

You do not need to manually register every Dual Wield copy.

Grenade Launcher automatically copies its external registration information when ULTRAKILL creates a Dual Wield duplicate.

This includes:

  • primary mode
  • external secondary ownership
  • custom paint palette
  • secondary cooldown display
  • normal projectile appearance

A one-shot projectile appearance override is intentionally not copied.


Removing a Registration

If your mod wants to stop controlling a launcher:

GrenadeLauncherIntegration.UnregisterExternalLauncher(launcher);

You can check whether a launcher is registered with:

bool registered =
    GrenadeLauncherIntegration.IsExternalLauncher(launcher);

Grenade Launcher also cleans up registrations when the corresponding RocketLauncher is destroyed.


Important Notes

Registration is per weapon instance

Registering one launcher does not globally change all Blue, Green, or Red Rocket Launchers.

This is intentional so mods can create completely separate weapons using the same vanilla chassis.

Terminal choices are left alone

The API does not rewrite the player's Grenade Launcher selections in the terminal.

External weapons and the player's normal arsenal can coexist.

Your custom secondary is still your responsibility

Setting externalSecondary: true prevents Grenade Launcher/native Rocket Launcher Fire2 behavior from leaking through.

It does not create a new Alt-Fire for you.

Use PlayExternalSecondaryAnimation and SetExternalSecondaryCooldownProgress if you want your mechanic to match the custom Grenade Launcher model.

Do not patch Grenade Launcher internals unless you actually need to

If the behavior you need is covered by this API, using the public API is strongly preferred.

Internal classes and implementation details may change between versions. The public integration API exists so other mods do not have to depend on those internals.


Public API Quick Reference

GrenadeLauncherIntegration.RegisterExternalLauncher(...)
GrenadeLauncherIntegration.RegisterExternalNativeLauncher(...)

GrenadeLauncherIntegration.SetExternalPrimaryMode(...)
GrenadeLauncherIntegration.SetExternalSecondaryOwnership(...)

GrenadeLauncherIntegration.SetExternalPalette(...)
GrenadeLauncherIntegration.ClearExternalPalette(...)

GrenadeLauncherIntegration.SetExternalPrimaryProjectileAppearance(...)
GrenadeLauncherIntegration.SetNextExternalProjectileAppearance(...)

GrenadeLauncherIntegration.PlayExternalSecondaryAnimation(...)
GrenadeLauncherIntegration.SetExternalSecondaryCooldownProgress(...)

GrenadeLauncherIntegration.IsExternalLauncher(...)
GrenadeLauncherIntegration.UnregisterExternalLauncher(...)

Related public types:

GrenadeLauncherPrimaryMode
GrenadeLauncherProjectileAppearance
GrenadeLauncherPaintPalette

This API was added in Grenade Launcher 2.0.2.