A/B Testing SDK
Run experiments directly in your plugin code. Assign players to variants, show different experiences, and track which performs best.
Quick Start
import net.analyse.api.Analyse;// Get the player's assigned variantString variant = Analyse.getVariant(player.getUniqueId(), "welcome-rewards");// Show the appropriate experienceswitch (variant) {case "control":give(player, new ItemStack(Material.BREAD, 16));break;case "diamonds":give(player, new ItemStack(Material.DIAMOND, 5));break;case "tools":giveStarterTools(player);break;}// Track when they convertAnalyse.trackConversion(player.getUniqueId(),player.getName(),"welcome-rewards","played_one_hour");
Creating Experiments
Before using the SDK, create your experiment in the dashboard:
- Go to A/B Tests in your project
- Click "New Experiment"
- Configure:
- Name: "Welcome Rewards"
- Key:
welcome-rewards(use this in your code) - Variants: control (50%), diamonds (25%), tools (25%)
- Primary Metric:
played_one_hour
- Click "Create" and activate when ready
Getting Variants
Basic Usage
String variant = Analyse.getVariant(player.getUniqueId(), "experiment-key");
Returns:
- The variant key (e.g.,
"control","variant-a") nullif the test doesn't exist or isn't active
Deterministic Assignment
The same player always gets the same variant:
// First callString variant1 = Analyse.getVariant(uuid, "my-test"); // "control"// Second call (same player, any time later)String variant2 = Analyse.getVariant(uuid, "my-test"); // "control"// Always the same!assert variant1.equals(variant2);
With Fallback
Handle cases where the test isn't active:
String variant = Analyse.getVariant(player.getUniqueId(), "spawn-location");if (variant == null) {variant = "default"; // Fallback}switch (variant) {case "spawn-a":teleport(player, spawnA);break;case "spawn-b":teleport(player, spawnB);break;default:teleport(player, defaultSpawn);}
Tracking Conversions
Track when a player completes your experiment's goal:
Analyse.trackConversion(player.getUniqueId(),player.getName(),"experiment-key","conversion-event-name");
Example: First Purchase
// In your purchase handler@EventHandlerpublic void onPurchase(PlayerPurchaseEvent event) {Player player = event.getPlayer();// Track conversion for active experimentsAnalyse.trackConversion(player.getUniqueId(),player.getName(),"welcome-rewards","first_purchase");}
Example: Retention
// When player reaches 1 hour playtimepublic void onOneHourPlayed(Player player) {Analyse.trackConversion(player.getUniqueId(),player.getName(),"onboarding-flow","played_one_hour");}
Checking Test Status
Is Test Active?
if (Analyse.isTestActive("my-experiment")) {// Apply experiment logic} else {// Use default behavior}
Get Test Details
ABTest test = Analyse.getTest("welcome-rewards");if (test != null) {System.out.println("Test: " + test.getName());System.out.println("Status: " + test.getStatus());System.out.println("Variants: " + test.getVariants().size());}
List All Active Tests
List<? extends ABTest> activeTests = Analyse.getActiveTests();for (ABTest test : activeTests) {System.out.println(test.getKey() + " - " + test.getName());}
Complete Example
public class WelcomeListener implements Listener {@EventHandlerpublic void onPlayerJoin(PlayerJoinEvent event) {Player player = event.getPlayer();// Skip if not a new playerif (player.hasPlayedBefore()) {return;}// Get variant assignmentString variant = Analyse.getVariant(player.getUniqueId(), "new-player-kit");if (variant == null) {variant = "basic"; // Default if test inactive}// Apply the variantswitch (variant) {case "basic":giveBasicKit(player);player.sendMessage("Welcome! Here's a starter kit.");break;case "premium":givePremiumKit(player);player.sendMessage("Welcome! Enjoy this premium starter kit!");break;case "guided":giveBasicKit(player);startTutorial(player);player.sendMessage("Welcome! Let me show you around.");break;}}// Track conversion when player reaches level 10@EventHandlerpublic void onLevelUp(PlayerLevelUpEvent event) {if (event.getNewLevel() == 10) {Player player = event.getPlayer();Analyse.trackConversion(player.getUniqueId(),player.getName(),"new-player-kit","reached_level_10");}}}
ABTestManager
For advanced usage, access the manager directly:
ABTestManager manager = Analyse.abTests();// Get all active testsList<? extends ABTest> tests = manager.getActiveTests();// Get specific testABTest test = manager.getTest("my-test");// Get variant for playerString variant = manager.getVariant(uuid, "my-test");// Track conversionmanager.trackConversion(uuid, username, "my-test", "purchased");
Test Triggers
Experiments can have different triggers configured in the dashboard:
| Trigger | When Applied |
|---|---|
FIRST_JOIN | Only on player's first join |
EVERY_JOIN | On every join |
ON_COMMAND | When player runs a command |
ON_EVENT | When a specific event fires |
Check trigger in code:
ABTest test = Analyse.getTest("my-test");if (test.matchesTrigger(ABTest.Trigger.FIRST_JOIN)) {// Only apply on first join}
Best Practices
1. Always Handle Null Variants
String variant = Analyse.getVariant(uuid, "test");if (variant == null) {// Test not active - use default behaviorreturn;}
2. Keep Variants Simple
Test one thing at a time for clear results:
// ✅ Good - one variableString color = Analyse.getVariant(uuid, "button-color");// "red", "blue", or "green"// ❌ Bad - multiple variables in one testString combo = Analyse.getVariant(uuid, "ui-changes");// "red-large-animated" - hard to know what's working
3. Track Meaningful Conversions
// ✅ Good - clear business valueAnalyse.trackConversion(uuid, name, "onboarding", "made_purchase");Analyse.trackConversion(uuid, name, "onboarding", "returned_day_2");// ❌ Bad - vanity metricAnalyse.trackConversion(uuid, name, "onboarding", "clicked_button");
4. Don't Change Mid-Session
Apply variant once, store the result:
// ✅ Good - store variantString variant = Analyse.getVariant(uuid, "shop-layout");playerData.setShopVariant(variant);// Later, use stored valueopenShop(player, playerData.getShopVariant());