Client SDK (custom events)
When to use custom events
Section titled “When to use 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)
Event design guidelines
Section titled “Event design guidelines”- 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.
Sending an event
Section titled “Sending an event”You can use the included AnalyticsClient provided by AnalyticsProvider.
In paper, it is accessible after ShardAnalytics plugin is enabled.
private AnalyticsClient analyticsClient;
@EventHandlerpublic 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);}