Skip to content

owengregson/SimpleBoxer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

35 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SimpleBoxer

Virtual sparring players for testing combat plugins. Spawn a bot that is a real player to your server β€” real player-list entry, real inventory, real movement packets, real knockback β€” then tune its ping, aim, click speed, reach, and movement to spar against. Built for Paper 1.17.1 β†’ 26.x.

Minecraft Platform Release


Why SimpleBoxer?

Testing a combat plugin (knockback tuning, anti-cheat, OldCombatMechanics modesets, Mental profiles) usually means rounding up real people. SimpleBoxer gives you opponents on demand.

A boxer is indistinguishable from a real player to the server. Whatever shapes combat on your server shapes the boxer identically, because the boxer rides the same wire:

  • Knockback arrives as the same velocity packet a real client receives, and is integrated through the vanilla client's motion math β€” so a boxer flies back exactly like a player with the same ping would.
  • Movement, sprinting, attacks, and swings leave as genuine player packets β€” same server validation, same Bukkit events (PlayerMoveEvent, PlayerToggleSprintEvent, …).
  • Vanilla commands (/tp, /effect, /give) and other plugins target boxers like any player. They're hidden from the tab list but stay tab-completable.

Use case: arena-style flat/simple terrain. Boxers sprint, strafe, and jump single-block steps β€” they don't path through mazes.


Features

  • πŸ–₯️ GUI-first β€” run /boxer and everything (spawn, tune, target, kit, presets, config) is point-and-click. No command syntax to memorise; the command tree stays for console and scripts.
  • πŸŽ’ Virtual inventories β€” kit a boxer out in armor and weapons, including custom-enchanted gear (StarEnchants and friends). It's a real player, so vanilla and custom enchant effects apply exactly as they would to a person wearing the same items β€” armor protects, weapons proc on hit, passive armor enchants tick.
  • πŸ₯Š Real-player bots β€” no NPC shortcuts; the server sees a ServerPlayer.
  • 🎚️ Difficulty ladder β€” dummy β†’ easy β†’ medium β†’ hard β†’ expert β†’ aimbot, each a full behaviour bundle.
  • πŸ›°οΈ Simulated ping β€” symmetric RTT that delays both perception and action, like a real laggy client.
  • 🎯 Spring-damper aim β€” presets locked/sharp/smooth/sloppy, or tune stiffness, damping, and max turn speed by hand.
  • πŸ–±οΈ Configurable clicking β€” CPS with jitter, reach and aim-cone gating.
  • πŸƒ Movement styles β€” rush, strafe-circle, strafe-weave, stand, with w-tap rhythm and stop-distance rings.
  • βš™οΈ Live tuning β€” change any knob at runtime with /boxer set.
  • 🧩 Skins & targets β€” wear any account's skin; pre-bind a follow target.
  • πŸ›‘οΈ Tireless fixtures β€” invincible (full hit + restore) and well-fed by default, so a test never ends because the bot starved or died.

Requirements

Server Paper (or a Paper fork) 1.17.1 through 26.x
Java 17+ for MC 1.17–1.20.4 Β· 21+ for MC 1.20.5 and newer

SimpleBoxer reaches into server internals (NMS) to make boxers real players. It targets Paper; Spigot/CraftBukkit are untested. If your exact version is unsupported the plugin disables itself cleanly and logs why β€” it never half-loads.


Installation

  1. Download the latest SimpleBoxer-x.y.z.jar from the Releases page.
  2. Drop it into your server's plugins/ folder.
  3. Restart the server (a reload won't load a new plugin cleanly).
  4. Verify β€” you should see SimpleBoxer x.y.z enabled in the console, and a plugins/SimpleBoxer/config.yml will be created.
  5. Spawn one in-game:
    /boxer spawn Rival hard target:YourName
    

That's it. By default only operators can use the commands (see Permissions).


Quick start

Just run:

/boxer

That opens the menu β€” the front door for everything. From there you can:

  • Spawn a Boxer β€” name it, pick a difficulty, choose a skin and target, and build its starting kit, then drop it at your feet.
  • Manage Boxers β€” one head per live boxer; click to retune, re-kit, set a target, pause/resume, teleport, or remove. Bulk pause/resume/remove too.
  • Presets & Defaults β€” edit the spawn defaults and the difficulty presets, or create your own β€” all saved to config.yml.
  • Plugin Settings β€” tab-list visibility and a config reload.

Alias: /sb works anywhere /boxer does.

Kitting a boxer (virtual inventory)

Open a boxer's Kit screen and drop items into the six equipment slots β€” four armor pieces and both hands. It never touches your real items: cursor-click a slot to equip a copy (paint as many boxers as you like from one item in creative), shift-click your own gear to add it, or hit Copy my gear to mirror what you're wearing. Because the boxer is a real player, custom-enchanted gear behaves exactly as it would on a person β€” armor protects and procs, weapons activate on hit, and passive armor enchants tick. The kit survives death and respawn.

Prefer commands? They still work

The full command tree remains for console and scripting:

/boxer spawn Bot expert skin:Notch target:Steve
/boxer target Bot Steve                # sic an existing boxer onto a player
/boxer set Bot ping 150                # tune anything, live
/boxer pause Bot                       # freeze its brain (it still takes hits)
/boxer remove all                      # clean up

Commands

All commands are under /boxer (alias /sb). Bare /boxer opens the menu β€” the commands below exist for console and scripting, but you never need them.

Command Description
/boxer Β· /boxer menu Open the management GUI (players only).
/boxer spawn <name> [preset] [skin:<player>] [target:<player>] [at <x> <y> <z>] Spawn a boxer. With no preset it uses your defaults. at is required from console.
/boxer remove <name|all> Remove one boxer, or every boxer.
/boxer list List live boxers with their target, ping, and CPS.
/boxer info <name> Full settings dump for one boxer.
/boxer target <name> <player|none> Set or clear a boxer's follow/attack target.
/boxer pause <name|all> Freeze a boxer's brain (it still receives knockback).
/boxer resume <name|all> Un-freeze.
/boxer set <name> <key> <value> Tune one setting at runtime (see below).
/boxer reload Re-read config.yml.

Tunable keys (/boxer set)

Key Value Example
ping whole number of ms (0–2000) /boxer set Bot ping 150
cps clicks per second (0–50; 0 = never attacks) /boxer set Bot cps 12
reach blocks (0.5–6) /boxer set Bot reach 3.2
aim locked / sharp / smooth / sloppy /boxer set Bot aim smooth
wtap true / false /boxer set Bot wtap true
movement rush / strafe-circle / strafe-weave / stand /boxer set Bot movement strafe-circle
preset any preset name /boxer set Bot preset expert
invincible true / false /boxer set Bot invincible false

Invalid input is answered in plain language β€” e.g. set Bot ping abc replies ping expects a whole number, not 'abc'. rather than throwing.


Difficulty presets

Each preset bundles ping, CPS, aim, reach discipline, w-tap, and movement into a named tier. Every component stays individually overridable at spawn or with /boxer set.

Preset Feel Ping CPS Aim
dummy Stands still, never attacks β€” a punching bag 0 0 smooth
easy High ping, slow sloppy clicks, walks 120 4 sloppy
medium An ordinary player 60 7 smooth
hard A practiced PvPer, disciplined w-taps 35 10 sharp
expert Tournament-grade, circles its target 15 13 tight
aimbot The calibrator: zero ping, locked aim 0 16 locked

You can also define your own presets in config.yml as sparse overlays β€” an entry there with a built-in's name overrides it.


Permissions

Everything defaults to operators only. Grant these nodes to delegate.

Node Grants Default
simpleboxer.gui Open and use the in-game menu (the full toolset on one screen) op
simpleboxer.command.use Run /boxer, plus help, list, info op
simpleboxer.command.spawn spawn and remove op
simpleboxer.command.control target, pause, resume op
simpleboxer.command.tune set op
simpleboxer.command.reload reload op
simpleboxer.* All of the above op

Configuration

A documented config.yml is written to plugins/SimpleBoxer/ on first start. The two top-level blocks are defaults (applied to any spawn that names no preset, and the base every preset overlays) and presets (your own named overlays). Every key inherits a sensible default when omitted, and a malformed value warns in the console and keeps the inherited value β€” a typo can never break a spawn.

# Keep boxers out of the tab list (still tab-completable in commands).
hide-from-tab: true

defaults:
  ping-ms: 0              # simulated RTT, 0–2000 (split: half perception, half action)
  cps: 8.0               # clicks per second, 0–50 (0 = never attacks)
  click-jitter: 0.3      # per-click interval wobble, 0–0.9
  aim:
    preset: sharp         # locked / sharp / smooth / sloppy
    # stiffness: 0.55     # optional granular overrides on top of the preset
    # damping: 0.30
    # max-velocity: 60.0
  reach: 3.0             # attack range in blocks, 0.5–6
  aim-tolerance-degrees: 10.0   # a click only attacks within this cone
  w-tap:
    enabled: false
    delay-ticks: 1        # ticks after a hit before forward releases (0–20)
    release-ticks: 2      # ticks forward stays released (1–20)
  movement:
    style: rush           # rush / strafe-circle / strafe-weave / stand
    stop-distance: 0.0    # 0 = hold W through the target (true rusher)
    sprint: true
  invincible: true        # take the full hit, then restore health
  feed-hunger: true       # pin hunger full so sprint stays legal

# Your own presets (sparse overlays over `defaults`):
presets:
  # laggy-spammer:
  #   ping-ms: 180
  #   cps: 14
  #   aim:
  #     preset: smooth

After editing, run /boxer reload.


Developer API

Other plugins can spawn and control boxers. The api module exposes BoxerService, obtainable from Bukkit's ServicesManager:

BoxerService boxers = Bukkit.getServicesManager().load(BoxerService.class);

boxers.spawn(new BoxerSpawnRequest(
        "Rival",
        player.getLocation(),
        DifficultyPresets.HARD,
        "Notch",        // skin owner, or null
        player.getName() // target, or null
)).thenAccept(boxer -> boxer.setTarget(player));

BoxerSpawnEvent and BoxerRemoveEvent fire on the Bukkit event bus.

Boxers carry a virtual inventory you can read and set β€” kit one out (custom enchants included) and it behaves like a player wearing the same gear:

boxer.equip(new Loadout(
        helmet, chestplate, leggings, boots,   // any ItemStacks, or null
        mainHandWeapon, offHandShield));

Loadout worn = boxer.loadout();                 // immutable, defensively copied

A starting kit can also ride the spawn request β€” new BoxerSpawnRequest(name, loc, settings, skin, target, loadout) β€” so a boxer spawns already dressed.


Building from source

Requires a JDK 21+ (the build provisions a Java 25 toolchain automatically).

git clone https://github.com/owengregson/SimpleBoxer.git
cd SimpleBoxer
./gradlew build          # compiles + runs unit tests; jar in core/build/libs/

The shaded plugin jar is core/build/libs/SimpleBoxer-<version>.jar.

Tests

./gradlew build                  # unit tests (physics, aim, latency, settings)
./gradlew integrationTest        # boots real Paper servers (floor + ceiling) and runs the in-server suite
./gradlew integrationTestMatrix  # every version listed in gradle.properties

Integration results land in run/<version>/plugins/SimpleBoxerTester/test-results.txt.

See ARCHITECTURE.md for the module map, the captured-connection design, threading rules, and the honest boundaries (in-process packets are invisible to packet-sniffing plugins; Folia and pathfinding are deferred).


Honest boundaries

  • In-process boxers have no socket, so their outbound packets don't traverse the netty pipeline β€” ProtocolLib/PacketEvents listeners won't see boxer traffic. The interesting direction (a real player attacking a boxer) works fully, because the attacker's own connection carries the packets.
  • Folia isn't supported yet (the scheduling seam is ready; placement and cross-region brains aren't).
  • Boxers are ephemeral β€” they're never written to player data and are despawned cleanly on shutdown.

Credits

Built by owengregson to pair with Mental and OldCombatMechanics. Issues and pull requests welcome on GitHub.