ServerBot is an advanced AI companion plugin designed for PaperMC (Minecraft 1.21.1). It integrates a Large Language Model (LLM) directly into your Minecraft server, allowing players to chat and interact with an intelligent companion that can behave like a player, a server helper, or any customized persona you design.
ServerBot is designed with robustness, thread safety, and resource optimization in mind, ensuring it does not lag the main Minecraft server thread.
To prevent server lag (TPS drop), all API calls to the LLM are handled asynchronously using Java's CompletableFuture and HttpClient.sendAsync().
- Concurrency Control & Locking: A dedicated queue lock prevents concurrent requests to the API. If the bot is already processing a response, new incoming queries are placed in a message queue.
- Message Batching: To prevent context fragmentation and token waste, when the bot finishes generating and retrieves the next items from the queue, it batches all queued messages together into a single prompt.
- Queue Bounds: The queue has a maximum size (default 12) defined by
bot.max_queue_size. If the queue is full, the plugin safely drops further messages and prints a warning to avoid out-of-memory issues. - Deduplication: Consecutive identical chats—including a message currently being generated—are normalized and deduplicated to prevent double-posting spam.
- Safe Reloads: Runtime settings are copied into an immutable snapshot, so asynchronous listeners and HTTP callbacks never race against Bukkit's mutable YAML configuration.
Since LLM context windows are limited and API usage can scale in cost, ServerBot features an automated memory compression engine.
- Token Estimation: ServerBot dynamically estimates its token usage (assuming roughly 4 characters per token).
- Auto-Compression Trigger: When estimated tokens reach
memory.max_tokens(default 4000), it kicks off a background compression request to the LLM using a customizable summary prompt. - State Verification (No Data Loss): While compression is happening in the background, new chats may occur. Before applying the summary, the plugin verifies that the memory history has not changed from under it. If new messages arrived in the meantime, they are automatically appended on top of the newly generated summary, preventing any lost conversation context.
- Atomic Turns and Writes: Each user/assistant exchange is added and persisted as one synchronized operation.
current.txtis written through a temporary file and atomically replaced where the filesystem supports it, greatly reducing the chance of partial state after a crash. - Corruption Quarantine: Empty, malformed, unexpectedly large, or otherwise unreadable memory is preserved as
current.txt.corrupt_<timestamp>_<sequence>before a clean state is initialized.
- Every changed memory state is saved with a timestamped backup in the
backups/directory. Redundant shutdown writes do not create duplicate backups. - A sliding retention window (configured via
memory.backup_retention) automatically deletes older files once the backup count exceeds the limit.
- Connects to any standard OpenAI-compatible API endpoint (e.g. OpenAI, Groq, local Llama.cpp, or Ollama).
- Supports bearer token authentication via the config file or securely through environment variables.
- Dynamically splits long bot replies into multiple chat lines at space boundaries to ensure they fit cleanly in the Minecraft chat HUD without overflowing (
bot.max_chat_line_length). - Treats player and model output as literal text, so section signs or other content cannot inject chat formatting.
/sb <message>- Description: Speaks directly to ServerBot. This command broadcasts your message to the server formatted as a public chat (
§7<Player> message), and forces the bot to generate a response regardless of whether you mentioned its name. - Usage:
/sb Hello ServerBot, how do I craft a beacon?
- Description: Speaks directly to ServerBot. This command broadcasts your message to the server formatted as a public chat (
Admin commands require the sbot.admin permission (which defaults to OP).
/sbotadmin <subcommand>- compress: Triggers manual background memory compression.
- reload: Reloads the
config.ymlsettings and forces a memory reload fromcurrent.txt. - prompt : Updates the active system prompt and saves it to the configuration file instantly.
- status: Shows useful diagnostic information:
- Current API model and URL.
- Number of messages in active memory.
- Estimated token count vs maximum token budget.
- Whether compression or response generation is active, plus the current queue depth.
- clear confirm: Permanently wipes the bot's current memory state (does not delete existing backup files).
sbot.admin- Description: Grants access to
/sbotadminand all its subcommands. - Default:
op
- Description: Grants access to
Below is the default structure of config.yml located in plugins/ServerBot/:
api:
# The endpoint URL. For local Ollama, this is usually http://127.0.0.1:11434/v1/chat/completions
url: "http://127.0.0.1:11434/v1/chat/completions"
model: "llama3"
# API Authentication token (leave empty if using local Ollama/Llama.cpp)
key: ""
# Or fetch from a system environment variable for security
key_env: ""
timeout_seconds: 120
max_tokens: 512
temperature: 0.7
bot:
# Display name in Minecraft chat
name: "ServerBot"
# Aliases the bot will respond to in public chat.
# The plugin scans chats for these aliases using strict boundary checks.
aliases:
- "serverbot"
- "sbot"
system_prompt: "You are a helpful and fun AI companion on a Minecraft server. Keep your responses relatively short, engaging, and in character as a Minecraft player/helper. Do not use formatting like markdown."
max_queue_size: 12
# Maximum Unicode code points accepted by /sb.
max_message_length: 1000
max_chat_line_length: 240
failure_message: "I could not reach the AI endpoint right now."
memory:
# Estimated token count before automatic background compression is triggered.
max_tokens: 4000
# Number of past memory backups to keep in the backups directory.
backup_retention: 25
# Prompt sent to the LLM to request history compression.
compression_prompt: "Summarize the following conversation history concisely. Retain important facts, names, and the general flow of what has happened, but make it as short as possible to save memory space."When a player chats normally on the server:
- The plugin catches the event asynchronously (
AsyncChatEvent). - It parses the message and tests it against configured aliases.
- If an alias is found with clean alphanumeric boundaries (e.g. matching
"hey sbot"but not"sbotter"), it triggers the AI processor. - The message is queued, batched with other pending chats, and sent off to the AI.
- The response is split into Unicode-safe lengths and broadcast to all players as a literal Adventure text component.
Ensure you have Java 21 installed. The project uses Gradle and compiles against the public Paper API.
# Clone the repository
git clone <repository_url>
cd ServerBot
# Compile, run tests, and build the jar
./gradlew buildThe compiled jar file will be located at build/libs/ServerBot-1.1.0.jar.