Minecraft Synthetic Player Activity Research

Date: 2026-06-27

Issue: #76

Recommendation

Build the follow-on implementation as a small Node.js synthetic-player runner based on Mineflayer, not as a custom gameplay client. Keep the existing Python scripts/dev/minecraft_synthetic_clients.py helper for cheap Minecraft Java status, ping, and login-start traffic; it is useful for relay and protocol reachability checks, but it intentionally stops before full player login and gameplay packets.

The first implementation slice should be Java Edition only and operator/test only. It should target Swarm Hosts-owned deployments, local test servers, or explicitly authorized development endpoints. Do not expose a public arbitrary server load-test button.

Tool Choice

Recommended stack:

  • mineflayer 4.37.1 for joined-player behavior. Its README describes a high-level JavaScript bot API with chat, movement, block, entity, inventory, digging, building, and plugin support, and currently lists support through Minecraft Java 1.21.11.
  • minecraft-protocol 1.66.2 through Mineflayer for packet handling, encryption, and authentication. It also remains the right low-level library if Swarm Hosts later needs many lightweight protocol clients.
  • mineflayer-pathfinder 2.4.5 for autonomous navigation once the MVP needs goal-directed movement instead of simple random walking.
  • mineflayer-collectblock 1.6.0 as an optional later behavior plugin, not an MVP requirement.
  • Node.js 22 or newer for the runner. npm view mineflayer and npm view minecraft-protocol both reported engines.node >=22 on 2026-06-27.

Useful upstream references:

  • Mineflayer: https://github.com/PrismarineJS/mineflayer
  • minecraft-protocol: https://github.com/PrismarineJS/node-minecraft-protocol
  • mineflayer-pathfinder: https://github.com/PrismarineJS/mineflayer-pathfinder
  • prismarine-auth: https://github.com/PrismarineJS/prismarine-auth
  • flying-squid: https://github.com/PrismarineJS/flying-squid

Alternative Strategies

minecraft-protocol or the existing Python protocol helper are best for high fan-out status, ping, and login-start pressure. They are lighter than Mineflayer, but they do not naturally exercise world state, movement physics, chat, inventory, entity interaction, block digging, or block placing. Treat this as a companion probe, not realistic player load.

MCProtocolLib is a viable Java protocol-library alternative for custom clients. It is lower level than Mineflayer and would require Swarm Hosts to build more behavior logic itself. That extra control is not worth the first slice.

Headless real Minecraft clients would have the highest fidelity but are not a good MVP path. They are heavier, harder to automate in CI, require licensed accounts for online-mode servers, and add launcher, graphics, credential, and terms-of-use risk.

Bedrock should stay out of scope for this issue. Prismarine has bedrock-protocol, but Swarm Hosts is Minecraft Java-first and the current templates/probes are Java-oriented.

Authentication Constraints

Offline-mode development and test servers are the clean MVP path. Mineflayer and minecraft-protocol can connect with auth: "offline" when the target server is configured for offline mode. This works for local tests and disposable Swarm Hosts validation deployments where ONLINE_MODE=FALSE.

Online-mode public servers require Microsoft/Minecraft authentication. Upstream docs show device-code Microsoft auth with token caching through prismarine-auth. This means each concurrently connected bot needs a distinct licensed account or a separately valid authenticated profile. Tokens and cache directories are secrets and must never be logged or committed. Account cost, rate limits, and terms-of-use risk need product/legal review before any customer server feature relies on authenticated bot accounts.

Because of those constraints, the implementation follow-on should launch a dedicated offline-mode test deployment for synthetic-player validation first. Authenticated bots against normal online-mode customer servers should remain a separate, explicitly reviewed future issue.

Operational Model

Run the synthetic-player runner outside the Flask control-plane web process. Good first locations are:

  • an operator CLI on a trusted workstation;
  • a CI or validation worker container;
  • a disposable Swarm Hosts validation job that resolves a deployment id to the known Swarm Hosts endpoint.

Prefer the user-facing relay endpoint for reachability/load proof because that exercises the path real players use. Agent-side or host-LAN execution can be a later diagnostic mode, but it should not replace public endpoint validation.

The runner should accept a deployment id or a validated Swarm Hosts endpoint, not an arbitrary public host in product UI. If a raw host/port mode exists for local development, keep it behind a clearly named development flag.

Local Proof

A local proof was run on 2026-06-27 without accepting the official Minecraft server EULA. It used a temporary Node 22 runner, mineflayer@4.37.1, and flying-squid@1.12.0 as an offline-mode Prismarine server harness.

Result:

{
  "server": "flying-squid@1.12.0",
  "client": "mineflayer@4.37.1",
  "node": "v22.23.1",
  "auth": "offline",
  "spawned": true,
  "chatSent": true,
  "moved": true,
  "action": "swing_arm",
  "dig": "ok",
  "serverChatObserved": true,
  "botVersion": "1.21",
  "distanceMoved": 6.344,
  "targetBlock": {
    "name": "grass_block",
    "position": "(18, 38, 8)"
  },
  "durationMs": 5817
}

This proves Mineflayer can drive joined-player activity in offline-mode Java protocol conditions: join, chat, movement, arm action, and digging. It does not replace the required follow-on proof against a real Swarm Hosts Minecraft Java deployment through the user-facing endpoint.

Safe Operating Limits

Start conservatively:

  • default bot count: 1;
  • maximum MVP bot count: 10 per runner invocation;
  • default duration: 60 seconds;
  • maximum MVP duration: 5 minutes;
  • spawn interval: at least 500 ms, preferably 1 second for live deployments;
  • behavior profile: join, wait for spawn, chat once, random walk/look/jump, swing, optionally dig/place only inside a prepared test area;
  • target scope: Swarm Hosts-owned validation deployments, local servers, or explicitly authorized endpoints only;
  • identity: generated names such as SwarmBot001 with a visible prefix;
  • output: structured JSON summary plus per-bot disconnect reason;
  • cancellation: process signal handling and timeout cleanup;
  • quotas: runner CPU/memory limits when containerized;
  • audit: record who launched it, deployment id, endpoint, bot count, duration, behavior profile, and result path;
  • kill switch: central config or env flag that disables synthetic-player launches.

Do not run against third-party public servers, do not bypass anti-bot systems, and do not attempt to hide bot identity.

Metrics And Evidence

The follow-on should record both runner-side and server-side proof:

  • runner: attempted joins, successful spawns, chat/action counts, movement distance, dig/place results, disconnect reasons, latency samples, total duration;
  • Minecraft status: player count before, during, and after the run through the Java status endpoint;
  • server logs: bot join, chat, action-related lines where available, and leave events;
  • RCON or command path where available: /list during the run and optional setup/cleanup commands for test areas;
  • Swarm Hosts deployment data: deployment id, game id, image, relay mode, user-facing host/port, lifecycle state, restart/container id stability;
  • host/container metrics: CPU, memory, network, and any available game-specific tick health. Vanilla Minecraft does not expose TPS/MSPT directly, so Paper or a server-side metrics plugin may be needed for tick-level load evidence.

MVP Scope For Issue #77

Unblock #77, but narrow it to an operator/test runner rather than a customer feature.

Acceptance criteria for the first implementation:

  • Add a Node 22 synthetic-player runner with pinned npm dependencies and no committed credentials.
  • Support Minecraft Java offline-mode targets first.
  • Accept bot count, duration, endpoint/deployment target, username prefix, and a small behavior profile.
  • Hard-cap bot count and duration in config validation.
  • Run at least one bot that joins, chats, moves, swings, and digs or places one safe block in a prepared test world.
  • Emit structured JSON with per-bot success/failure, disconnect reason, action counts, and elapsed time.
  • Preserve the existing Python status/login-start helper for lightweight probes.
  • Add tests for config validation, username generation, result aggregation, and failure/timeout handling.
  • Validate against a real Swarm Hosts Minecraft Java deployment using the user-facing endpoint. For the MVP, use a dedicated offline-mode validation deployment, then record status-protocol reachability, server logs, player count evidence, runner output, and cleanup.

Future issues should cover Microsoft-authenticated bot accounts, customer-facing UI, Bedrock support, large-scale capacity benchmarking, and richer behavior profiles.