SDK
Custom events
Send any custom event from your plugin with properties you care about.
Custom events are how you teach Analyse about the things that make your server unique. The SDK has a small fluent builder for them.
Quick example
java
import net.analyse.api.Analyse;public class QuestListener implements Listener {@EventHandlerpublic void onQuestComplete(QuestCompleteEvent event) {Player player = event.getPlayer();Analyse.trackEvent("quest_completed").withPlayer(player.getUniqueId(), player.getName()).withData("quest_id", event.getQuestId()).withData("difficulty", event.getDifficulty()).withValue(event.getRewardValue()).send();}}
That's it. Every time a quest completes, Analyse gets an event with the quest ID, difficulty, and reward value, linked to the player.
The builder
java
Analyse.trackEvent(String name).withPlayer(UUID uuid, String username).withData(String key, Object value).withData(Map<String, Object> values).withValue(double value).send();
nameis the event name. Lowercase with underscores:quest_completed,first_kill,crate_opened.withPlayerlinks the event to a player. Optional but almost always useful.withDataadds a property. Call it as many times as you want.withValueis a numeric "main metric" for the event (reward amount, damage dealt, price paid). Used for sum/average widgets in Dashboards.sendfires the event. Fire-and-forget.
Rules
- Name stability matters. Don't rename events. If you have to, treat it as a new event and keep the old name for a while.
- Limit properties. 10 or fewer per event is the sweet spot. Overdoing it makes filtering confusing.
- Primitive values only. Numbers, booleans, strings. Objects are stringified which is rarely what you want.
- Don't send PII. No email, no IP, no real names. Minecraft username and UUID are fine.
- Run off-thread if your event handler is performance-sensitive.
send()is non-blocking but event bodies can be large.
Checking availability
If your plugin should also work when Analyse is missing, wrap the calls:
java
if (Analyse.isAvailable()) {Analyse.trackEvent("quest_completed").withPlayer(player.getUniqueId(), player.getName()).send();}
Or if you want to silently skip when the API is not ready:
java
try {Analyse.trackEvent("quest_completed").withPlayer(player.getUniqueId(), player.getName()).send();} catch (IllegalStateException ignored) {// Analyse not initialized yet, that's fine}
Good events to add first
tutorial_finishedwithduration_seconds,skipped_stepsfirst_killwithweapon,target_typerank_activatedwithrank_name,pricestore_viewedwithsource(what triggered the open)match_finishedwithresult,duration_seconds
See Custom events for the product-side view and Funnels for using them as steps.
Events from a backend (with a proxy)
If you run Velocity or BungeeCord in front of your backends, and you want a backend to send events through the proxy, use AnalyseMessaging. See Plugin messaging.