Backend Architecture
Details of Pilaf’s backend implementations for RCON and Mineflayer.
Overview
Pilaf provides two backend types:
-
RconBackend - Server command execution via RCON protocol
-
MineflayerBackend - Player simulation using Mineflayer library
Both implement the PilafBackend base interface.
Backend Factory
Backends are created through PilafBackendFactory:
const { PilafBackendFactory } = require('@pilaf/backends');
// Create RCON backend
const rcon = await PilafBackendFactory.create('rcon', {
host: 'localhost',
port: 25575,
password: 'secret'
});
// Create Mineflayer backend
const mineflayer = await PilafBackendFactory.create('mineflayer', {
host: 'localhost',
port: 25565,
auth: 'offline',
rconHost: 'localhost',
rconPort: 25575,
rconPassword: 'secret'
});
RconBackend
Located at: packages/backends/lib/rcon-backend.js
Connection
const rcon = new RconBackend();
await rcon.connect({
host: 'localhost',
port: 25575,
password: 'secret',
timeout: 30000 // 30 second connection timeout
});
Sending Commands
const response = await rcon.send('time query daytime');
// response.raw = "The time is 12345"
// response.parsed = 12345 (if JSON)
Timeouts
To prevent hanging, all RCON operations have timeouts:
-
Connect timeout: 30 seconds (configurable)
-
Send timeout: 10 seconds (configurable)
// Timeout implementation
await Promise.race([
Rcon.connect({ host, port, password }),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), timeout)
)
]);
MineflayerBackend
Located at: packages/backends/lib/mineflayer-backend.js
Connection
const backend = await PilafBackendFactory.create('mineflayer', {
host: 'localhost',
port: 25565,
auth: 'offline', // or 'microsoft'
rconHost: 'localhost',
rconPort: 25575,
rconPassword: 'secret'
});
await backend.waitForServerReady({ timeout: 60000 });
Creating Bot Players
const bot = await backend.createBot({
username: 'testplayer',
spawnTimeout: 60000
});
The bot is a standard Mineflayer bot instance with all Mineflayer methods available.
Server Readiness
await backend.waitForServerReady({
timeout: 60000, // Max wait time
interval: 3000 // Check interval
});
Polls using RCON list command until server responds.
Querying Entities
const entities = await backend.getEntities();
// Returns array of entity objects:
// [{ id, name, type, position: {x, y, z}, ... }]
Querying Inventory
const inventory = await backend.getPlayerInventory('username');
// Returns object:
// { items: [{ name, count, slot }], slots: 36 }
Backend Interface
All backends must implement:
-
connect(config)- Establish connection -
disconnect()- Close connection -
createBot(options)- (Mineflayer only) Create bot instance -
quitBot(bot)- (Mineflayer only) Disconnect bot -
getEntities()- (Mineflayer only) List entities -
getPlayerInventory(username)- Get player inventory -
send(command)- (RCON only) Execute command
Connection Management
StoryRunner Usage
// Setup phase
this.backends.rcon = await PilafBackendFactory.create('rcon', config);
this.backends.players.set('username', playerBackend);
// During steps
await this.backends.rcon.send('list');
const entities = await this.backends.players.get('username').getEntities();
// Teardown phase
await this.backends.rcon.disconnect();
await this.backends.players.get('username').disconnect();
Reconnection Pattern
For testing reconnection, create fresh backend instances:
// Logout (disconnect bot)
await backend.quitBot(bot);
// Login (create fresh backend + new bot)
const freshBackend = await PilafBackendFactory.create('mineflayer', config);
const newBot = await freshBackend.createBot({ username });
Error Handling
Performance Considerations
-
Connection pooling - Reuse backends across steps
-
Timeouts - Prevent hanging on unresponsive servers
-
Sequential operations - Mineflayer operations are serialized
-
Bot limits - Too many bots can impact server performance
Security Notes
-
RCON passwords - Use environment variables, never hardcode
-
Offline mode - For testing only, production should use
auth: 'microsoft' -
Firewall - RCON port should not be exposed publicly
Next Steps
-
StoryRunner Deep Dive - How backends are used in stories
-
Architecture Overview - System architecture