Skip to content

Client SDK (custom events)

Use custom events when you want to track gameplay or business logic that isn’t covered by default metrics, for example:

  • Quest progression
  • Economy actions (shop purchases, trades)
  • Minigame lifecycle (match start/end)
  • Prefer stable, low-cardinality names (e.g. minigame.match_end).
  • Put high-cardinality values (like player UUIDs) in the payload, not in event names.
  • Keep payloads small and consistent over time.

You can use the included AnalyticsClient provided by AnalyticsProvider.

In paper, it is accessible after ShardAnalytics plugin is enabled.

Example code
private AnalyticsClient analyticsClient;
@EventHandler
public void onServerLoad(ServerLoadEvent event) {
if (!Bukkit.getPluginManager().isPluginEnabled("ShardAnalytics"))
return;
analyticsClient = AnalyticsProvider.get();
}
public void onQuestComplete(PlayerQuestCompleteEvent event) {
Player player = event.getPlayer();
Location bukkitLocation = player.getLocation();
GameLocation gameLocation = new GameLocation(bukkitLocation.getWorld().getName(),
bukkitLocation.getBlockX(),
bukkitLocation.getBlockY(),
bukkitLocation.getBlockZ());
Quest quest = event.getQuest();
Map<String, Object> properties = new HashMap<>();
properties.put("quest_id", quest.getId());
properties.put("quest_name", quest.getName());
properties.put("completion_time", event.getCompletionTime());
analyticsClient.trackCustom("quest.complete", player.getUniqueId().toString(), gameLocation, properties);
}
public void onArenaEnd(ArenaEndEvent event) {
Arena arena = event.getArena();
Map<String, Object> properties = new HashMap<>();
properties.put("arena_id", arena.getId());
properties.put("arena_name", arena.getName());
properties.put("winning_team", event.getWinningTeam().getName());
analyticsClient.trackCustom("arena.end", null, null, properties);
}