Skip to content

Modded Connectors ​

Welcome to the Crowd Control Modding SDK! The SDK is used for all of our in-house emulator integrations as well as a majority of our PC mods. The SDK has several connectors to various platforms and standards, including:

  • memory reading and writing inside emulators including BizHawk, or in Windows apps
  • TCP connections to local mods using BepInEx, MelonLoader, or custom game mods
  • text file input/output connections to especially locked down mods
  • and a couple more really obscure connectors

The SDK is required only for game modding; for developing your own game or non-game projects like overlays, please check out our other plugins and APIs on the homepage.

Getting Started ​

A "native" game pack is a C# file loaded by the Crowd Control desktop app or SDK. It defines your game metadata, effect list, and connector details. Depending on the connector, the effect logic may live inside the pack itself or inside a separate mod/plugin.

API reference ​

If something you need is missing from this guide and the linked guides, check out the SDK API reference. It's periodically generated from the public .NET assemblies shipped to game pack projects. It covers the public pack base classes, game and effect models, connector interfaces, and connector implementations.

The reference intentionally excludes internal, private, and protected-only implementation details. Start with:

Download the SDK ​

Before starting a new SDK-based project, make sure you have the latest Crowd Control desktop app and the latest SDK build.

Download the latest SDK

Picking a connector ​

Choose the connector that matches how your game can communicate:

Minimal SimpleTCP pack ​

The SDK ships with a couple examples in its installation folder. Below is an example SimpleTCP game pack as this template is used prominently in most modern PC modded packs.

csharp
using ConnectorLib.SimpleTCP;
using CrowdControl.Common;
using ConnectorType = CrowdControl.Common.ConnectorType;

namespace CrowdControl.Games.Packs.YourGame;

public class YourGame : SimpleTCPPack<SimpleWebsocketServerConnector>
{
    public YourGame(
        UserRecord player,
        Func<CrowdControlBlock, bool> responseHandler,
        Action<object> statusUpdateHandler
    ) : base(player, responseHandler, statusUpdateHandler)
    {
    }

    public override Game Game => new(
        "Your Game",
        "YourGame",
        "PC",
        ConnectorType.SimpleWebsocketServerConnector
    );

    public override ushort Port => 28379;

    public override EffectList Effects => new Effect[]
    {
        new("Kill Player", "kill_player")
        {
            Price = 100,
            Description = "Kills the player.",
            Category = "Player",
        },
        new("Damage Player", "damage_player")
        {
            Price = 100,
            Quantity = 1..10,
            Description = "Damages the player.",
            Category = "Player",
        },
        new("Flip Screen", "flip_screen")
        {
            Price = 100,
            Duration = 30,
            Description = "Flips the screen for a short time.",
            Category = "Visual",
        },
    };
}

Defining effects ​

An Effect is an action that a viewer can trigger to occur within the game. This section will describe the metadata for effects, not the execution of them. Every effect needs:

  • a stable effect ID/code (should not change)
  • a viewer-facing name
  • a default price in US cents

Optionally, you can also add:

  • Description to explain what the effect does
  • Category to group effects together in the viewer's menu
  • Quantity for stackable effects
  • Duration for timed effects (in seconds)
  • Note when you need variants, such as "Host" VS "Random Player" in multiplayer games

Handling effects ​

The exact technical specifics of how to handle an effect depends on the connector, so please see the corresponding docs for your connector.

In general, your code should attempt to execute the effect, then report back within five seconds on whether:

  • the effect executed successfully
  • the effect failed, but the app should try to use it again in a few seconds
  • the effect failed, and it should not currently be retried
  • the effect failed because it is not known to exist and should not be purchasable

If an effect is cancelled goes for a minute without getting executed, then the Crowd Control app will reject the effect and refund the purchaser.

Timed effects should also report when they begin, pause, resume, and end.

Running a pack in the SDK ​

  1. Use Load Pack Source to load your .cs file.
  2. Select a Game Connector from the dropdown.
  3. Click Connect to start the connection.

Need help? ​

If you run into issues, join the community on Discord and open a private ticket.

Submitting a pack ​

If you want your pack publicly listed and supported, reach out on Discord with:

  • your CS file
  • any required mods, versions, or setup steps
  • anything special QA should know

Our team will review the integration, test it, and follow up with any issues or release requirements.

More on our release process: crowdcontrol.live/how-we-work