Sign In

Event Tracking

Track custom player actions in your plugin. Events appear in your dashboard for analysis, segmentation, and funnel building.

Basic Usage

import net.analyse.api.Analyse;
Analyse.trackEvent("event_name")
.withPlayer(player.getUniqueId(), player.getName())
.send();

Event Builder

The EventBuilder provides a fluent API for constructing events.

With Player

Associate an event with a specific player:

Analyse.trackEvent("joined_arena")
.withPlayer(player.getUniqueId(), player.getName())
.send();

With Data

Add contextual properties to your event:

Analyse.trackEvent("crate_opened")
.withPlayer(player.getUniqueId(), player.getName())
.withData("crate_type", "legendary")
.withData("location", "spawn")
.withData("keys_remaining", 5)
.send();

With Value

Include a numeric value for aggregations (sum, average, etc.):

Analyse.trackEvent("coins_earned")
.withPlayer(player.getUniqueId(), player.getName())
.withData("source", "mob_kill")
.withValue(150.0)
.send();

With Callback

Get notified when the event is sent:

Analyse.trackEvent("purchase_completed")
.withPlayer(player.getUniqueId(), player.getName())
.withData("item", "vip_rank")
.withValue(9.99)
.send(success -> {
if (success) {
player.sendMessage("Purchase tracked!");
}
});

Complete Example

public class CrateListener implements Listener {
@EventHandler
public void onCrateOpen(CrateOpenEvent event) {
Player player = event.getPlayer();
Crate crate = event.getCrate();
ItemStack reward = event.getReward();
// Track the crate open with full context
Analyse.trackEvent("crate_opened")
.withPlayer(player.getUniqueId(), player.getName())
.withData("crate_type", crate.getType().name())
.withData("crate_location", formatLocation(crate.getLocation()))
.withData("reward_item", reward.getType().name())
.withData("reward_rarity", getRarity(reward))
.withValue(crate.getValue())
.send();
}
}

Event Naming Conventions

Use snake_case for consistent, readable event names:

✅ Good❌ Bad
quest_completedQuestCompleted
crate_openedcrateOpened
pvp_killPVP Kill
shop_purchaseshop-purchase

Track events that help you understand player behavior:

Progression

Analyse.trackEvent("tutorial_completed")
.withPlayer(player.getUniqueId(), player.getName())
.withData("duration_seconds", duration)
.send();
Analyse.trackEvent("level_up")
.withPlayer(player.getUniqueId(), player.getName())
.withData("new_level", level)
.withData("class", playerClass)
.send();

Economy

Analyse.trackEvent("coins_earned")
.withPlayer(player.getUniqueId(), player.getName())
.withData("source", "quest_reward")
.withValue(amount)
.send();
Analyse.trackEvent("coins_spent")
.withPlayer(player.getUniqueId(), player.getName())
.withData("item", itemName)
.withValue(price)
.send();

Combat

Analyse.trackEvent("pvp_kill")
.withPlayer(killer.getUniqueId(), killer.getName())
.withData("victim", victim.getName())
.withData("weapon", weapon.getType().name())
.withData("arena", arenaName)
.send();

Social

Analyse.trackEvent("party_created")
.withPlayer(leader.getUniqueId(), leader.getName())
.withData("party_size", size)
.send();

Best Practices

Don't Over-Track

Track events you'll actually analyze. Avoid tracking every minor action.

// ✅ Good - meaningful event
Analyse.trackEvent("boss_killed")
.withPlayer(player.getUniqueId(), player.getName())
.withData("boss", "ender_dragon")
.send();
// ❌ Bad - too granular
Analyse.trackEvent("block_broken") // Millions of events, little insight
.withPlayer(player.getUniqueId(), player.getName())
.send();

Include Useful Context

Properties enable segmentation and filtering in your dashboard.

// ❌ Bad - no context
Analyse.trackEvent("item_purchased").send();
// ✅ Good - rich context
Analyse.trackEvent("item_purchased")
.withPlayer(player.getUniqueId(), player.getName())
.withData("item_id", item.getId())
.withData("item_category", item.getCategory())
.withData("payment_method", "coins")
.withValue(item.getPrice())
.send();

Track Pairs for Funnels

Track both start and completion for measuring conversion:

// When player starts
Analyse.trackEvent("quest_started")
.withPlayer(player.getUniqueId(), player.getName())
.withData("quest_id", quest.getId())
.send();
// When player completes
Analyse.trackEvent("quest_completed")
.withPlayer(player.getUniqueId(), player.getName())
.withData("quest_id", quest.getId())
.withData("duration_minutes", duration)
.send();

Error Handling

Events are sent asynchronously and won't block your main thread. If Analyse isn't available, methods fail gracefully:

// Safe to call even if Analyse isn't installed
if (Analyse.isAvailable()) {
Analyse.trackEvent("my_event")
.withPlayer(player.getUniqueId(), player.getName())
.send();
}

Next Steps