Matchbox provides a comprehensive API for server plugins to integrate with game sessions, manage events, and customize gameplay.
The Matchbox API allows you to:
- Create and manage game sessions programmatically
- Listen to game events (start, end, eliminations, etc.)
- Customize game configuration per session
- Integrate with minigame frameworks and arena systems
- Build custom chat processors and filters
Add Matchbox as a dependency in your pom.xml:
<dependency>
<groupId>com.ohacd</groupId>
<artifactId>matchbox</artifactId>
<version>0.9.5</version>
<scope>provided</scope>
</dependency>Add Matchbox as a dependency in your build.gradle:
dependencies {
compileOnly 'com.ohacd:matchbox:0.9.5'
}import com.ohacd.matchbox.api.MatchboxAPI;
import com.ohacd.matchbox.api.ApiGameSession;
import java.util.Optional;
// Create a new game session
Optional<ApiGameSession> session = MatchboxAPI.createSession("arena1")
.withPlayers(players)
.withSpawnPoints(spawnLocations)
.withDiscussionLocation(discussionArea)
.start();
if (session.isPresent()) {
// Session created successfully
ApiGameSession gameSession = session.get();
plugin.getLogger().info("Game started with " + gameSession.getTotalPlayerCount() + " players");
} else {
// Failed to create session
plugin.getLogger().warning("Failed to create game session");
}import com.ohacd.matchbox.api.events.*;
public class MyEventListener implements MatchboxEventListener {
@Override
public void onGameStart(GameStartEvent event) {
// Game has started
String sessionName = event.getSessionName();
Collection<Player> players = event.getPlayers();
// Send custom messages, update scoreboards, etc.
Bukkit.broadcastMessage("Game " + sessionName + " has started!");
}
@Override
public void onGameEnd(GameEndEvent event) {
// Game has ended
GameEndEvent.EndReason reason = event.getReason();
Map<Player, Role> finalRoles = event.getFinalRoles();
// Award points, update statistics, etc.
handleGameEnd(event.getSessionName(), reason, finalRoles);
}
@Override
public void onPlayerEliminate(PlayerEliminateEvent event) {
// A player was eliminated
Player eliminated = event.getPlayer();
Role role = event.getRole();
PlayerEliminateEvent.EliminationReason reason = event.getReason();
// Update player stats, send messages, etc.
plugin.getLogger().info(eliminated.getName() + " was eliminated as " + role);
}
}
// Register the listener
@Override
public void onEnable() {
MatchboxAPI.addEventListener(new MyEventListener());
}import com.ohacd.matchbox.api.GameConfig;
// Create custom game configuration
GameConfig customConfig = GameConfig.builder()
.swipeDuration(180) // 3 minutes
.discussionDuration(120) // 2 minutes
.votingDuration(60) // 1 minute
.sparkAbility("hunter_vision") // Always use Hunter Vision
.randomSkins(false) // Disable random skins
.build();
// Create session with custom config
Optional<ApiGameSession> session = MatchboxAPI.createSession("custom_game")
.withPlayers(players)
.withSpawnPoints(spawns)
.withCustomConfig(customConfig)
.start();Main entry point for all API operations.
Key Methods:
createSession(String name)— Create a new session buildergetSession(String name)— Get an active session by namegetPlayerSession(Player player)— Get the session a player is ingetPlayerRole(Player player)— Get a player's rolegetAllSessions()— Get all active sessionsendSession(String name)— End a specific sessionendAllSessions()— End all active sessionsaddEventListener(MatchboxEventListener listener)— Register event listenerremoveEventListener(MatchboxEventListener listener)— Unregister event listener
Fluent builder for creating game sessions.
Key Methods:
withPlayers(Collection<Player>)— Set initial playerswithSpawnPoints(List<Location>)— Set spawn locationswithDiscussionLocation(Location)— Set discussion areawithSeatLocations(Map<Integer, Location>)— Set discussion seatswithCustomConfig(GameConfig)— Apply custom configurationstart()— Start the session (returns Optional)
Wrapper for active game sessions.
Key Methods:
getName()— Get session nameisActive()— Check if session is activegetCurrentPhase()— Get current game phasegetCurrentRound()— Get current round numbergetPlayers()— Get all players in sessiongetAlivePlayerCount()— Get count of alive playersgetTotalPlayerCount()— Get total player countaddPlayer(Player)— Add a player to the sessionremovePlayer(Player)— Remove a player from the sessionendGame()— End the game session
Configuration builder for custom game settings.
Key Methods:
swipeDuration(int seconds)— Set swipe phase durationdiscussionDuration(int seconds)— Set discussion phase durationvotingDuration(int seconds)— Set voting phase durationsparkAbility(String ability)— Set Spark ability (random, hunter_vision, spark_swap, delusion)randomSkins(boolean enabled)— Enable/disable random skinsbuild()— Build the configuration
- GameStartEvent — Game initialization
- GameEndEvent — Game completion (with end reason)
- PhaseChangeEvent — Phase transitions
- PlayerJoinEvent — Player joins session
- PlayerLeaveEvent — Player leaves session
- PlayerEliminateEvent — Player elimination (with reason)
- PlayerVoteEvent — Voting actions
- AbilityUseEvent — Special ability usage
- SwipeEvent — Spark attack actions
- CureEvent — Medic healing actions
Implement MatchboxEventListener and override methods for events you care about:
public interface MatchboxEventListener {
default void onGameStart(GameStartEvent event) {}
default void onGameEnd(GameEndEvent event) {}
default void onPhaseChange(PhaseChangeEvent event) {}
default void onPlayerJoin(PlayerJoinEvent event) {}
default void onPlayerLeave(PlayerLeaveEvent event) {}
default void onPlayerEliminate(PlayerEliminateEvent event) {}
default void onPlayerVote(PlayerVoteEvent event) {}
default void onAbilityUse(AbilityUseEvent event) {}
default void onSwipe(SwipeEvent event) {}
default void onCure(CureEvent event) {}
}Custom chat processors for filtering and routing chat messages:
import com.ohacd.matchbox.api.chat.*;
public class CustomChatProcessor implements ChatProcessor {
@Override
public ChatProcessingResult process(ChatMessage message) {
// Add custom formatting
Component modified = Component.text("[GAME] ")
.append(message.formattedMessage());
return ChatProcessingResult.allowModified(
message.withFormattedMessage(modified)
);
}
}
// Register the processor
MatchboxAPI.registerChatProcessor("arena1", new CustomChatProcessor());// End all sessions (useful for server maintenance)
int endedCount = MatchboxAPI.endAllSessions();
plugin.getLogger().info("Ended " + endedCount + " game sessions");public class ArenaManager {
private final Map<String, ApiGameSession> activeSessions = new HashMap<>();
public boolean startArena(String arenaName, Collection<Player> players) {
Arena arena = getArena(arenaName);
Optional<ApiGameSession> session = MatchboxAPI.createSession(arenaName)
.withPlayers(players)
.withSpawnPoints(arena.getSpawns())
.withDiscussionLocation(arena.getDiscussion())
.withSeatLocations(arena.getSeats())
.start();
session.ifPresent(s -> activeSessions.put(arenaName, s));
return session.isPresent();
}
public void stopArena(String arenaName) {
ApiGameSession session = activeSessions.remove(arenaName);
if (session != null) {
session.endGame();
}
}
}For comprehensive API documentation with detailed examples, advanced usage patterns, and best practices, see:
MatchboxAPI_Docs.md in the repository.
This includes:
- Detailed method documentation
- Arena integration examples
- Event-driven minigame integration
- Multi-arena management
- Thread safety guidelines
- Migration guides
- Join our Discord
- Check the Developer Notes page
- Review example code in MatchboxAPI_Docs.md
See the Contributing page for information on submitting API improvements or bug fixes.