Typed operations
Replace raw routes and JSON maps with validated builders, enums, records and consistent operation responses.
Client JavadocsRemote Java SDK · 2.0.0
A type-safe client for control panels, orchestration services and automation running outside Paper. Authenticate once, call the Remote API and subscribe to resilient live event streams.
try (UltimateBotClient client =
UltimateBotClient.builder()
.baseUri("http://server:8765/ultimatebot/api/v1/")
.token(token)
.build()) {
client.spawnBot(request)
.requireSuccess();
}
Remote integration
The SDK wraps UltimateBot’s authenticated HTTP endpoints and live event stream. It is designed for standalone Java applications, dashboards, network services and test automation.
Replace raw routes and JSON maps with validated builders, enums, records and consistent operation responses.
Client JavadocsReceive structured SSE envelopes with automatic reconnection, exponential retry and Last-Event-ID resume support.
EventBus JavadocsList the combat modes, custom brains and hosted addons installed on the target UltimateBot server.
Platform discoveryUnlike the server API, the SDK is an implementation dependency. It contains the HTTP client, Jackson integration, event-stream handling and shared model contracts needed by the remote application.
Server setup
Remote access is disabled by default. Configure a strong token, choose the network interface deliberately and restart or reload the supported UltimateBot configuration before connecting.
remote-api:
enabled: true
host: "127.0.0.1"
port: 8765
base-path: "/ultimatebot/api/v1"
token: "replace-with-a-long-random-secret"
Use 127.0.0.1 when the Java application runs on the same machine. The API is not exposed to the public network.
When binding beyond localhost, restrict the port with a firewall or private network and place TLS termination in front of the endpoint.
Never commit it to source control, expose it in browser-side JavaScript or log it. Supply it through your application’s secret or environment configuration.
Installation
The published artifact brings its shared UltimateBot models and JSON runtime transitively. No Paper or Minecraft dependency is required.
repositories {
maven("https://repo.monkeymoon104.it/releases")
}
dependencies {
implementation("com.monkey.ultimatebot:sdk:2.0.0")
}
<dependency>
<groupId>com.monkey.ultimatebot</groupId>
<artifactId>sdk</artifactId>
<version>2.0.0</version>
</dependency>
Client lifecycle
UltimateBotClient owns the remote event bus and may use a supplied HTTP client or ObjectMapper. Prefer one long-lived instance and close it during application shutdown.
UltimateBotClient client = UltimateBotClient.builder()
.baseUri("https://minecraft.example.com/ultimatebot/api/v1/")
.token(System.getenv("ULTIMATEBOT_TOKEN"))
.timeout(Duration.ofSeconds(8))
.build();
client.health().requireSuccess();
Runtime.getRuntime().addShutdownHook(Thread.ofPlatform().unstarted(client::close));
baseUri(String|URI) selects the versioned Remote API roottoken(String) is required and validated before constructiontimeout(Duration) controls normal request timeoutshttpClient(HttpClient) allows managed transport reuseobjectMapper(ObjectMapper) allows compatible JSON customizationclose() terminates active event subscriptions and workersBot requests
Start with an owner-bound or independent factory, override only what the scenario needs, then build an immutable request. Cross-field validation catches invalid modes, ranges and behavior combinations locally.
BotSpawnRequest request = BotSpawnRequest.ownedBy(playerUuid)
.botNameTemplate("Remote-Trainer")
.botUUID(customBotUuid)
.difficulty(DifficultyTier.HARD)
.combatMode(CombatMode.MACE)
.targetMode(BotTargetMode.PLAYERS)
.armor(BotArmorTier.NETHERITE)
.totemCount(8)
.autoTargetRange(24.0D)
.healing(true)
.explosionBlockDamage(false)
.emptyEquipmentSlot(SdkBotEquipmentSlot.OFF_HAND)
.build();
BotOperationResponse response = client.spawnBot(request).requireSuccess();
BotSnapshotResponse spawned = Objects.requireNonNull(
response.snapshot(), "Successful spawn did not return a snapshot");
UUID botUuid = Objects.requireNonNull(spawned.botUUID(), "Spawned bot UUID is unavailable");
Starts from SINGLE mode and supplies the required owner UUID automatically.
Starts without an owner and accepts explicit target UUIDs for controlled scenarios.
Configure EVENT, ALLY or TEAM_ALLY, including shared team owners.
| Builder method | Effect |
|---|---|
| stationary() | Disables movement-oriented behavior for controlled stationary scenarios. |
| wander(radius, distance, delay) | Enables idle wandering and configures its return-to-spawn behavior in one call. |
| disableExplosiveCombat() | Disables Crystal PvP, explosions and related destructive combat options together. |
| equipmentItem(slot, material, amount) | Keeps a specific material in a main-hand, off-hand or armor slot. |
| emptyEquipmentSlot(slot) | Prevents UltimateBot from placing anything into the selected slot. |
| brain(BrainKey) | Assigns a registered full custom AI independently of the selected mode. |
Remote operations
Read operations return immutable response models. Mutation operations return BotOperationResponse with a success flag, message, optional latest snapshot and optional bulk-removal count.
| Operation family | Client methods |
|---|---|
| Health and discovery | health, listBots, activeBotCount, getBot, listCombatModes, getCombatMode, listBrains, getBrain, listAddons. |
| Lifecycle | spawnBot, remove, removeByBotUUID, removeAll and removeBySource. |
| Behavior | Totems, follow, combat, difficulty, armor, auto-target, targets, team owners, WorldGuard respect, idle wander and owner-death persistence. |
| Combat | Target mode, combat mode, custom brain, tuning, healing, Crystal PvP, explosions, terrain damage, Ender Pearls and bot-vs-bot attacks. |
| Presentation | Kill messages and persistent main-hand, off-hand or armor equipment-slot policies. |
BotSnapshotResponse bot = client.getBot(ownerOrBotUuid);
client.updateCombatModeByBotUUID(bot.botUUID(), CombatMode.CRYSTAL).requireSuccess();
client.updateTargetModeByBotUUID(bot.botUUID(), BotTargetMode.PLAYERS_AND_MOBS).requireSuccess();
client.updateBrain(bot.botUUID(), BrainKey.of("myaddon", "adaptive-ai")).requireSuccess();
client.resetBrain(bot.botUUID()).requireSuccess();
client.removeByBotUUID(bot.botUUID()).requireSuccess();
Most modern SDK updates resolve either identity. Explicit ByBotUUID variants remain available where owner and bot routes have distinct server semantics. Consult each Javadoc method before choosing the identifier.
Server-Sent Events
The SDK opens a background SSE connection per subscription, reconnects with exponential delay and resumes from the last delivered event ID when the server supports replay.
BotEventSubscription subscription = client.events().subscribeForBot(
botUuid,
Set.of(
SdkBotEventType.ATTACK_STARTED,
SdkBotEventType.DIED,
SdkBotEventType.TARGET_CHANGED),
event -> {
System.out.printf("%s #%d at %s%n",
event.type(), event.sequence(), event.occurredAt());
event.payloadValue("targetUUID", String.class)
.ifPresent(target -> System.out.println("Target: " + target));
});
// Later: subscription.close();
Receive all event types or filter with a set of SdkBotEventType values.
Filter the server stream by owner UUID and optionally by event type.
Follow a specific runtime bot UUID even in multi-bot environments.
A subscription owns a virtual-thread worker and network stream. Use try/finally, application lifecycle hooks or another deterministic owner; closing the client closes all remaining subscriptions.
Models and failures
Requests validate before transport, responses are records, optional values are annotated, and protocol/HTTP failures use a dedicated client exception.
Inspect success, message, snapshot and removedCount, or call requireSuccess() for fail-fast flows.
Identity, owners, targets, settings, selected mode/brain and runtime state returned as an immutable snapshot.
Snapshot JavadocsKnown metadata remains typed while event-specific payload values can be accessed safely by name and runtime type.
Envelope JavadocsAuthentication failures, non-success HTTP status, malformed responses and connection problems do not masquerade as bot operation failures.
Exception Javadocstry {
BotOperationResponse response = client.updateDifficulty(botUuid, DifficultyTier.GOD);
if (!response.success()) {
logger.warn("Server rejected update: {}", response.message());
}
} catch (UltimateBotClientException transportFailure) {
logger.error("UltimateBot endpoint unavailable", transportFailure);
}
Dynamic combat platform
Combat modes and brains are namespaced values, not a hardcoded remote list. Query the server before presenting choices in a control panel.
List<CombatModeDefinition> modes = client.listCombatModes();
List<BrainDefinition> brains = client.listBrains();
List<AddonInfo> addons = client.listAddons();
modes.stream()
.filter(CombatModeDefinition::enabled)
.forEach(mode -> ui.addMode(mode.mode(), mode.displayName()));
client.updateCombatModeByBotUUID(botUuid, CombatMode.of("myaddon", "adaptive-duels"));
client.updateBrain(botUuid, BrainKey.of("myaddon", "adaptive-ai"));
Receive namespaced identity, display name, description, permission, capabilities and server-defined difficulty profiles.
List registered custom brains, inspect capabilities and assign or reset them independently of a mode.
Inspect installed hosted addons and their lifecycle state. The SDK intentionally cannot upload or execute jars.
Generated from source
Search every public SDK type generated for version 2.0.0. Open a result for its constructor, builder methods, fields, response contract and nullability details.