4 new perks have been added: - Ironclad - Scorch - Tenacity - Tracker 1 new kit has been added: - Alchemist
SpeedHG
A Spigot / Paper plugin for the SpeedHG Hunger-Games variant by McScrims Network.
Built with Kotlin · Paper API 1.21 · Version1.0.0
Table of Contents
- Overview
- Dependencies
- Game Flow
- Configuration
- Kits
- Perks
- Commands
- Permissions
- Architecture
- Adding a New Kit
- Adding a New Perk
- Runtime Configuration via
SPEEDHG_CUSTOM_SETTINGS
Overview
SpeedHG is a competitive Hunger-Games game-mode where every player selects a Kit (with an Aggressive or Defensive playstyle) and up to 2 passive Perks before the round starts. The world border steadily shrinks, disasters trigger, and a feast spawns mid-game to force confrontation.
Key features at a glance:
- 17 fully-implemented Kits, each with 2 Playstyles (Aggressive / Defensive)
- 14 passive Perks with persistent DB-backed selection
- Hit-charge system for active abilities (configurable hits-to-charge per kit)
- Dynamic WorldBorder shrink, Feast, and Pit events
- Anti-runner detection, soup-based healing, team support
- Lunar Client integration (waypoints, scoreboard)
- Discord webhook for game results
- MySQL-backed stats, ranking, and leaderboard
- Fully i18n-able via
en_US.yml(MiniMessage format)
Dependencies
| Dependency | Role |
|---|---|
WorldEdit |
Arena construction for GladiatorKit |
Apollo-Bukkit |
Lunar Client integration |
Kup |
Internal rank/permission bridge |
All three must be present on the server; the plugin will not load without them.
Game Flow
LOBBY → STARTING → INVINCIBILITY → INGAME → ENDING
| Phase | Description |
|---|---|
LOBBY |
Waiting for min-players. Every 15 s an idle message is broadcast. |
STARTING |
Countdown (lobby-time seconds). Aborts if player count drops. |
INVINCIBILITY |
Players are teleported, kits & perks applied, Speed I + Haste I active. No damage dealt. |
INGAME |
Combat enabled, WorldBorder shrinks, timer counts up, Feast & Pit events fire. |
ENDING |
Winner announced, server shuts down after a short delay. |
Default timing values (overridable in config.yml):
| Setting | Default |
|---|---|
| Min players | 8 |
| Lobby time | 120 s |
| Invincibility time | 120 s |
| Border start | 600 blocks |
| Border end | 150 blocks |
| Border shrink time | 900 s |
Configuration
config.yml
game:
beta: true
min-players: 2
lobby-time: 60
invincibility-time: 120
border-start: 600.0
border-end: 100.0
border-shrink-time: 900 # seconds
max-radius-teleport: 50.0
ranked: false
teams:
enabled: false
preset-count: 10
max-size: 2
anti-runner:
enabled: false
discord:
enabled: false
webhook-url: "YOUR_WEBHOOK_URL"
database:
host: "localhost"
port: 3306
name: "speedhg"
username: "speedhg_user"
password: "your_password"
use-ssl: false
pool:
max-size: 10
min-idle: 2
SPEEDHG_CUSTOM_SETTINGS Environment Variable
For production overrides without touching config.yml, pass a JSON blob via environment variable (see Runtime Configuration).
Kits
Players select a kit in the lobby and choose a Playstyle (Aggressive [AGG] / Defensive [DEF]).
Active abilities are triggered by right-clicking the kit item. Most abilities require a configurable number of hits to charge first (global_hits_required, default: 15).
| Kit | Aggressive Active | Defensive Active | Passive (AGG) | Passive (DEF) |
|---|---|---|---|---|
| Anchor | Summon Iron Golem anchor — no-knock + bonus damage in radius | ← same | Partial knockback resistance | Partial knockback resistance |
| Armorer | — | — | Strength I on kill | Protection I on armor |
| Backup | — | — | — | — |
| BlackPanther | Wakanda Leap — leap forward, hit enemies on land | ← same | — | — |
| Blitzcrank | Rocket Grab — pull nearest enemy to you | ← same | — | — |
| Gladiator | Sky arena 1v1 duel (glass cage, Wither IV after 180 s) | ← same | — | — |
| Goblin | Steal enemy kit for 60 s | Spawn a bunker for cover | — | — |
| IceMage | Ice Spike Burst — cone of freezing projectiles | Freeze Burst — 16 snowballs in circle | Speed in cold biomes, slowness chance on hit | 33 % slowness proc on being hit |
| Ninja | Vanish + backstab: teleport behind last-hit enemy | Shadow Step: teleport to nearest enemy | Last-hit tracking | — |
| Puppet | Puppet Trap — summon entity traps | ← similar | — | — |
| Rattlesnake | Pounce — sneak-charge then leap, applies Poison II | — | Poison II on pounce hit | 25 % reflect Poison II on being hit |
| Spielo | — | — | — | — |
| Tesla | Lightning strike AoE | ← same | — | Knock-back + ignite reflect on being hit |
| TheWorld | Shockwave + 3× Blink forward | Shockwave + Freeze nearby enemies (10 s, 5-hit cap) | — | Frozen enemies have a 5-hit break cap |
| Trident | Dive — launch up, lightning on landing (charge-based) | — | — | Parry — chance to bounce + Slowness on attacker |
| Venom | Venom Blast — Blindness I + Wither I + 2 hearts instant damage | Barrier — absorbs up to 15 damage, reflects projectiles | — | — |
| Voodoo | Curse — apply Glowing + delayed damage to nearby enemies | ← similar | 20 % Wither proc on hit | Speed + Regen while cursed enemies are nearby |
Kit Item
Each kit provides its signature item in the player's inventory at game start. Items are tracked in cachedItems (UUID → List<ItemStack>) and cleaned up on onRemove.
Perks
Players may equip up to 2 Perks before the round starts. Selections are persisted to the database per-player UUID.
| Perk | Effect |
|---|---|
| Adrenaline | Dropping below 3 hearts → Speed II for 5 s (30 s cooldown) |
| Berserker | Below 4 hearts → deal 15 % more melee damage |
| Bloodlust | On kill: Speed I + Regen I for 5 s |
| Enderblood | Ender Pearl landings deal no fall damage |
| Evasion | 15 % chance to dodge incoming projectiles |
| Featherweight | Full immunity to fall damage |
| Ghost | Invisible to compass tracking and the Oracle perk |
| Gourmet | Consuming soup → Regen I + Speed I for 2 s |
| Last Stand | Taking damage below 3 hearts → Resistance II + Absorption I for 4 s (60 s cooldown) |
| Momentum | Sprint for 4 s without combat → Speed I |
| Oracle | Shows kit + distance to the nearest enemy on sneak / compass |
| Pyromaniac | Immune to fire, lava, magma blocks, and burn ticks |
| Scavenger | Every kill drops an extra Golden Apple at the corpse |
| Vampire | 10 % chance on melee hit to heal ½ heart |
Commands
| Command | Alias | Permission | Description |
|---|---|---|---|
/kit <name> <playstyle> |
— | — | Select a kit via command |
/kitinfo <id> |
/perkinfo <id> |
— | Show name + lore of a kit or perk |
/perks |
— | — | Open the Perk Selector GUI |
/leaderboard |
— | — | View the top 10 players |
/timer <time> |
— | speedhg.admin.timer |
Change the current game timer |
/ranking <toggle|status|rank [player]> |
— | speedhg.admin.ranking |
Manage the ranking system |
/help |
— | — | Show the help screen |
Permissions
| Node | Default | Description |
|---|---|---|
speedhg.bypass |
false |
Join while the game is running |
speedhg.admin.timer |
op |
Change the game timer |
speedhg.admin.ranking |
op |
Manage ranking |
speedhg.admin.staff |
false |
Staff flag for Lunar Client |
Architecture
SpeedHG (main class)
├── GameManager – state machine, game loop, compass, win check
├── KitManager – kit registry, player selections, hit-charge state
├── PerkManager – perk registry, player selections, DB persistence
├── KitEventDispatcher – single Listener delegating all kit events
├── PerkEventDispatcher – single Listener delegating all perk events
├── ScoreboardManager – sidebar scoreboard
├── TablistManager – tab list (Lunar Client / Volcano rank)
├── AntiRunningManager – cave-aware anti-runner detection
├── DisasterManager – periodic in-game disasters
├── FeastManager – mid-game feast event
├── PitManager – pit event
├── RankingManager – ELO / rank logic
├── StatsManager – kill/death/win tracking (MySQL)
├── DatabaseManager – HikariCP connection pool
├── LanguageManager – MiniMessage i18n
├── LunarClientManager – Lunar Client waypoints, scoreboard
├── DiscordWebhookManager– post-game Discord messages
├── WorldManager – map archive extraction & world loading
├── DataPackManager – biome overrides via datapack
└── CustomGameManager – SPEEDHG_CUSTOM_SETTINGS JSON parsing
Thread Safety
All per-player state maps use ConcurrentHashMap. BukkitTask references are canceled and removed in every onRemove / onDeactivate hook.
Kit Charge System
When a player's kit is applied, a PlayerChargeData object is stored in KitManager. Each confirmed melee hit (≥ 90 % attack strength) increments the charge counter. When it reaches hitsRequired, the state transitions to READY and the player receives an ActionBar notification. Hitting right-click with the ability item triggers ActiveAbility.execute() and resets the charge.
hitsRequired priority: kit-specific override > global_hits_required > hardcoded default.
Kits that use an internal cooldown instead (e.g. TridentKit Dive) set hardcodedHitsRequired = 0.
Adding a New Kit
- Create
src/main/kotlin/.../kit/impl/YourKit.ktextendingKit(). - Implement all abstract members (
id,displayName,lore,icon,cachedItems,giveItems,getActiveAbility,getPassiveAbility). - Create
private inner classfor each ability (Active & Passive, for each Playstyle). - Put magic numbers in a
companion objectwithUPPER_SNAKE_CASEconstants. - Wire configurable values through
override().getLong("key") ?: DEFAULT_*. - Add language keys under
kits.<id>.*insrc/main/resources/languages/en_US.yml. - Register in
SpeedHG.registerKits():kitManager.registerKit( YourKit() )
Adding a New Perk
- Create
src/main/kotlin/.../perk/impl/YourPerk.ktextendingPerk(). - Implement
id,displayName,lore,icon. - Override only the event hooks you need (
onActivate,onDeactivate,onHitEnemy, etc.). - Clean up all state in
onDeactivate. - Add language keys under
perks.<id>.*inen_US.yml. - Register in
SpeedHG.registerPerks():perkManager.registerPerk( YourPerk() )
Runtime Configuration via SPEEDHG_CUSTOM_SETTINGS
Pass a JSON blob as an environment variable to override game and kit settings without redeploying:
{
"game": {
"min_players": 4,
"lobby_time": 45,
"invincibility_time": 60,
"border_start": 500.0,
"border_end": 50.0,
"border_shrink_time": 720
},
"kits": {
"global_hits_required": 12,
"kits": {
"ninja": {
"hits_required": 10,
"extras": {
"cooldown_ms": 8000,
"backstab_damage": 6.0
}
},
"gladiator": {
"arena_radius": 11,
"arena_height": 7,
"wither_after_seconds": 180
},
"trident": {
"extras": {
"max_dive_charges": 3,
"sequence_cooldown_ms": 12000,
"lightning_radius": 4.0,
"lightning_damage": 4.0,
"parry_chance": 0.35,
"parry_slowness_ticks": 60
}
}
}
}
}
Kit-level extras keys are free-form strings resolved at runtime via KitOverride.getLong(), .getInt(), and .getDouble() with the kit's own hardcoded defaults as fallback.
McScrims Network · play.mcscrims.club