New: see how many SpigotMC listing viewers end up running your plugin →
DocsProxies & mods

Proxies & mods

The same SDK and dashboard for proxy plugins and mods: one artifact per platform, the same calls, and the platform's own types.

Updated · by Skilled

One artifact per platform

PlatformArtifactStart it
Spigot, Paper, Purpur, Foliapluginanalytics-bukkitPluginAnalytics.start(this, key) in onEnable
Velocitypluginanalytics-velocityPluginAnalytics.start(this, server, dataDirectory, key) on ProxyInitializeEvent
BungeeCord, Waterfallpluginanalytics-bungeePluginAnalytics.start(this, key) in onEnable, analytics.stop() in onDisable
Fabric (servers and games)pluginanalytics-fabricPluginAnalytics.start("yourmodid", key) in onInitialize
NeoForge (servers and games)pluginanalytics-neoforgePluginAnalytics.start("yourmodid", key) in your @Mod constructor

All of them use the repository, version and relocation from Installation: change only the artifact name. Relocation is required everywhere. The class is always PluginAnalytics, and track, property, time, captureError, excludeConfig and the rest work the same.

Velocity

// build.gradle.kts: implementation("com.gamepathics:pluginanalytics-velocity:1.7.0")
@Plugin(id = "partyplus", name = "PartyPlus", version = "1.0.0")
public final class PartyPlus {
    private final ProxyServer server;
    private final Path dataDirectory;
    private PluginAnalytics analytics;

    @Inject
    public PartyPlus(ProxyServer server, @DataDirectory Path dataDirectory) {
        this.server = server;
        this.dataDirectory = dataDirectory;
    }

    @Subscribe
    public void onInit(ProxyInitializeEvent e) {
        analytics = PluginAnalytics.start(this, server, dataDirectory, "pa_your_key");
    }

    void createParty(Player leader) {
        analytics.track("party_created", leader);
    }
}

It stops by itself when the proxy shuts down. Velocity 3.5 and later (Java 21) are supported.

BungeeCord and Waterfall

// build.gradle.kts: implementation("com.gamepathics:pluginanalytics-bungee:1.7.0")
public final class PartyPlus extends Plugin {
    private PluginAnalytics analytics;

    @Override
    public void onEnable() {
        analytics = PluginAnalytics.start(this, "pa_your_key");
    }

    @Override
    public void onDisable() {
        analytics.stop(); // BungeeCord has no "plugin disabled" event: this sends the last batch
    }
}

Fabric

// build.gradle.kts: implementation("com.gamepathics:pluginanalytics-fabric:1.7.0"), shaded and relocated
public final class SkyIslands implements ModInitializer {
    public static PluginAnalytics analytics;

    @Override
    public void onInitialize() {
        analytics = PluginAnalytics.start("skyislands", "pa_your_key");
    }
}

// anywhere: a player is their UUID
SkyIslands.analytics.track("island_created", player.getUuid());

The SDK doesn't depend on Minecraft classes, so one version works on every Minecraft version Fabric runs. On dedicated servers, player joins, the server thread (for Performance) and player counts come from Fabric API when it's installed; without it, your own track calls still work.

NeoForge

// build.gradle.kts: implementation("com.gamepathics:pluginanalytics-neoforge:1.7.0"), shaded and relocated
@Mod("skyislands")
public final class SkyIslands {
    public static PluginAnalytics analytics;

    public SkyIslands() {
        analytics = PluginAnalytics.start("skyislands", "pa_your_key");
    }
}

Mods in players' games

The Fabric and NeoForge SDKs also run on the client. There, every install of the game is one anonymous "server" in your dashboard (shown as Fabric (client) or NeoForge (client)), and every player event belongs to that install:

  • Nothing identifies the player: no name, account, UUID or IP. The install is a random id with its own salt.
  • Data goes out over HTTPS every 30 minutes and when the game closes, never over a held-open connection.
  • Players turn it off for every mod in config/pluginanalytics.yml (enabled: false).
  • Say in your mod's description that it collects anonymous usage statistics. Modrinth asks for a "Contains telemetry" disclosure.

Each active install counts toward your plan like a server does.

What each platform supports

BukkitVelocity, BungeeCordFabric, NeoForge serversGames (clients)
Servers, versions, players✓✓ (the proxy and its players)✓✓ (one install, one player)
Events, properties, funnels, retention✓✓✓✓
Errors and logs✓✓✓✓
Config usageconfig.ymlconfig.yml, .toml or .json in the data folderconfig/<modid>.json, .toml, .properties or .ymlsame as servers
Performance by method✓ (not Folia)spans only (no main thread)✓ with Fabric API / on NeoForgespans only
Automatic command events and timing✓–––
Update noticesconsole and admins in gameconsole and players with the notify permissionconsole (and operators in game on NeoForge)log
Bug reports and ideas/<plugin> report|suggest, or report()report() and suggest() from your commandsreport() and suggest()report() and suggest()