# API Reference The Observer API allows third-party plugins to hook into Observer's event management systems. The API module provides interfaces, data classes, events, and exceptions for interacting with all major Observer subsystems. --- ## Maven Dependency Observer-API is hosted on JitPack. Add the following to your `pom.xml`: ```xml <repositories> <repository> <id>jitpack.io</id> <url>https://jitpack.io</url> </repository> </repositories> <dependencies> <dependency> <groupId>com.github.Lodestones</groupId> <artifactId>Observer-API</artifactId> <version>1.0.64</version> <scope>provided</scope> </dependency> </dependencies> ``` ### Gradle (Groovy) ```groovy repositories { maven { url 'https://jitpack.io' } } dependencies { compileOnly 'com.github.Lodestones:Observer-API:1.0.64' } ``` ### Gradle (Kotlin DSL) ```kotlin repositories { maven("https://jitpack.io") } dependencies { compileOnly("com.github.Lodestones:Observer-API:1.0.64") } ``` --- ## Accessing the API The static entry point for the Observer API is `ObserverAPI.getApi()`. This returns an `IObserverAPI` instance once Observer has been loaded on the server. ```java import gg.lode.observerapi.ObserverAPI; import gg.lode.observerapi.IObserverAPI; IObserverAPI api = ObserverAPI.getApi(); ``` Ensure your plugin declares Observer as a dependency (or soft dependency) in `plugin.yml` so Observer loads first: ```yaml depend: - Observer ``` --- ## IObserverAPI Interface The core API interface provides access to all manager instances and game state control. ```java public interface IObserverAPI { ICapsuleManager getCapsuleManager(); ICustomRecipesManager getCustomRecipesManager(); IDecayManager getDecayManager(); IEliminationManager getEliminationManager(); ILateScatterManager getLateScatterManager(); ILifestealManager getLifestealManager(); IMechanicsManager getMechanicsManager(); IPedestalManager getPedestalManager(); IPlayerManager getPlayerManager(); IRespawnManager getRespawnManager(); ITranslationManager getTranslationManager(); IWorldEventManager getWorldEventManager(); IHelpOpManager getHelpOpManager(); IKitManager getKitManager(); void setGameState(Player player, GameState gameState); void setGameState(GameState gameState); GameState getGameState(); double getBaseHealth(); void setBaseHealth(double baseHealth); World getLobbyWorld(); World getEventWorld(); } ``` ### Game State Observer manages three game states defined in the `GameState` enum: | State | Description | |---|---| | `IN_LOBBY` | Players are in the lobby world awaiting the event start. | | `PRE_GAME` | The event is being prepared (capsule assignment, countdown, etc.). | | `IN_GAME` | The event is actively running. | ```java // Get current state GameState current = api.getGameState(); // Change state (fires PreGameStateChangeEvent) api.setGameState(player, GameState.IN_GAME); // Change state silently (no PreGameStateChangeEvent) api.setGameState(GameState.IN_LOBBY); ``` --- ## Custom Events Observer fires custom Bukkit events at key lifecycle points. Cancellable events implement `Cancellable`. ### Game State Events | Event | Cancellable | Description | |---|---|---| | `PreGameStateChangeEvent` | Yes | Fired before a game state transition. Allows setting a tick delay. | | `GameStateChangeEvent` | No | Fired after a game state transition has completed. | ```java @EventHandler public void onPreStateChange(PreGameStateChangeEvent event) { GameState oldState = event.getOldState(); GameState newState = event.getNewState(); Player source = event.getSource(); // nullable // Add a 100-tick delay before the state change event.setTickDelay(100); // Or cancel it entirely event.setCancelled(true); } @EventHandler public void onStateChange(GameStateChangeEvent event) { if (event.getNewState() == GameState.IN_GAME) { // Game has started } } ``` ### Elimination Events | Event | Cancellable | Description | |---|---|---| | `PlayerEliminatedEvent` | Yes | Fired when a player is eliminated. Provides access to the killer, death message, drops, and the original `PlayerDeathEvent`. | ```java @EventHandler public void onElimination(PlayerEliminatedEvent event) { Player eliminated = event.getPlayer(); LivingEntity killer = event.getKiller(); // nullable // Modify the death message event.setDeathMessage(Component.text("Custom death message")); // Modify drops event.setDrops(new ArrayList<>()); } ``` ### Lifesteal Events | Event | Cancellable | Description | |---|---|---| | `PlayerConsumeHeartEvent` | Yes | Fired when a player consumes a heart item. | | `PlayerWithdrawHeartEvent` | Yes | Fired when a player withdraws a heart via `/withdraw`. | ### Capsule Events | Event | Cancellable | Description | |---|---|---| | `PlayerAssignedToCapsuleEvent` | Yes | Fired when a player is assigned to a capsule. | | `PlayerSwapCapsulesEvent` | Yes | Fired when two players swap capsule assignments. | ### Pedestal Events | Event | Cancellable | Description | |---|---|---| | `PrePedestalCraftEvent` | Yes | Fired before a pedestal craft begins. | | `PedestalCraftEvent` | No | Fired after a pedestal craft completes. | | `PedestalLoadEvent` | No | Fired when a pedestal is loaded. | ### Recipe Events | Event | Cancellable | Description | |---|---|---| | `PlayerCraftRecipeEvent` | Yes | Fired when a player crafts a custom recipe. | ### World Events | Event | Cancellable | Description | |---|---|---| | `StartWorldEvent` | Yes | Fired when a world event is activated. | | `EndWorldEvent` | Yes | Fired when a world event is deactivated. | ### Player Events | Event | Cancellable | Description | |---|---|---| | `PlayerJoinFirstTimeEvent` | No | Fired the first time a player joins during an event. | | `PlayerReviveEvent` | Yes | Fired when a player is revived. | --- ## Data Classes ### Capsule ```java public record Capsule(UUID uniqueId, Location location, @Nullable String teamId) {} ``` Represents a spawn capsule with a unique ID, world location, and optional team assignment (requires Lead). ### RespawnData ```java public record RespawnData( String id, String timestamp, String name, String savedBy, byte[] contents, double health, int foodLevel, float saturation, float experience, int level, double absorption, int fireTicks, List<String> potionEffects, Location location ) {} ``` A complete snapshot of a player's state used by the respawn and kit systems. ### PedestalData ```java public record PedestalData( String id, Location position, List<ItemStack> ingredients, ItemStack result, int maxUses, float itemHeight, PedestalType pedestalType, HashMap<UUID, Integer> uses ) {} ``` Represents a pedestal crafting station with its recipe, position, and usage tracking. ### WorldEvent A data class representing a custom world event with an ID, icon material, translation ID, and a list of commands to execute on activation. ### Translation ```java public record Translation( @Nullable String tellraw, @Nullable Title title, @Nullable SoundTranslation soundTranslation, List<String> commands ) {} ``` A translation entry that can be sent to individual players via `send(Player)` or broadcast to all players via `broadcast()`. --- ## Enums | Enum | Values | Description | |---|---|---| | `GameState` | `IN_LOBBY`, `PRE_GAME`, `IN_GAME` | Current phase of the event lifecycle. | | `CapsuleType` | `BATTLE_ROYALE`, `CIVILIZATION`, `WORLD_SPAWN` | Capsule spawning strategy. | | `LifestealType` | `ANYTIME`, `DROP`, `CONSUME`, `OBTAIN` | When lifesteal hearts are distributed. | | `PedestalType` | `SINGLE_USE`, `PER_PLAYER`, `REUSABLE` | How pedestal usage is limited. | --- ## Exceptions The API defines specific exceptions for error handling: | Exception | Description | |---|---| | `AlreadyInGameModeException` | Thrown when attempting to enter IN_GAME while already in that state. | | `AlreadyInLobbyModeException` | Thrown when attempting to enter IN_LOBBY while already in that state. | | `AlreadyInPreGameModeException` | Thrown when attempting to enter PRE_GAME while already in that state. | | `InsufficientPlayersException` | Thrown when there are not enough players to start. | | `InsufficientTeamsException` | Thrown when there are not enough teams to start. | | `LeadNotInstalledException` | Thrown when a team operation requires Lead but it is not installed. | | `NotInLobbyModeException` | Thrown when an operation requires IN_LOBBY state. | | `NotInPreGameModeException` | Thrown when an operation requires PRE_GAME state. | | `PlayerOverflowException` | Thrown when more players than capsules are available. | | `TeamOverflowException` | Thrown when more teams than capsules are available. | | `RecipeAddException` | Thrown when a custom recipe cannot be registered. | --- ## Player Data Access player data through `IPlayerManager`: ```java IPlayerManager playerManager = api.getPlayerManager(); // Online player data IPlayerData data = playerManager.getPlayerData(player); boolean inCombat = data.inCombat(); boolean isInLobby = data.isInLobbyMode(); boolean isDead = data.isDead(); String team = data.getBindedTeam(); // Offline player data IOfflinePlayerData offlineData = playerManager.getPlayerData(uuid); boolean wasEliminated = offlineData.isMarkedAsDead(); boolean wasSittingOut = offlineData.isSittingOut(); String region = offlineData.getRegion(); ``` --- ## Related Pages - [[Observer/Developers/Overview]] - Developer overview - [[Systems]] - Detailed system breakdowns