An AI assistant with its own voice. Java plugins on Paper 1.21: combat, loot, morphing, whole civilisations. The Skript that holds a live server together, and the storefront that pays for it. All mine, start to finish. Not things that demo well.
Server plugins, mods, texture packs and Discord bots. Most of what's on this site started as someone asking for something that didn't exist yet, including a combat system I'd never built anything like before, which had a working demo four hours later.
0Things shipped
0Classes in AegisStaff
0Tools behind JARVIS
0Hours to a first demo
Skills
What I work with.
The bar on each card isn't a self-rating. It's how many of my 12 projects it shows up in. Keep scrolling and the row moves.
Selected work
Things I've shipped.
Filter, then open any card to see how it works.
Scroll to spin the wheel. Click a card to bring it forward, click it again to open it.
01JARVIS
Downloads
Try out my plugins before ordering one.
Five small plugins you can run on your own test server. Drop the jar into your plugins folder, restart, and see how I build before you spend anything. They're built for Paper 1.21.
Small jobs and whole systems, agreed before I start.
Reviews
What clients say.
4 hrsto a first working demo of a combat system I'd never built anything like before.
I asked this guy to make me a plugin, which at the time he had never made something so combat based and difficult to produce before. despite this the guy put out the first demo within 4 hours- Which he listens to feedback and improves stuff off of, great guy to work with and quite friendly to talk to. Very talented at his work, something like this can pull off great comparisons against some of the top smp mods in minecraft like bliss, this thing comes really close alongside the quality of bliss and still bliss took ages to develop along with multiple devs, this was a one man army developing this. He's great at his work and I really would recommend him!
ÌçêsîxêClient · Crysgear
Process
How I work.
You always get something runnable early. Not a progress update. An actual jar you can drop on a test server and click around in.
Step 1
Talk
You tell me what you want. Not a spec, what it should feel like to the player using it. I'll tell you honestly if it's a bad idea, or if a plugin that already exists does the job.
Step 2
Scope
I come back with what I'd build, what's in and what's out, and a price. Nothing starts until you've agreed to both.
Step 3
Demo early
You get something you can actually run and click as soon as there's anything worth showing, not at the end.
Step 4
Iterate
You play it, you tell me what's wrong, I change it. This is the part that makes the difference and I don't rush it.
Step 5
Ship
Built jar, config, and documentation written so your staff can actually use it.
What you get
Documentation that isn't an afterthought. Every config option explained, including the ones where the obvious change is the wrong one.
Config you don't have to fight. Where it makes sense the setup lives in an in-game menu instead of a YAML file. KyronCrates has no config worth opening.
Built for a live server. Crash-safe, dupe-resistant, and tested against the awkward paths, not just the happy one.
Straight answers. If something will take longer than I said, you hear it from me first.
How long it takes
Size
First runnable
Finished
A script
Within the hour
Same day
A single-purpose plugin
A few hours
A day or two
A system
Same day
A few days
The variable is never the building, it's the iteration. A fixed spec ships quickly. "Build it and we'll see how it feels" takes as long as it takes to feel right, which is usually the correct choice for anything players will touch every day.
What it costs
I quote per job rather than publishing a rate card, because a rate card is wrong for almost every job. Tell me what you want and you get a number before anything starts. No hourly meter running, no bill that grows while you're not looking.
What
Why it moves the price
Size
One command is an evening. A system with its own database, GUIs and forty commands is not.
State
Anything that remembers between restarts needs storage designing, and storage is where the hard bugs live.
Custom items
Models, textures or a resource pack are a separate piece of work.
Interfaces
An in-game editor is far more work than a config file, and far better to use.
Hostility
FFA or anarchy servers need dupe-resistance and crash-safety a private SMP doesn't.
Iteration
A fixed spec is cheaper than "build it and we'll see". Both are fine.
If an existing free plugin already does what you need, I'll tell you that instead of quoting.
Paying
Full payment up front, once we've agreed the scope and the number. Nothing starts before that, and the price doesn't move afterwards unless you ask for something that wasn't in the scope.
That asks you to trust someone you've probably not worked with, so here's what you can check before you send anything:
Download something I made and run it. The Downloads tab has five plugins you can try on your own test server.
Look at the detail on this site. Every project explains how the thing actually works, because I built it and can.
FAQ
Asked, answered.
Do I get the source code?
Yes, on request. You paid for it. Some clients only ever want the jar and the config, which is fine, but the source is yours if you want it and I won't hold it back as leverage.
What if it breaks after you've delivered it?
If it's a bug in what I built, I fix it. That isn't a support contract with a time limit on it. It's just that shipping something broken and walking away isn't delivering. New features, or making it work on a version that came out later, are new work. The line is simple: if it never did what we agreed, that's mine. If you want it to do something else, that's a new job.
How many revisions do I get?
There's no counter. Iteration is step four of how I work and it's the part that decides whether the thing is good, so I'm not going to charge you per opinion. What does change the price is scope. Rebalancing an ability ten times is iteration. Deciding halfway through that it also needs a GUI and a database is a different plugin, and I'll say so before doing it rather than after.
Can you work with a plugin I already have?
Usually. Building on top of another plugin's API is normal. The Skript tooling on this site drives KyronCrates through its own commands rather than reimplementing it, which is exactly this. What I can't promise is modifying a paid plugin I don't have the source to. Tell me what you're running and I'll tell you honestly whether it's possible.
What do you need from me to start?
Your server software and version, roughly how many players it needs to hold, and a description of what the feature should feel like to the person using it. Not a spec. I'd rather hear "crates should feel like opening something, not clicking a chest" than a list of methods. If you have a competing plugin you like parts of, say which parts. That's usually the fastest way to understand what you actually want.
Will it slow my server down?
It shouldn't, and that's a design constraint rather than an afterthought. Things that run on every block break or every tick get treated differently from things that run when someone types a command. Fresh's Sus and Crysgear both explain where that mattered and what it cost. If you're already running badly before I start, I'll tell you that too. A new plugin isn't going to fix an overloaded server.
Contact
Want something built?
DM me on Discord and tell me what you're after. Include your server version, roughly how many players it needs to hold, and what you want it to do.
Discord. The fastest way to reach me about plugin work.
Your server software and version.
Roughly how many players it needs to hold.
What it should feel like to the person using it. Not a spec.
A personal AI assistant that runs on my own Windows PC, with a voice and a live HUD in the browser. You talk to him, he talks back, and he uses real tools to get things done.
He opens apps, controls the PC, reads and explains the screen, remembers things between sessions, guards the machine against malware and helps run a Discord server. The model picks the tool it needs, so you never have to know which feature a request belongs to before you ask.
Cores and Aspects for Crysgear SMP. A combat system built around one item you carry, four elements you can put inside it, and the choice of whether to keep that power in your hand or burn it into your gear.
Java 21 · Paper 1.21 · 38 classes · custom resource pack · no database
The idea
A player carries a Core. The core holds one Aspect at a tier from one to three. There are four aspects — Strength, Mirror, Light and Fire — and each one gives you passives that are always on plus abilities you fire by clicking with the core in hand. Higher tiers don't just scale numbers; they unlock new abilities and move the old ones onto different click slots, so a tier 3 player has a genuinely different kit from a tier 1 player.
Then there's the second decision. You can infuse an aspect into a sword or a piece of armour. When you do, the core goes quiet — you lose the whole ability kit — and the gear takes over with its own passives and, at tier 3, its own ability. It's a real trade rather than an upgrade: burst power in your hand, or something quieter that works while you're holding a weapon.
Command
What it does
/cores open
Open your core and socket or swap the aspect inside it
/cores withdraw
Take the aspect back out
/cores infuse armour|sword
Burn the aspect into what you're wearing or holding
/cores cast 1|2|3
Fire an ability by number, so it can be bound to a key
/cores info
Everything your current aspect does at your current tier
Everything in these tables is the live data the plugin ships — the same strings /cores info prints in chat, read out of a single catalog class so the chat text, the item lore and the HUD can never disagree with each other.
Strength red
Straight-ahead melee. It's the aspect that removes your weaknesses as much as it adds damage.
Ability
Trigger
CD
What it does
Brawl T1
Right click, core in main hand — off hand from T2
30s
A ball of unbreakable crimson hyphae 5 blocks across. Lasts 10 seconds, then every block reverts. Anyone stood inside gets Weakness II.
Fury T2
Right click, core in main hand
60s
20 seconds of black sparks and a red crown. Each crit you land multiplies your damage by another 1.25x. Taking two hits wipes the stacks.
Hunger T3
Left click air, core in main hand
120s
Sharpness VI on that sword for 30 seconds, draining your food bar as it burns.
Fear T3
Left click a target, core in main hand
50s
Nausea, Blindness, Slowness I and Weakness I on the target for 10 seconds.
Revenge infused
Right click, infused sword
45s
A 30 second window. Land 3 crits without being hit and every swing crits on its own. Being hit, or 5 quiet seconds, drops you back.
Passives: Strength I at all times, II from tier 2. Weakness can't be applied to you; from tier 3 neither can Wither or Poison. Infused: armour gives a 1 in 10 chance that a hit you take hands the attacker Weakness I for 6s (T2). A tier 3 sword rages you into Strength III at 4 hearts or below.
Mirror yellow
Turns other people's advantages into yours. Copies effects, reflects projectiles, and throws out decoys that look exactly like you.
Ability
Trigger
CD
What it does
Afterimage T1
Right click, core in main hand — off hand from T2
30s
A decoy takes your place and you turn invisible. It pops in pale yellow when struck, or fades on its own after 5 seconds.
Visualize T2
Right click, core in main hand
35s
A 6 block field that follows you for 15 seconds, copying the potion effects of everyone inside it onto you.
Shatter T3
Left click air, core in main hand
100s
Five clones batter the target in turn for two hearts each, with knockback, then vanish together.
Replicate infused
Right click, infused sword
20s
Land two knockback hits without being hit and you start replicating. Every hit after adds a clone beside your target, up to five, and the whole set strikes with you. Taking a knockback hit breaks the chain.
Passives: 10% chance to copy an attacker's effects onto you for 8s, 20% chance to reflect a projectile back at whoever fired it, and from tier 2 a 20% chance to throw out an afterimage whenever you're hit. Infused: armour gives a 12% chance that a clone of your attacker turns their own hit back on them (T2).
Light gold
Ranged and disruptive. The only aspect that changes how you fight at distance.
Ability
Trigger
CD
What it does
Reflection T1
Right click, core in main hand — off hand from T2
30s
Coat yourself in light for 5 seconds. The next hit you take lands on your attacker instead.
Bolt T2
Right click, core in main hand
45s
Throw a yellow bolt. Whatever it hits gets struck by lightning for 3 hearts.
Beams T3
Left click air, core in main hand
80s
Summon 3 runes that angle wherever you aim. Each left click fires one beam — left, right, then middle — and spends that rune.
Passives: 10% chance to call lightning when you hit with a bow or crossbow, and tridents too from tier 2. Your body gives off torch light. Blindness can't be applied to you from tier 2. Infused: armour gives a 15% chance an attacker gains yellow glow for 8s plus Nausea and Slowness I — Mining Fatigue I instead at tier 3. A tier 3 sword has a 15% chance to mark a target with 6s of glow and Slowness I.
Fire orange
The one that changes where you can go. Lava stops being terrain and starts being cover.
Ability
Trigger
CD
What it does
Ember T1
Right click, core in off hand
45s
For 10 seconds anything you land a hit with sets the target alight, with no fire aspect enchant involved.
Fry T2
Right click, core in main hand
35s
A 6 block ring that follows you, cooking anyone inside and boiling away water. Fire resistance does not save them.
Fireball T3
Left click air, core in main hand
100s
Charges over 60 seconds, growing as it goes. Release any time for 2 hearts and a 3 block crater, up to 6 hearts and 8 blocks at full.
Passives: fire resistance at all times and no lava fog. From tier 2 you swim through lava like water; at tier 3 standing in it gives your hits a 1.10x boost. Infused: armour regenerates you while you stand in lava. A tier 3 sword carries Fire Aspect II for as long as it stays infused.
How it works
Adding a fifth aspect takes three lines
Aspects are registered into an EnumMap<AspectType, AspectHandler> at startup. Every other system in the plugin — the HUD, the cooldown tracker, the core GUI, the item lore builder, /cores info, both tick loops — goes through that registry rather than switching on a type. So a new element is one enum constant, one class implementing AspectHandler, and one register() call. Nothing else has to be told it exists.
Nothing about a player's aspect is stored server-side. The aspect id, its tier, the stored tier for a withdrawn aspect and the infusion flag all live in the item's own PersistentDataContainer, under namespaced keys registered once at startup.
That buys a lot for free. State survives restarts without a save routine. It survives a world transfer or a server move, because it's inside the item file Minecraft already writes. Hand the core to someone else and the power goes with it, which is exactly the behaviour you want on an SMP — cores get looted, traded and fought over as objects, rather than as a row in a table with someone's name on it.
The same container drives the visuals. CustomModelData is computed from the aspect type and tier, so the resource pack shows a different model for each of the twelve aspect-and-tier combinations, plus the empty core, without the plugin knowing anything about textures.
The cost is the obvious one: if an item can be duplicated, the state duplicates with it. That's why every GUI in the plugin works on clones and writes back deliberately, rather than moving the real stack around inside an inventory the player can reach into.
Passive effects, infusion sweeps and the cooldown display run every 10 ticks — half a second. That's plenty for reapplying Strength or checking whether someone still has the right armour on, and it keeps the per-player cost low on a full server.
Anything that has to track movement gets its own loop at one tick. A charging fireball grows and follows the aim; Light's runes stay angled where the player is looking; Mirror's afterimage has to be in the right place the moment it's struck. At half-second granularity all of those visibly stutter.
Both loops resolve the aspect the same way, and both fall back to the stowed core rather than the held one. That's deliberate: an ability already in flight has to keep running after you switch to your sword. Putting the core away shouldn't cancel a fireball that's already in the air.
Crysgear.java — runTaskTimer at 10L and at 1L
Which aspect is actually active
At any moment a player might have a core in the main hand, a core in the off hand, an infused sword, infused armour, or several of those at once. Everything that fires an ability, draws the HUD or checks a cooldown asks one method which aspect is live, and gets a single answer.
The rule: infused gear wins. If an aspect has been burned into gear it has left the core, so the core stops acting entirely and the infused item is the only thing that can. If nothing is infused, the core has to be in one of your two hands. Sitting in your inventory does nothing.
The part that took the most care is that the infusion flag lives on the core, not on the sword — one authority — and a background sweep keeps the two honest when a player drops the gear, dies, or has it broken. Two independent sources of truth about whether something is infused is exactly the kind of thing that drifts apart on a live server and ends with someone holding the sword bonuses and the full core kit at the same time.
Crysgear ships its own pack rather than reusing vanilla items with a rename. It carries a model and texture per aspect per tier, driven off the custom model data above, and a bitmap font used to draw ability icons inline in chat and on the action-bar HUD — so a cooldown readout shows the actual ability glyph instead of a letter.
The build script compiles the plugin and zips the pack side by side, so a release is always a matched pair. A jar that ships without its pack shows everyone a stick.
Physical crates and keys for Kyron FFA. Bind a crate to any block in the world, build its loot table in a menu, and let players spin it. Built so an admin never has to open a config file and a player never loses a key they paid for.
A crate is a real block — a chest, a beacon, whatever you're looking at when you run the command. A hologram floats above it. Right-click it holding the right key and the key is consumed, the roulette spins, and the prize goes into your inventory, or onto the floor at your feet if it's full. Right-click without a key, or left-click at all, and you get the reward preview with the real odds instead of a guess.
Keys are tagged with the crate id in NBT, so a renamed lookalike opens nothing. They can't be placed as blocks. They drop on death like any other item — which is the entire point on an FFA server, where a key in someone's inventory is a reason to fight them.
Placed crate blocks can't be broken, blown up, or moved by a piston.
crates.yml exists, but nobody is meant to open it. It's an output. Everything about a crate is built in a menu instead.
The top four rows are the loot table. Pick an item up in your inventory and click an empty slot to add it as a reward, or shift-click it straight across. Click a reward with an empty cursor to remove it. A comparator toggles into odds mode, where clicking a reward raises or lowers its weight — left for +1, shift-left +10, right −1, shift-right −10 — and the live chance percentage updates on every item in the table as you go. Weights are relative, so a reward at 10 is ten times as likely as one at 1, and you never have to make them add up to anything.
Next to the name tag is the key slot. Drop any item in there and it becomes this crate's key, keeping its name, lore and enchants. Leave it alone and it uses the default. There's a toggle for whether a win from this crate broadcasts to the server.
Closing the menu saves. So does a plugin disable while the editor is open, which is a two-line guard that stops a server restart eating twenty minutes of loot-table work.
Every slot in that menu holds a copy. Nothing ever leaves or enters your real inventory while you're editing. That isn't a detail — it's the whole reason the editor can exist. An admin menu that moves live item stacks around is a dupe waiting to be found, and on an FFA server it will be found.
The spin is theatre — the winner is already decided
The prize is rolled from the weighted table before the menu even opens. The animation is handed that result and its only job is to arrive at it convincingly.
It's a 27-slot inventory with a nine-slot strip across the middle row. Every step shifts the strip one slot left and feeds a new random reward in at the right-hand end. The real prize is inserted at exactly the step that leaves it coasting into the centre slot on the final shift. The gap between steps stretches as it goes — one tick, then two, then four, seven, eleven — so it slows into place rather than stopping dead.
Because the outcome is fixed up front, the animation is disposable. It can be cut short at any frame — by a close, a disconnect, or the server going down — without changing what the player wins or leaving the outcome undecided.
gui/SpinGui.java · crate/CrateManager.java roll()
A consumed key is never left unpaid
The key is taken from the player's hand only once the spin has actually started, so a failed open — wrong key, unknown crate, no rewards configured — costs nothing.
From that moment the plugin owes them a prize, and there are three ways the spin can end: it finishes normally, the menu closes, or the plugin disables underneath it. All three route into the same award() method, which guards on a flag so it can be called from anywhere, more than once, in any order. Whichever path gets there first pays out; the rest do nothing.
If the inventory is full the prize drops at the player's feet rather than vanishing. The win message uses the reward's real display name where it has one and falls back to the item's translation key where it doesn't, so it reads correctly in whatever language the client is set to. Broadcasts are per-crate, so a common crate doesn't spam chat.
Floating crate text is the classic way to leave permanent litter in a world. Entities get saved into the chunk, the plugin gets removed or crashes before it can clean up, and the text stays there forever with nothing left that knows how to delete it.
These are non-persistent display entities. They're never written to the region file at all — they're spawned when the chunk loads and destroyed on disable. A hard crash leaves nothing behind, because there was never anything on disk to leave. Remove the plugin entirely and the world is clean the moment it next loads.
crate/HologramManager.java
Install
Drop the jar in plugins/ and restart. Config is written by the editor, so there's nothing to set up first. Rebuild after code changes with bash build.sh.
The whole staff side of a server in one plugin. Punishments with an escalation ladder, staff mode, vanish, freeze, reports, notes, an audit log of what staff themselves have been doing, Discord feeds and a local web dashboard.
Java 21 · Paper 1.21 · 124 classes · SQLite or MySQL · zero dependencies · v3.0.0
It's the largest thing on this site. Forty-odd commands, five staff ranks, its own database layer, and a set of rules designed around the assumption that the people using it can also abuse it.
The five ranks
Ranks stack downward — each one includes everything below it, and a person gets exactly one. They're composed in LuckPerms rather than hardcoded, because every single feature is its own permission node and every node defaults to false. Nothing is implicit, and a server that wants a different shape of team can build one.
Rank
Gains
Helper
Chat moderation and reports. Warn, kick, mute, tempmute, the punish GUI, player history, notes, staff chat, staff mode. No inspection tools and no bans
Mod
Tempban, unmute, unwarn, the ban list, spectate, /tphere, direct player alerts, resolving reports
Admin
Freeze, /tp, the staff audit GUI, deleting notes and reports. First rank that can review other staff — and the first that's punish-exempt and freeze-exempt from them
Manager
Permanent bans, unbans, IP bans, IP addresses visible in /seen, and forcing another staff member off duty
Head Manager
Vanish including on others, silent join and quit, config reload, diagnostic dump
A deliberate gap: mods can pull a player to them with /tphere but cannot /tp to a player. Teleporting to someone lets you drop into a fight or a base unannounced; pulling them to you doesn't. That distinction is the difference between a moderation tool and a way to cheat at survival.
Three commands sit on no rank at all — /invsee, /endersee and /spawnstash. They're op-only and have to be granted by hand, one player at a time, because reading someone's inventory is a different category of power from muting them.
Every punishment takes an optional -s flag to issue it silently, so a ban during an event doesn't have to become an announcement. Any command that clashes with another plugin can be switched off in config, and /staff <command> always works regardless of what else is installed.
How it works
Punishment guidelines as config, and a ladder that escalates on its own
The feature I'd point at first. Staff don't decide durations — they name what happened, and the plugin works out the punishment.
/offend <player> <offence> looks the offence up in a guidelines file that holds its type (ban, mute, kick or warn), what a first offence costs, whether it's severe enough to always be permanent, shorthand aliases staff can type instead of the full id, and a category for browsing. The plugin then applies it, and escalates repeat offenders by itself.
The ladder is keyed by which number punishment it is, and only the numbers that change need listing — set 2 and 5, and punishments 2 through 4 all take the first value while 5 onward take the second. Bans and mutes count separately, so someone who talks too much never creeps toward a ban. Every ban counts toward the ladder, including expired ones, lifted ones, and ones typed by hand.
What this buys is consistency. The oldest problem in server moderation is two staff members handing out wildly different punishments for the same thing, and every argument that follows. Encoding the guidelines means the answer doesn't depend on who was online. /offend is still gated by the permission for whatever punishment it would issue, so a helper naming a bannable offence doesn't get to issue a ban through the back door.
Staff mode: on duty is a different mode of play, not a hat
Going on duty puts you in spectator and stores your inventory. Coming off duty returns you to spawn and gives it back. While you're on duty you cannot change gamemode.
No staff command works off duty. Not one — and being op doesn't bypass it. The only exception is /report, which any player can use. That single rule is what stops the staff toolkit leaking into normal play, and it means "was this person on duty" is always a meaningful question with a recorded answer.
Creative mode is blocked for anyone not on an explicit bypass list, which closes the other obvious route to the same problem.
Combat locks staff out of their own tools
For fifteen seconds after another player hits you, every staff command is refused. Including /staffmode — especially/staffmode, because going on duty was the escape route. Only /report still works.
Without this, staff tools are an "I win" button in a fight: you're losing, you vanish or flip to spectator, and you take nothing. The lock means a staff member in a fight is a player in a fight until it's over.
The same combat tracking punishes ordinary combat logging. Disconnect within the window of trading blows and you're punished automatically — routed through the offence system, so it uses the same published guidelines and the same escalation ladder as everything else rather than being a special case bolted on the side.
Watching the staff, not just the players
Most staff plugins record what was done to players. This one also records what staff did, and puts it in front of the rest of the team.
Every staff action goes into an audit log, browsable in a GUI by admins and above. On top of that sits a bias check: if a staff member punishes someone they were fighting inside the last minute, the rest of the team is warned about it automatically. Nothing is blocked — the punishment still lands, because sometimes the person you're fighting genuinely is cheating — but it can't happen quietly.
There's also a weekly digest posted to Discord summarising what each staff member did. Both features exist because the failure mode on a real server is almost never a staff member who can't find the ban command; it's one who uses it on someone they lost a fight to.
The permission structure backs this up. Admins and above are punish-exempt and freeze-exempt, so the tools can't be turned sideways on the people meant to be reviewing them.
Storage: SQLite by default, MySQL when you actually need it
Default is SQLite, and it needs no setup whatsoever — Paper already ships the driver, and the database is one file in the plugin folder. Drop the jar in, restart, done. MySQL is there for the one case that genuinely requires it: several servers sharing one punishment list.
Access goes through a set of DAOs — punishments, reports, notes, profiles, player state, audit — over a versioned schema, so a table change is a migration rather than a wipe.
Two things sit on top of that. Unknown names can be looked up against Mojang, so someone can be banned pre-emptively before they've ever joined. And on first start it can import punishments and player records from an older FreshStaff v2 install — reading that folder only, never moving or changing anything in it, so the old install stays a working rollback if the migration goes wrong.
The whole plugin ships with no shaded libraries at all. Paper provides Adventure, the annotations and the SQLite driver, so the jar in the plugins folder is the entire plugin.
Four Discord feeds, none of which can lag the server
Punishments, reports, staff actions and staff chat each post to their own webhook, so they can go to four different channels with four different sets of people able to read them. Staff chat in a channel the team can reach from their phones; punishments somewhere players can see them; the audit feed somewhere only management looks.
Leave a URL blank and that feed is simply off — there's no separate enable toggle per feed to get out of sync with itself.
Everything posts asynchronously. A webhook that's been deleted, or a Discord outage, cannot slow the server down or stop a punishment going through. The ban lands whether or not anyone gets told about it, which is the correct priority.
A dashboard that can't be reached from the internet
There's a read-only web panel for the owner, and it binds to 127.0.0.1 — not 0.0.0.0. It's reachable from the machine the server runs on and from nowhere else: not the LAN, and not the internet even if someone forwards the port.
That's a deliberate ceiling on the blast radius. A staff panel holding punishment records, IP addresses and player notes is a genuinely attractive target, and the safest version of that is one that was never listening on a public interface in the first place. An optional token can be required in the URL for anyone who wants to tunnel to it.
The bait chest
/spawnstash builds a decoy stash from a schematic — a convincing little base with chests in it, placed to catch people who are stealing from others. The plugin reads and pastes the structure itself, including the block entities, rather than depending on a world-edit plugin being installed.
It's op-only and granted by hand, like the other inspection tools.
How it was tested
Staff tooling is miserable to test by hand. Half the features need a second player, several need that player to do something specific at a specific moment, and the interesting cases are the ones where someone disconnects at exactly the wrong time.
So the tests are scripted. A headless Minecraft client connects to a local server and plays out each scenario — get hit and then try to open staff mode, log out mid-fight, tunnel downward, walk into a frozen state, click through a GUI — while watching what the server sends back. Around twenty of them, one per scenario, each runnable on its own.
It means the awkward paths get exercised on every build instead of the first time a player finds them.
Messages and configuration
Every piece of player-facing text lives in its own messages file, separate from configuration, so retheming the plugin for a server never means touching a setting. Durations use one format everywhere — 30m, 14h, 2d, 1w, perm — in commands, in the guidelines file and in the GUI presets alike.
Catches base-hunters two ways at once. It scores players on how they mine to spot the ones hunting rather than digging, and it stops ESP clients seeing underground bases at all — server-side, so no cheat client can work around it.
On a survival server the thing that ruins bases isn't combat, it's people finding them. Two ways that happens: someone runs a cheat client that draws chests through walls, or someone just tunnels methodically downward across the map until they hit something.
An anticheat catches the first if the client is one it knows about. Nothing catches the second, because digging down isn't cheating — it's just mining, done with intent. This plugin goes after both.
/espsus
aliases /sus and /suspects · opens the suspect list, spectate or dismiss from it
How it works
Scoring the shape of someone's mining
The signal is a descent: a block broken directly beneath the player. Doing that once is completely normal. Doing it over and over in a row is the pattern people use when they're sweeping for someone else's base rather than actually collecting anything.
So each descent adds a point — but once a run of consecutive descents passes a streak length, every further one is worth several times more. That multiplier is the whole heuristic. It's what separates "dug down to a cave" from "systematically tunnelling", without needing to know anything about the player's intent. Breaking anything that isn't below you resets the streak.
Points bleed away every minute, so ordinary mining fades to nothing and only sustained behaviour accumulates. Cross the score threshold and you land on the list.
There's a second, independent rule for volume: a large number of descents within a rolling window puts someone on the list on its own, whatever the decaying score happens to be doing. Digging at that rate for that long isn't ordinary mining regardless of how it's scored.
Falling and soft blocks — gravel, sand, dirt, grass, water, lava — are ignored entirely, since they aren't tunnelling and would otherwise generate constant noise.
Anti-ESP that a cheat client can't defeat
The important part: the client is never sent the data. This isn't obfuscation or a client-side check that a modified client can ignore — the information simply doesn't leave the server, so there is nothing for a cheat to read.
To anyone above ground, containers and spawners below a depth threshold are sent as plain stone, and deepslate below Y=0 so the fake block never looks out of place for the depth it's at. Item frames, armour stands, minecarts, dropped items and mobs below the threshold aren't sent at all. Everything is restored the instant a player descends past the threshold themselves — so the base owner sees their own base normally, and only someone hovering above it is looking at a lie.
The concealed list is the set of things base ESP actually hunts for: chests, barrels, shulkers, hoppers, furnaces, brewing stands, beacons, spawners, trial spawners, vaults. These are found through the chunk's block-entity list, which is also its limitation — plain blocks like ores don't have block entities, so hiding those is Paper's own anti-xray's job, not this plugin's. The config says so directly rather than letting someone add ores to the list and assume it worked.
A margin above the threshold stops the effect flickering for someone hovering right on the boundary, and the conceal radius is meant to sit near the server's view distance — going wider costs work for no benefit, since the client isn't sent those chunks anyway.
Players are never hidden, because hiding them would break PvP and look like a bug. The ender dragon and the wither are never hidden either.
Suspects never learn they're suspects
Alerts are hidden from the person they're about, even if that person holds the alert permission themselves. Staff get pinged when someone is added, and pinged again each time an already-listed player climbs another chunk of score.
This matters more than it sounds. A watchlist that tells you you're on it converts a detection tool into a training tool — the person adjusts their pattern, stays under the threshold, and you've taught them exactly where the line is. The config note for the setting says to turn it off only while testing alone, since otherwise you flag yourself and see nothing.
There's an exempt permission for players who should never be listed at all.
One list, two kinds of evidence
If AxyronAC is installed, the plugin pulls violation levels out of it so anticheat verdicts sit in the same list as the mining heuristics. A high enough total across all checks puts someone on the list on anticheat evidence alone, and individual checks that are noisy on a given server can be ignored without silencing the rest.
It's a soft dependency. With no anticheat present the plugin carries on as a pure mining watchlist rather than failing to load — the integration is a bonus, not a requirement.
Having both in one place is the point. Neither signal is conclusive by itself; someone who trips the anticheat occasionally and tunnels like a base-hunter is a much stronger case than either on its own, and that's only visible if they're on the same screen.
Everything is tunable, and the config explains itself
Points per descent, streak length and bonus, the threshold, the decay rate, the volume rule, the depth cutoff and the ignored blocks are all configurable — because the right numbers depend on the server. A skyblock server and a 5000-block-radius survival map have completely different ideas of what normal mining looks like.
Each setting carries a comment explaining what it's for and what changing it does, including the ones where the obvious change is wrong. The depth cutoff defaults to counting everything, with a note explaining why: base-hunters start digging from wherever they're standing, and spawn can easily be high up a mountain, so a "sensible" lower cutoff would miss them.
There's a debug mode that logs why each individual block break was or wasn't counted, for tuning the thresholds against a real server's mining habits rather than guessing.
The biggest thing I've built. Players found towns, claim land, run a treasury, tax their citizens, sign alliances and go to war over borders. A server-wide political layer sitting on top of survival.
Java · Paper · land claims · economy · warfare
What it does
A player founds a settlement and claims the land around it. Inside those borders they decide who can build, who can break and who can come in at all. Outsiders can't touch it.
From there it stops being about blocks. A civilisation has a treasury, and it fills it by taxing the people who live there. It has neighbours it can trade with, ally with, or refuse to speak to. And when diplomacy fails it can declare war, and territory changes hands — the borders on the map are the scoreboard.
System
What it covers
Towns & claims
Founding a settlement, claiming and unclaiming land, and controlling who can build, break or enter inside your borders
Economy
A treasury per civilisation, taxes on citizens, resource stockpiles, and trade between nations
Diplomacy
Alliances, and the standing relationships that decide who can walk into your land without a fight
War
Declaring on another civilisation, fighting over territory, and taking land off the loser
Commands
One root command with subcommands, so everything a civilisation does lives under /civ and there's one thing to remember rather than a dozen top-level commands competing with every other plugin on the server.
Command
Who
What it does
/civ create <name>
everyone
Found a civilisation where you're standing
/civ claim
member
Claim the chunk you're standing in
/civ unclaim
leader
Give a chunk back
/civ map
everyone
Who owns the land around you
/civ info [civ]
everyone
Members, territory, treasury and standing
/civ list
everyone
Every civilisation on the server
/civ invite <player>
leader
Invite someone to join
/civ join <civ>
everyone
Accept an invite
/civ leave
member
Leave your civilisation
/civ kick <player>
leader
Remove a member
/civ deposit <amount>
member
Pay into the treasury
/civ withdraw <amount>
leader
Take from the treasury
/civ tax <rate>
leader
Set what members are charged
/civ ally <civ>
leader
Offer or accept an alliance
/civ unally <civ>
leader
Break an alliance
/civ war declare <civ>
leader
Declare war. Their claims stop protecting them from you
/civ war end
leader
Sue for peace
The permission column is a rank inside the civilisation rather than a server permission — leaders can spend the treasury and move borders, members can claim and contribute. The split matters because the treasury is the thing worth arguing over.
How it works
Claims are a permission system pretending to be a map
Underneath the borders, every claim is answering one question thousands of times a second: is this player allowed to do this here? Every block placed, every block broken, every chest opened, every piston, every explosion, every fire tick inside claimed land has to be checked against who owns it and what that person's relationship to the owner is.
Which means the answer has to be cheap. Claim lookups sit in the hottest path in the whole plugin — they run on events that fire constantly, on every player, forever. Everything else in the system can afford to be clever; this part has to be fast, and it has to be right, because the moment claim protection is wrong someone loses a base.
War is the interesting problem, because it has to break the rules
Claims exist to say no. War exists to say sometimes yes. The entire protection system is built to stop outsiders touching your land, and then war has to carve a hole in exactly that, for exactly the right people, for exactly as long as the war lasts.
That's the tension the whole feature lives in. Open it too far and a declaration of war becomes a griefing tool — declare, level someone's town, walk away. Keep it too closed and war is two people hitting each other in a field while the borders never move and nothing is at stake.
The answer has to make territory the thing you win and lose, so the fighting has a point beyond the fight, while leaving the loser with a civilisation still standing at the end of it. A player who logs off after a war having lost land will be back. A player who logs off having lost everything they built will not.
Taxes are the part players feel most
An economy where money only ever comes in isn't an economy — it inflates until the numbers stop meaning anything. Taxes are the drain that keeps the treasury worth filling and gives leadership an actual decision to make.
It's also the most politically loaded thing in the plugin. A tax rate is a leader making a decision that costs their citizens something, and citizens can leave. That single number does more to generate server drama than every other feature combined, which is precisely why it's in there.
Become a block. Any block, anywhere — or in a round of prop hunt, where one team hides in the scenery and the other team has to work out which crafting table is breathing.
Java · Paper · minigame + free-roam · solid disguises
What it does
Turn into a block and you stop being a player-shaped thing standing in a room. You become part of the room. Pick the right block and stand somewhere it belongs and people walk past you — which is the entire game.
Two ways to use it. Free roam: morph anywhere on the server, whenever you like, and use it however you want — ambushes, hiding, or just being a very confusing chest. Prop hunt: a proper round with hiders, seekers and a clock.
Commands
Command
Who
What it does
/blockmorph <block>
everyone
Become that block. You lock in place and turn solid
/unblockmorph
everyone
Drop the disguise and get your movement back
/blockmorphs
everyone
List every block you can turn into
Same three-command shape as Morph, for the same reason: the whole appeal is picking a spot and committing to it before anyone arrives, and a menu would cost you the seconds that decide whether it works.
The rules that make it work
Two design decisions carry the whole thing, and they're both about taking something away from the player who's hiding.
Rule
Why it's there
You're locked in place
Movement is what gives a hider away, so removing it makes the disguise nearly perfect — and makes committing to a hiding spot a real decision you can't take back
You're a solid block
People bump into you, stand on you and try to break you. The disguise has to survive being touched, not just being looked at
How it works
Being solid is what makes it a game instead of a costume
A disguise you can walk through is a cosmetic. The moment a seeker's first instinct — run at the suspicious block and see what happens — actually collides with something, the disguise is load bearing, and it can be tested, probed and caught out.
It cuts the other way too. Being solid means a hidden player changes the shape of the map: they can be stood on, they can plug a gap, they can be in the way. A hider who picks a spot that makes the room subtly wrong gets found, and that's a skill worth having.
Locked in place is a cost, not a limitation
Being unable to move is the price of being almost invisible, and the trade is what makes the hiding interesting. You commit before the seekers arrive, and once you're committed you can only sit there and find out whether you chose well.
It also removes the failure mode that ruins prop hunt: a hider who can move freely just runs away forever and the round never ends. Taking movement away means the round always resolves — either they're found or the clock runs out.
Blending in is on the player, not the plugin
The plugin's job is to make you a convincing block. Whether you're a convincing block in that spot is on you. A stone brick in a stone brick wall is invisible. The same stone brick alone in the middle of a wheat field is a person, and everyone knows it.
That's deliberate — it's where the skill lives. If the plugin picked a sensible block for you the game would play itself, and the fun of watching someone stare directly at you from two blocks away would be gone.
Turns a player into a mob. Pick a form and everyone on the server sees a zombie, a creeper, an enderman — walking around, doing whatever you're doing.
Java · Paper · Minecraft plugin
What it does
You choose a mob and you become it. Not a skin on a player model — other players see the actual mob, moving where you move, doing what you do. Your own view stays normal so you can still play; it's everyone else's screen that changes.
The point is the reaction. A zombie that stops and looks at you does not read as a mob for very long, and the moment someone works out that one of the mobs in the room is a person, the whole space changes. That's a fundamentally different experience from a cosmetic that only changes what you look like standing still.
Commands
Command
Who
What it does
/morph <mob>
everyone
Become that mob. Everyone else sees the mob from that moment on
/unmorph
everyone
Drop the disguise and go back to looking like yourself
/morphs
everyone
List every mob you can turn into
Three commands, and that's deliberately the whole surface. There's no menu to learn and no setup — you type what you want to be. Anything more would get in the way of a feature whose entire appeal is how fast you can use it.
How it works
Your screen and everyone else's screen disagree, on purpose
The morphed player has to stay playable. If you replace someone with a mob on their own client too, they lose their hands, their hotbar and their camera, and the feature stops being usable for anything except standing still and being looked at.
So the illusion is built for other people. The morphed player keeps a normal first-person view and normal controls, while everyone else's client is told there's a mob there instead. Two versions of the same player, and the only one that has to be convincing is the one you can't see yourself.
The hard part is everything that isn't standing still
A static disguise is easy. Keeping it right through movement is where the work is — the form has to follow every position and rotation update, survive sprinting, sneaking, swimming and falling, and handle the moments where a player does something a mob has no animation for.
Then there's every other system that assumes a player is shaped like a player: combat reach, hitboxes, nametags, what happens when you take damage, and what other people see when you die. A disguise that breaks the first time someone hits you is worse than no disguise, because it teaches people exactly how to test for it.
Ranks and permissions without LuckPerms. Four roles out of the box, a coloured star next to every name, per-player permission grants, and a config you can read in one sitting.
Java 21 · Paper 1.21 · no dependencies · replaces LuckPerms
Why it exists
LuckPerms is excellent and most servers only ever use a tenth of it. Contexts, tracks, inheritance graphs, MySQL sync, a web editor — powerful, and all of it sitting on a server whose actual requirement is "give staff a blue name and let them run a few commands".
This does that part and stops. Four roles, a permission list per role, per-player grants on top, and a name colour. One config file, no database, nothing to install alongside it.
The roles
Role
Star
Colour
Inherits
Member
✦
#bec7d1
—
Staff
✦
#55d6ff
Member
Dev
✦
#d66bff
Staff, Member
Owner
✦
#ffb000
Dev, Staff, Member
Each role carries a label, a star glyph, a hex colour, an order number and its permission list. All five are config values, so the shipped four are a starting point rather than a fixed set — add a fifth by copying a block.
Commands
Command
What it does
/role <player> <role>
Put a player in a role
/roles
List the roles that exist, with their stars and colours
/perm <player> <permission> <add|remove>
Grant or revoke a single permission on top of their role
/roleinfo <player>
What role someone is in, and their colour
/reloadperms
Re-read the config and reapply to everyone online
How it works
Inheritance is a list, not a graph
LuckPerms resolves inheritance at runtime — a group points at its parent, that parent points at its own, and the effective set is computed by walking the tree. Powerful, and the reason a misconfigured setup can be genuinely hard to debug.
Here each role simply lists every permission it has, including the ones it shares with the roles below it. Owner's list contains the dev, staff and member nodes explicitly. It's more typing and it duplicates entries — and in exchange, what a role can do is the list next to its name. There is no resolution step to reason about and no way to be surprised by an inherited node you forgot about.
That trade only works because the list is short. At forty roles it would be unmanageable, and at that size you should be running LuckPerms.
Permissions are attachments, rebuilt from scratch every time
Bukkit grants permissions through attachments, and the easy mistake is to add them incrementally and lose track — a stale attachment keeps granting a permission long after it should have gone.
So nothing is ever adjusted in place. Every refresh removes every attachment the plugin is holding for that player, then rebuilds the whole set from their role plus their personal grants. Applying a change and applying it for the first time are the same code path, which means the state after a change can't drift from what a fresh login would produce.
Attachments are tracked per player and dropped when they disconnect, so a long-running server doesn't accumulate references to people who left hours ago.
The star is the point
A permission plugin nobody can see is a permission plugin nobody values. The visible half is a coloured star and role label in front of the player's name, applied to both the tab list and their display name, in the role's own hex colour.
It's the same reasoning as ranks on a store page: people pay for, and care about, the part that other players can see. The permission nodes are what the plugin does; the star is what it's for.
One caveat worth stating plainly: this sets the player's display name, so a chat plugin that builds its own format from scratch will ignore it. On a server already running a chat formatter, the star shows in tab and the chat format stays that plugin's job.
Storage is a flat file, on purpose
Role assignments and per-player permissions live in a data.yml next to the config, written on every change. No database, no connection pool, no driver to install.
For a single server with a normal player count that's the right answer — it's readable, it's editable by hand in an emergency, and it backs up by being copied. The moment you need several servers sharing one permission set, this is the wrong tool and LuckPerms is the right one.
What it deliberately doesn't do
Worth being straight about, because picking this over LuckPerms should be an informed choice:
Offline players. Commands target players who are online. Setting someone's role while they're away isn't supported.
Multi-server sync. One server, one file.
Contexts and tracks. No per-world permissions, no promotion ladders.
Temporary permissions. Nothing expires on its own.
Each of those is a feature LuckPerms has and this doesn't. If you need one, use LuckPerms — it's free and it's better at being LuckPerms. This is for the servers that were never going to use any of them.
A live scoreboard of how you're actually doing. Kills, deaths, wins, losses, your best streak, your current streak and your K/D — on screen while you play, not buried behind a command.
Java · Paper 1.21
Commands
Command
Who
What it does
/stats
everyone
Your kills, deaths, wins, losses, best and current streak, and K/D
/statsedit
admin
Opens the editor for changing what the board shows
What it tracks
Seven numbers, each of which can be switched off if you don't want it on the board:
Stat
Why it's there
Kills
The headline number, and the one people compare
Deaths
Meaningless alone, essential next to kills
Wins / Losses
Outcomes rather than raw fights — a different measure of doing well
Best streak
A personal record to beat, which is what keeps people playing
Current streak
The one that creates tension. A long streak makes you play differently
K/D ratio
The number people actually argue about
How it works
Current streak is the number that changes behaviour
Kills and deaths are history — they tell you what already happened and nothing about right now. A current streak is live. It goes up while you're winning and it's gone the moment you're not, which means a player sitting on a good one plays more carefully than they otherwise would.
That's the whole reason both streaks are on the board rather than just a total. Best streak gives you something to chase; current streak gives you something to lose. On an FFA server, where there's no objective other than fighting, those two numbers are most of what makes a session feel like it has stakes.
Everything on the board is a toggle
All seven stats are individually switchable in the config, because the right board depends on the server. A pure deathmatch server might want kills, streaks and K/D and nothing else. A server with rounds cares about wins and losses. Showing everything by default and letting people delete what they don't want is easier than making them assemble it.
The board title and its colours are configurable too — it ships with a purple-to-pink gradient, and both ends are set in the config rather than hardcoded, so it can be made to match a server's existing branding instead of clashing with it.
There's also a seasonal flag, for servers that want to reset the table and start a new competition rather than have month-one players permanently at the top.
Small on purpose
The whole plugin is a few kilobytes. It does one thing — count some numbers and put them on a scoreboard — and it doesn't need a database, a permissions tree or a dependency to do it.
Not everything has to be AegisStaff. A server owner who wants a stats board should be able to drop in a jar, restart, and be finished, and anything that made that harder would be working against the point of it.
Not everything deserves a plugin. These are the tools a live server runs on day to day — handing out crate keys, letting staff post as another player, printing the rules. Small surface, written to sit on top of the plugins rather than duplicate them.
Skript · LuckPerms · 3 scripts · 5 commands
keys.sk
Crate key handouts for staff. Three commands wrapping KyronCrates so nobody has to remember internal crate ids, with every handout logged.
/givekey /keyall /keys
3 commandsaudit logdefers to the plugin
makesay.sk
Posts a chat line as another player, formatted so it matches the server's real chat exactly — rank prefix included, read live from LuckPerms.
/makesay LuckPerms audit log
1 commandrank-aware formatting
rules.sk
The Spear SMP rules in chat. Six numbered sections, formatted to stay readable in a scrolling chat window and editable without a restart.
/rules 6 sections
1 commandplayers + console
The thread running through all three
Never duplicate what a plugin already owns.keys.sk could mint its own key items and doesn't — it calls KyronCrates and lets the plugin stay the only thing that decides what a valid key is. A script that reimplements a plugin's data format works right up until the day the plugin changes it.
Anything that can be abused gets logged. Handing out loot and speaking as another player are both things people argue about afterwards. Both write to their own file with who did it, to whom, and what was sent — because chat scrollback is not evidence.
Wrong input should teach you the right input. Run these with no arguments and you get the list of valid crates, or the list of online players — not a usage string and not an error. The most common reason staff mistype one of these is that they're half-remembering a name.
The storefront for a Java 1.21 server — twelve ranks across two game modes, gift cards, Stripe checkout and a live player count. Then built four more times in four different visual directions, off the same data, so the owner could pick one by looking at it rather than by describing it.
Vanilla JS · no framework · no build step · Stripe Payment Links · Node dev server
What's on it
Nine SMP ranks from £1 to £10, three FFA ranks, and two gift card denominations. Every rank carries the same four perks — custom prefix on tab, a rank kit, a chat tag and a Discord role — so the page has to sell the difference between them on identity rather than on a feature list. The £1 tier lets you write your own prefix, subject to staff approval.
Around the store: a hero with the live player count and a one-click IP copy, a "what happens after I pay" section, gift card redemption steps, the rules, and the terms and privacy pages a payment processor expects to see. Light and dark toggle throughout.
SMP rank
Price
FFA rank
Price
Custom Rank of Choice
£1.00
Kyron +
£2.50
Sargelaw
£1.50
VIP
£3.00
Flame
£2.50
Kyron ++
£5.00
Eggchan
£3.00
Clown
£3.50
Gift card
£5.00
Jaden
£6.50
Gift card
£10.00
Minutetech
£7.00
Shoebilly
£8.00
Wemmbu
£10.00
How it works
One data file, five complete rebuilds
Every rank, price, checkout link, perk list, colour code and blurb lives in a single data.js that assigns one object to window.KYRON. Nothing is written into the markup. Each theme reads that object and renders itself from it.
Each rank carries its hex colour and the Minecraft colour code the prefix actually renders in, so the chat preview on the site shows the tag in the same colour the player will see it in game. Getting that wrong is the fastest way to a refund request.
A price change is one number, once. Five themes follow. That mattered more than it sounds like it should: the whole point of building five was that the client could change their mind about the look without anyone re-entering nine ranks by hand.
kyron-site/data.js
Why five versions, and what each one was testing
Asking someone to describe the site they want gets you adjectives. Showing them five finished sites gets you a decision. Each one commits properly to a direction rather than hedging, and each lays the ranks out differently, because the rank list is where the whole page lives or dies.
Theme
Direction
Ranks laid out as
Nightfall
Dark violet, glass cards, glow — the modern gaming-server look
3-up card grid with chat previews
Parchment
Warm paper, serif headlines, editorial and quiet
A priced list, not cards
Terminal
Mono, green on black, sharp corners, scanlines
A data table
Aurora
Bright, soft gradients, rounded and friendly
Wide rows with big pricing
Shipped build
The direction that won, finished out
—
A small Node server puts each theme on its own port so all five can sit open in five tabs and be flipped between, rather than compared from memory. It's about sixty lines, no dependencies, and it refuses to serve anything outside the site directory.
The site is static. There is no server holding card details, no database of orders, and nothing of mine sitting between a player and their bank — checkout is a Stripe Payment Link per product, so the card form is Stripe's page on Stripe's domain.
For a server store that's the right trade. The alternative is running a payment backend for the sake of eleven fixed-price products, and taking on the liability that comes with it. This way the riskiest thing the site does is redirect.
What that leaves is the part players actually get confused by: what happens between paying and having the rank. So the page answers it directly — a "what happens after I pay" section, gift card redemption steps written out, and a support email on every page. Most store tickets are that question, and answering it on the page is cheaper than answering it eleven times a week.
Live player count
The hero shows how many people are on right now, which is the single most persuasive thing a server store can put above the fold, and the fastest way to look dead if it breaks. It degrades to the plain IP rather than to a zero or a spinner when the query fails.
Next to it, one button that copies the IP to the clipboard — kyron.mygame.host, with the raw 46.249.47.73:25006 as the fallback for clients that don't resolve the hostname — and one that opens the Discord. Those two buttons are what the page is for; everything else is underneath them.