Promotion background
Easter Season IS HERE!
10% off limited time offer!
Ends in
00
H
00
M
00
S
limited time offer SAVE 10% NOW โ†’
DEVELOPER ๐ŸŒ API

๐Ÿงช Examples

Practical examples of what you can and cannot do with the Phoenix Duels API.

triangle-exclamation

These examples target the public API package (com.phoenixplugins.phoenixduels.api.*).

#1) Track match start and phase transitions

import com.phoenixplugins.phoenixduels.api.events.MatchPhaseStartEvent;
import com.phoenixplugins.phoenixduels.api.events.MatchStartEvent;
import com.phoenixplugins.phoenixduels.api.match.MatchState;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public final class MatchLifecycleListener implements Listener {

    @EventHandler
    public void onStart(MatchStartEvent event) {
        if (event.getMatch().getTeamsPlayers().isEmpty()) {
            event.setCancelled(true);
        }
    }

    @EventHandler
    public void onPhase(MatchPhaseStartEvent event) {
        if (event.getNewState() == MatchState.ROUND_IN_PROGRESS) {
            // Start your per-round metrics.
        }
    }
}

#2) Capture kills and deaths

import com.phoenixplugins.phoenixduels.api.events.MatchPlayerDeathEvent;
import com.phoenixplugins.phoenixduels.api.events.MatchPlayerKillEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public final class CombatStatsListener implements Listener {

    @EventHandler
    public void onDeath(MatchPlayerDeathEvent event) {
        // event.getPlayer() died, event.getKiller() can be null.
    }

    @EventHandler
    public void onKill(MatchPlayerKillEvent event) {
        // Track kill streaks or challenge progress here.
    }
}

#3) Observe queue entry and exit

import com.phoenixplugins.phoenixduels.api.events.queue.ProfileQueueStartEvent;
import com.phoenixplugins.phoenixduels.api.events.queue.ProfileQueueStopEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public final class QueueMetricsListener implements Listener {

    @EventHandler
    public void onQueueStart(ProfileQueueStartEvent event) {
        int participants = event.getParticipants().size();
        String modeId = event.getProfile().getSelectedModeId();
    }

    @EventHandler
    public void onQueueStop(ProfileQueueStopEvent event) {
        // Store queue duration and stop reason in your analytics.
    }
}

#4) React to global ELO changes

import com.phoenixplugins.phoenixduels.api.events.PlayerGlobalEloChangeEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public final class EloChangeListener implements Listener {

    @EventHandler
    public void onGlobalElo(PlayerGlobalEloChangeEvent event) {
        int delta = event.getNewElo() - event.getOldElo();
        if (delta >= 50) {
            // Trigger your own reward or announcement pipeline.
        }
    }
}

#5) Handle party lifecycle events

import com.phoenixplugins.phoenixduels.api.events.party.PartyCreatedEvent;
import com.phoenixplugins.phoenixduels.api.events.party.PartyLeaderChangedEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public final class PartyListener implements Listener {

    @EventHandler
    public void onPartyCreated(PartyCreatedEvent event) {
        int slots = event.getParty().getMaximumSlots();
    }

    @EventHandler
    public void onLeaderChanged(PartyLeaderChangedEvent event) {
        // Sync your own group service with the new party leader.
    }
}

#6) Read match player state safely

import com.phoenixplugins.phoenixduels.api.events.MatchStartEvent;
import com.phoenixplugins.phoenixduels.api.match.players.MatchPlayer;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public final class MatchRosterListener implements Listener {

    @EventHandler
    public void onMatchStart(MatchStartEvent event) {
        for (MatchPlayer player : event.getMatch().getTeamsPlayers()) {
            if (player.isDisconnected()) {
                continue;
            }

            String name = player.getName();
            int kills = player.getKills();
            int deaths = player.getDeaths();
        }
    }
}

#7) Use profile data from queue events

import com.phoenixplugins.phoenixduels.api.events.queue.ProfileQueueStartEvent;
import com.phoenixplugins.phoenixduels.api.profiles.MatchProfile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public final class ProfileAuditListener implements Listener {

    @EventHandler
    public void onQueued(ProfileQueueStartEvent event) {
        MatchProfile profile = event.getProfile();
        boolean hasPending = profile.containsPendingParticipants();
        boolean hasOffline = profile.containsOfflineParticipants();

        if (hasPending || hasOffline) {
            profile.sendMessage("Your group is not fully ready yet.");
        }
    }
}

#8) Register your listener through plugin entrypoint

import com.phoenixplugins.phoenixduels.api.PhoenixDuelsAPI;
import org.bukkit.event.Listener;

public final class ListenerBootstrap {

    public void register(Listener listener) {
        PhoenixDuelsAPI.getPluginInstance().getEventBus().registerListener(listener);
    }
}

#9) Internal systemPath: register menus, commands, and rules

When you include the plugin JAR via systemPath, you can access internal registries. Because you are depending on the built plugin JAR, use the shaded package names exposed by that JAR.

import com.phoenixplugins.phoenixduels.lib.xseries.XMaterial;
import com.phoenixplugins.phoenixduels.registry.CommandsRegistry;
import com.phoenixplugins.phoenixduels.registry.MenuRegistry;
import com.phoenixplugins.phoenixduels.registry.RuleRegistry;
import com.phoenixplugins.phoenixduels.internal.Key;
import com.phoenixplugins.phoenixduels.sdk.platforms.server.commands.ServerCommand;
import com.phoenixplugins.phoenixduels.sdk.platforms.server.commands.ServerCommandManager;

import java.util.Collections;

public final class InternalBootstrap {

    public void load() throws Exception {
        MenuRegistry.getInstance().registerMenu(
                "my_custom_menu",
                new MyCustomMenu.MyCustomMenuConfiguration(),
                "menus/custom/my_custom_menu.yml",
                MyCustomMenu::new
        );

        CommandsRegistry.registerCommand(new ServerCommand("mymode") {
            @Override
            public boolean execute(ServerCommandManager manager,
                                   org.bukkit.command.CommandSender sender,
                                   String label,
                                   String[] args) {
                sender.sendMessage("Custom command executed.");
                return true;
            }
        }, true);

        RuleRegistry.registerRule(Key.of("MY_CUSTOM_RULE"), MyCustomRule::new,
            new RuleRegistry.RuleDetails(XMaterial.BLAZE_ROD, "My Custom Rule",
                Collections.singletonList("Example custom rule registered from addon.")));
    }
}

This internal path is powerful but version-sensitive, so lock your plugin version and retest after updates.

#What is not supported by API-only integrations

  • Do not cast API interfaces (Match, MatchProfile, Party) to internal implementation classes.
  • Do not depend on internal registries or core-only packages as your primary integration path.
  • Do not mutate internal state by reflection; rely on events and documented API methods.
  • Do not run heavy blocking logic in event handlers during match or queue events.
Last updated about 3 hours ago
My Cart (0 items)

Oops... looks like the spiders padded through here

Add products to your cart and remove them from here Lets buy
This site uses cookies to personalize content, enhance your experience. By continuing, you agree to our cookie use. Learn more