File Details
BetterLootBox-4.2.5.jar
- R
- Apr 23, 2026
- 5.40 MB
- 250
- Early Access
File Name
BetterLootBox-4.2.5.jar
Supported Versions
- Early Access
New PUBLIC API ADDED:
GilloDaby
gillodaby
Invisible
<main class="chatContent_f75fb0" aria-label="dev (channel)">
<form class="form_f75fb0 formWithLoadedChatInput_f75fb0">
</form></main>
-
AIR [AURA], <time id="message-timestamp-1496709547673518130" datetime="2026-04-23T03:09:23.684Z"> — Yesterday at 11:09 PM</time>
big brain player -
understood it within a few hours
-
AIR [AURA], <time id="message-timestamp-1496767716206317628" datetime="2026-04-23T07:00:32.143Z"> — 3:00 AM</time>
@damven without mmo skills -
note enchants also amp it like crazy
-
the dmg can get crazy if u stack various mods <some weapons> * <Endless> * <Enchants> * <MMO>
-
idk if u have anything else that modifies the dmg
-
AIR [AURA], <time id="message-timestamp-1496796657931518032" datetime="2026-04-23T08:55:32.388Z"> — 4:55 AM</time>

-
GilloDaby
<time id="message-timestamp-1496886730995798168" datetime="2026-04-23T14:53:27.480Z"> — 10:53 AM</time>
I like so much your ui -
I need to step up...
-
AIR [AURA], <time id="message-timestamp-1496956289140523028" datetime="2026-04-23T19:29:51.434Z"> — 3:29 PM</time>

-
AIR [AURA], <time id="message-timestamp-1496963393347911743" datetime="2026-04-23T19:58:05.209Z"> — 3:58 PM</time>
oh i need an api event when you open an event -
so i can make an augment for ur mod LOL
-
GilloDaby
<time id="message-timestamp-1496964145449533481" datetime="2026-04-23T20:01:04.524Z"> — 4:01 PM</time>
open a lootbox? -
AIR [AURA], <time id="message-timestamp-1496964206631846049" datetime="2026-04-23T20:01:19.111Z"> — 4:01 PM</time>
ye -
when that event fires, i can link it with my mod
-
GilloDaby
<time id="message-timestamp-1496964384482656457" datetime="2026-04-23T20:02:01.514Z"> — 4:02 PM</time>
sure -
I will add
-
I never add some
-
since no one really asked
-
api for a lootbox x)
-
Gambler augment
-
@AIR I'm doing it right now! Will send you the updated jar before the release so you will be able to try!
-
GilloDaby
<time id="message-timestamp-1496968156525101069" datetime="2026-04-23T20:17:00.839Z"> — 4:17 PM</time>
Do you have all what you might need? I did that in 10 minutes so I hope it's fine <time datetime="2026-04-23T20:18:31.507Z"></time># BetterLootBox — Public API This document describes the public API that BetterLootBox exposes for other Hytale plugins. --- ## Getting started Get the API instance after BetterLootBox has loaded: ```java BetterLootBoxAPI api = BetterLootBoxAPI.get(); if (api == null) { // BetterLootBox is not installed or not yet initialized } ``` Register listeners early in your plugin's `setup()` or `start()` method so you don't miss events. --- ## Events All events are in the package `com.gillodaby.betterlootbox.api.events`. Events marked **Cancellable** can be cancelled by calling `event.setCancelled(true)`. ### Registering a listener ```java BetterLootBoxAPI.get().on(LootBoxPostOpenEvent.class, event -> { // your logic here }); ``` --- ### 1. `LootBoxPreOpenEvent` — Cancellable **Fired:** Before the player opens a lootbox, **before the key is consumed**. Cancelling this event stops the opening completely. The key is **not** consumed. | Method | Returns | Description | |---|---|---| | `getPlayerId()` | `UUID` | UUID of the player | | `getPlayer()` | `Player` | The player entity | | `getLootbox()` | `LootBoxDefinition` | The lootbox being opened | | `getWorldName()` | `String` (nullable) | World where the block is, or null if opened via API | | `getBlockPos()` | `Vector3i` (nullable) | Block position, or null if opened via API | | `isCancelled()` / `setCancelled(boolean)` | — | Cancel the opening | **Example use cases:** - Enforce a per-player cooldown from an external system - Block openings during a server event freeze - Require a quest to be completed before using a specific lootbox ```java api.on(LootBoxPreOpenEvent.class, event -> { if (cooldownSystem.isOnCooldown(event.getPlayerId(), event.getLootbox().id())) { event.setCancelled(true); // optionally notify the player } }); ``` --- ### 2. `LootBoxPostOpenEvent` **Fired:** After the reward has been fully given to the player and all reward commands have executed. | Method | Returns | Description | |---|---|---| | `getPlayerId()` | `UUID` | UUID of the player | | `getPlayer()` | `Player` | The player entity | | `getLootbox()` | `LootBoxDefinition` | The lootbox that was opened | | `getReward()` | `LootReward` | The reward the player received | **Example use cases:** - Grant XP in an external levelling system - Trigger a quest objective ("open X lootboxes") - Update a player statistics dashboard - Broadcast rare rewards to the server ```java api.on(LootBoxPostOpenEvent.class, event -> { int xp = rarityToXp(event.getReward().tier()); xpSystem.grant(event.getPlayerId(), xp); }); ``` --- ### 3. `LootBoxRewardSelectedEvent` — Cancellable **Fired:** After the reward is randomly selected, **before it is given** to the player. > **Note:** The key has already been consumed at this point. ... (258 lines left)API.md12 KB -
AIR [AURA], <time id="message-timestamp-1496968697766477975" datetime="2026-04-23T20:19:09.881Z"> — 4:19 PM</time>
ye LootBoxPostOpenEvent is good
<aside class="membersWrap_c8ffbb hiddenMembers_c8ffbb" aria-labelledby="uid_9361">
</aside>
# BetterLootBox — Public API
This document describes the public API that BetterLootBox exposes for other Hytale plugins.
---
## Getting started
Get the API instance after BetterLootBox has loaded:
```java
BetterLootBoxAPI api = BetterLootBoxAPI.get();
if (api == null) {
// BetterLootBox is not installed or not yet initialized
}
```
Register listeners early in your plugin's `setup()` or `start()` method so you don't miss events.
---
## Events
All events are in the package `com.gillodaby.betterlootbox.api.events`.
Events marked **Cancellable** can be cancelled by calling `event.setCancelled(true)`.
### Registering a listener
```java
BetterLootBoxAPI.get().on(LootBoxPostOpenEvent.class, event -> {
// your logic here
});
```
---
### 1. `LootBoxPreOpenEvent` — Cancellable
**Fired:** Before the player opens a lootbox, **before the key is consumed**.
Cancelling this event stops the opening completely. The key is **not** consumed.
| Method | Returns | Description |
|---|---|---|
| `getPlayerId()` | `UUID` | UUID of the player |
| `getPlayer()` | `Player` | The player entity |
| `getLootbox()` | `LootBoxDefinition` | The lootbox being opened |
| `getWorldName()` | `String` (nullable) | World where the block is, or null if opened via API |
| `getBlockPos()` | `Vector3i` (nullable) | Block position, or null if opened via API |
| `isCancelled()` / `setCancelled(boolean)` | — | Cancel the opening |
**Example use cases:**
- Enforce a per-player cooldown from an external system
- Block openings during a server event freeze
- Require a quest to be completed before using a specific lootbox
```java
api.on(LootBoxPreOpenEvent.class, event -> {
if (cooldownSystem.isOnCooldown(event.getPlayerId(), event.getLootbox().id())) {
event.setCancelled(true);
// optionally notify the player
}
});
```
---
### 2. `LootBoxPostOpenEvent`
**Fired:** After the reward has been fully given to the player and all reward commands have executed.
| Method | Returns | Description |
|---|---|---|
| `getPlayerId()` | `UUID` | UUID of the player |
| `getPlayer()` | `Player` | The player entity |
| `getLootbox()` | `LootBoxDefinition` | The lootbox that was opened |
| `getReward()` | `LootReward` | The reward the player received |
**Example use cases:**
- Grant XP in an external levelling system
- Trigger a quest objective ("open X lootboxes")
- Update a player statistics dashboard
- Broadcast rare rewards to the server
```java
api.on(LootBoxPostOpenEvent.class, event -> {
int xp = rarityToXp(event.getReward().tier());
xpSystem.grant(event.getPlayerId(), xp);
});
```
---
### 3. `LootBoxRewardSelectedEvent` — Cancellable
**Fired:** After the reward is randomly selected, **before it is given** to the player.
> **Note:** The key has already been consumed at this point.
You can **override** the reward with a different one by calling `setOverrideReward(LootReward)`.
Cancelling aborts the opening without giving any reward (the key is already spent).
| Method | Returns | Description |
|---|---|---|
| `getPlayerId()` | `UUID` | UUID of the player |
| `getPlayer()` | `Player` | The player entity |
| `getLootbox()` | `LootBoxDefinition` | The lootbox being opened |
| `getOriginalReward()` | `LootReward` | The reward chosen by the RNG |
| `setOverrideReward(LootReward)` | — | Replace the reward with a custom one |
| `getOverrideReward()` | `LootReward` (nullable) | The override, or null if not set |
| `isCancelled()` / `setCancelled(boolean)` | — | Cancel reward delivery |
**Example use cases:**
- Double-reward events (swap reward for a better tier)
- VIP multipliers (upgrade reward rarity for premium players)
- Prevent a specific reward from being given under certain conditions
```java
api.on(LootBoxRewardSelectedEvent.class, event -> {
if (eventSystem.isDoubleRewardActive()) {
LootReward better = pickBetterReward(event.getLootbox(), event.getOriginalReward());
event.setOverrideReward(better);
}
});
```
---
### 4. `LootBoxKeyConsumedEvent`
**Fired:** Immediately after a key has been removed from the player's inventory to open a lootbox.
| Method | Returns | Description |
|---|---|---|
| `getPlayerId()` | `UUID` | UUID of the player |
| `getPlayer()` | `Player` | The player entity |
| `getLootbox()` | `LootBoxDefinition` | The lootbox the key was used for |
**Example use cases:**
- Track key consumption in an external economy log
- Update an achievement counter ("used X keys total")
- Sync key usage to an analytics backend
```java
api.on(LootBoxKeyConsumedEvent.class, event -> {
analytics.track("key_used", event.getPlayerId(), event.getLootbox().id());
});
```
---
### 5. `LootBoxKeyGivenEvent`
**Fired:** After one or more keys have been successfully given to a player, via command, shop purchase, or programmatic API call.
| Method | Returns | Description |
|---|---|---|
| `getPlayerId()` | `UUID` | UUID of the player |
| `getPlayer()` | `Player` | The player entity |
| `getLootbox()` | `LootBoxDefinition` | The lootbox the key belongs to |
| `getAmount()` | `int` | Number of keys given |
| `getGiverName()` | `String` (nullable) | Who gave the key ("admin", "shop", etc.) |
**Example use cases:**
- Rank reward systems ("players at rank X get a key every hour")
- Grant achievement rewards through an external system
- Log all key distributions for economy balance auditing
```java
api.on(LootBoxKeyGivenEvent.class, event -> {
auditLog.record("key_grant", event.getPlayerId(), event.getAmount(), event.getGiverName());
});
```
---
### 6. `LootBoxBoundEvent`
**Fired:** When a world position is successfully bound to a lootbox (block placed by player with key, or admin binding via editor).
| Method | Returns | Description |
|---|---|---|
| `getLootbox()` | `LootBoxDefinition` | The lootbox now bound at this location |
| `getWorld()` | `String` | World name |
| `getPosition()` | `Vector3i` | Block coordinates |
**Example use cases:**
- Sync lootbox locations to an admin map plugin
- Mark territories as having active lootboxes
- Trigger a zone event when a lootbox appears in a specific area
```java
api.on(LootBoxBoundEvent.class, event -> {
mapPlugin.addMarker("lootbox", event.getWorld(), event.getPosition());
});
```
---
### 7. `LootBoxUnboundEvent`
**Fired:** When a world position is unbound from a lootbox (block broken in creative, or admin removal).
| Method | Returns | Description |
|---|---|---|
| `getLootbox()` | `LootBoxDefinition` | The lootbox that was removed from this location |
| `getWorld()` | `String` | World name |
| `getPosition()` | `Vector3i` | Block coordinates |
**Example use cases:**
- Remove map markers when a lootbox is removed
- End a zone event when the lootbox block is gone
```java
api.on(LootBoxUnboundEvent.class, event -> {
mapPlugin.removeMarker("lootbox", event.getWorld(), event.getPosition());
});
```
---
### 8. `LootBoxBatchOpenEvent` — Cancellable
**Fired:** When a player initiates a batch open (opening several lootboxes at once with the multi-open UI). Cancelling prevents the entire batch from starting.
For individual open events within a batch, listen to `LootBoxPostOpenEvent` — it fires once per reward regardless of single or batch mode.
| Method | Returns | Description |
|---|---|---|
| `getPlayerId()` | `UUID` | UUID of the player |
| `getPlayer()` | `Player` | The player entity |
| `getLootbox()` | `LootBoxDefinition` | The lootbox being batch-opened |
| `getCount()` | `int` | How many will be opened in this batch |
| `isCancelled()` / `setCancelled(boolean)` | — | Cancel the entire batch |
**Example use cases:**
- Limit batch opens during a maintenance window
- Require a special permission or achievement to batch-open
- Grant bonus rewards for batch openings ("open 10 at once, get a bonus")
```java
api.on(LootBoxBatchOpenEvent.class, event -> {
if (event.getCount() >= 10 && bonusSystem.isEligible(event.getPlayerId())) {
bonusSystem.scheduleBonus(event.getPlayerId(), event.getLootbox().id());
}
});
```
---
### 9. `LootBoxUniqueRewardClaimedEvent`
**Fired:** When a player claims a tracked-unique reward for the **first time** — a reward marked as one-time-only per player, or any reward in a lootbox configured with unique-per-player or global-unique settings. This event fires exactly once per player per reward in those cases.
| Method | Returns | Description |
|---|---|---|
| `getPlayerId()` | `UUID` | UUID of the player |
| `getPlayer()` | `Player` | The player entity |
| `getLootbox()` | `LootBoxDefinition` | The lootbox that contained the reward |
| `getReward()` | `LootReward` | The unique reward claimed |
**Example use cases:**
- Grant a one-time achievement for claiming the rarest item
- Trigger a global server broadcast ("Player X just got the legendary sword!")
- Mark a collection as completed in an external tracker
- Reward completion of a full lootbox reward pool
```java
api.on(LootBoxUniqueRewardClaimedEvent.class, event -> {
if (event.getReward().tier().equals("legendary")) {
broadcastSystem.announce(
event.getPlayer().getName() + " obtained a legendary reward from "
+ event.getLootbox().displayName() + "!"
);
}
collectionTracker.markClaimed(event.getPlayerId(), event.getLootbox().id(), event.getReward().id());
});
```
---
### 10. `LootBoxPreviewOpenedEvent`
**Fired:** When a player opens the reward preview UI for a lootbox (browsing possible rewards without opening).
| Method | Returns | Description |
|---|---|---|
| `getPlayerId()` | `UUID` | UUID of the player |
| `getPlayer()` | `Player` | The player entity |
| `getLootbox()` | `LootBoxDefinition` | The lootbox being previewed |
**Example use cases:**
- Analytics: track which lootboxes players inspect most before buying
- Achievement: "previewed 10 different lootboxes"
- Funnel analysis: preview → purchase conversion tracking
```java
api.on(LootBoxPreviewOpenedEvent.class, event -> {
analytics.track("lootbox_previewed", event.getPlayerId(), event.getLootbox().id());
});
```
---
## Query methods
```java
BetterLootBoxAPI api = BetterLootBoxAPI.get();
// List all configured lootboxes
List<LootBoxDefinition> all = api.getLootboxes();
// Get a lootbox by its config ID
LootBoxDefinition box = api.getLootbox("daily_crate");
// Get the lootbox bound at a specific world position
LootBoxDefinition atPos = api.getLootboxAtLocation("world", new Vector3i(10, 64, -30));
// Count how many keys a player has for a given lootbox
int keys = api.countKeys(player, box);
```
---
## Action methods
```java
// Open a lootbox for a player (consumes a key from their inventory)
api.openLootbox(player, box);
api.openLootbox(playerRef, box); // cross-world safe variant
// Open the preview UI
api.openPreview(playerRef, box);
// Give keys to an online player
boolean success = api.giveKey(playerId, box, 3, "rank-reward");
// Bind / unbind a world position
api.bindLocation(box, "world", new Vector3i(10, 64, -30));
api.unbindLocation(box, "world", new Vector3i(10, 64, -30));
```
---
## Removing listeners
```java
// Remove all listeners for a specific event type
api.clearListeners(LootBoxPostOpenEvent.class);
```
---
## Thread safety
Events are fired on the same thread that triggered the underlying action (world thread for block interactions, scheduler thread for batch openings). If your listener accesses shared state, handle synchronization on your side. Exceptions thrown in a listener are caught and logged — they will never crash the lootbox flow.