Links
Tags
Creators
Details
Licensed Apache-2.0
Published 10 months ago
Updated 4 months ago
All versions
4.6.0
Release
HungerGameSSS 4.6.06 months ago 32
Compatibility
Minecraft: Java Edition
1.21.x
Platforms
Bukkit
Paper
Purpur
Spigot
Changes
[4.6.0] โ Full Bug Fix & Improvement Pass (2026-05-05)
Fixed โ 46 bugs across 35 files
Critical โ Task & Memory Leaks
- BUG-CM-01
CooldownManagerrepeating task never cancelled on reload โ addedshutdown(), called fromonDisable() - BUG-MAIN-01 Game-loop
BukkitRunnablewas anonymous, never cancelled โ storedgameLoopTask, cancelled inonDisable() - BUG-AM-01
new NamespacedKey(plugin, "hg_ability")created on every interact/hit/move โ cached asfinal abilityPdcKeyfield - BUG-BASE-02
BaseAbility.onDeath()calledvalidateCanUse()โ blocked cleanup when arena state wasENDINGat last kill - BUG-CS-02
CloudSwordblock-expiry task had no handle โ glass blocks not restored on disable - BUG-HB-02
HermesBootspassive task had no handle +lastShiftmap never cleared on quit/death - BUG-RE-01
ReinforcedElytrapassive task had no handle +explosionCooldownsnever cleared - BUG-VW-02
VillagerWandstale-entry cleanup task had no handle โ leaked on reload - BUG-MJ-01
Mjolnir: noperformDeath()โItemDisplayentity leaked, item permanently lost on death - BUG-SB-02
ShadowBlade: no globalcleanup()โ players stayed invisible permanently after/reload - BUG-RH-03
RavagerHorn: no globalcleanup()โ ravager entities roamed arena world after reload - BUG-GH-03
GolemHammer:inAirmap never cleared on quit/death โ stale KB resist - BUG-LS-02
LichStaff: no globalcleanup()โ stale ammo entries persisted between matches - BUG-SG-02
SoulGauntlet: no globalcleanup()โ soul charges persisted between matches - BUG-VS-02
VoidStaff: 3 state maps never cleared on full shutdown - BUG-WS-02
WitherSickles: offhand copies not removed, cooldowns not cleared on shutdown - BUG-DN-01
DeathNote: usedonQuit/onDeathbypassing BaseAbility lifecycle chain - BUG-LISTENER-01
AbilityListener.onPlayerMove: missing null check onevent.getTo()โ NPE risk
High โ State Management
- OPT-REG-01
AbilityRegistry.getAbility()was O(42) triple-fallback loop โ O(1) normalizedHashMaplookup - OPT-BASE-01 Config key prefix
"abilities.xxx."rebuilt on every config call โ cached in constructor - OPT-BASE-02
BaseAbility.execute()14-arm switch-case โEnumMap<TriggerType, Consumer>dispatch - OPT-DISP-01+02
AbilityDispatcher: debug logging on miss + eliminated duplicateNamespacedKeycopy - OPT-UPT-01
UnifiedPassiveTickernow skips spectators, dead players, non-active arenas - OPT-AD-01
ArmadilloDetonator: per-entityBukkitRunnableโ single unified per-player ticker - OPT-BB-01
BeehiveBlaster: 4-tick polling per bee โEntityDamageByEntityEventlistener (zero tasks) - OPT-AB-02+03
ArtemisBow: per-arena homing arrow cap + live count in passive HUD - OPT-CC-01
CorruptedCrossbow: gravity0.04flat โ0.05+1%horizontal drag (matches vanilla) - IMP-LISTENER-01 All combat/interact
@EventHandlerhandlers now haveignoreCancelled = true - IMP-VM-01+02
VeinMinerListener: hard cap 128 blocks + spread breaking across ticks - BUG-MJ-01
Mjolnirglobalcleanup()removes all display entities
Medium โ Improvements
- IMP-CTX-01
AbilityContext: defensiveitem.clone()+requiresArena()validation +getLocationSafe() - IMP-UTILS-01
AbilityUtils:findSafeLanding,degradeRandomArmorPiece,isFriendlyFire,tickProjectile,removeAfter,distanceSquared-first AoE check - IMP-CD-02
CooldownManager.generateProgressBar()usesยงcodes consistent with downstream serializer - IMP-MAIN-01+02
Main.onEnable()split intoregisterManagers/Listeners/Commands/postStartup+ early Java/Paper validation - ARCH-MS-01+02+03
MatchServiceFSM:transition()method +BorderTask/FeastTask/DeathmatchTask+ArenaDeathmatchEvent - OPT-CD-01
CooldownManager: purge offline players fromactiveDisplayItemin periodic cleanup - A1-1+3
Ability.java: ISP sub-interfaces (ActiveAbility,PassiveAbility,ProjectileAbility,ListenerAbility) + full Javadoc - A1-10+11
AbilityRegistry: ServiceLoader SPI discovery + config-drivendisabled/enabled-onlyoverrides - A1-17
BaseAbility:AbilityGuardchain-of-responsibility +passesGuards()replaces 5 duplicated validate/cooldown blocks - A1-18
BaseAbility:getConfigStringList()+getConfigSection()helpers - A1-19
Aiglos: configurable AOE shape (sphere/cylinder) viaaoe_shapeconfig key - A1-23
CloudSword: self-listener removed; fall-cancel centralised inAbilityListener.onFallDamageCancelCloud - A1-26 4 abilities (
BeehiveBlaster,ArmadilloDetonator,RavagerHorn,GhastlyWhistle):setRemoveWhenFarAway(true)on all custom entity spawns - A1-S1
AbilityServices: lightweight DI context replacing rawMainaccessor calls - A1-S2
@AbilityTrigger+@PassiveTickannotations for future APT code generation - A1-S3+A2-S3
ArenaEntityTracker: unified entity lifecycle manager (track/release/prune by owner, arena, ability) - A1-S4+A2-S2
ParticleThrottle: throttle +spawnDeferred()based on arena player count - A1-S5
AbilityMetrics: internal activation/blocked counter withSnapshotrecord - A1-S6
ConfigSchemaValidator: declarative YAML schema validation replacing manualassertRange()loop - A2-4
Main:ComponentLogger(SLF4J) field +clog()accessor - A2-9+10
ArenaManager.processQueue(): async chunk pre-loading + BossBar build progress - A2-11
CornucopiaBuildernow injectable viaplugin.getCornucopiaBuilder() - A2-17
Arena.java:ArenaBlockRestorer+ArenaLegendaryTrackercomponent objects extracted; old getters kept as@Deprecateddelegation - A2-18
Ingredient+LootEntryconverted to Java 21 records with compact constructors - A2-20
MatchService.resetArena(): block restoration now async viaArenaBlockRestorer+processQueue() - A2-22 VeinMiner disabled by default; opt-in via
arena.builtin-veinminer: true - A2-S5
HungerGamesAPI: public Developer API for custom ability registration + arena queries - A2-S6
MatchState:isActive(),isJoinable(),isEnding(),match()functional switch
New Files
| File | Purpose |
|---|---|
ability/AbilityServices.java |
Lightweight DI context |
ability/AbilityMetrics.java |
Activation/blocked counters |
ability/annotation/AbilityTrigger.java |
Trigger handler annotation |
ability/annotation/PassiveTick.java |
Passive tick annotation |
api/HungerGamesAPI.java |
Public Developer API |
manager/ArenaEntityTracker.java |
Unified entity lifecycle tracker |
model/ArenaBlockRestorer.java |
Block-change tracking + restore |
model/ArenaLegendaryTracker.java |
Legendary placement + hologram lifecycle |
util/ParticleThrottle.java |
Particle throttle + deferred spawn |
util/ConfigSchemaValidator.java |
Declarative YAML schema validation |
resources/paper-plugin.yml |
Modern Paper plugin descriptor |
Config changes
# New keys added (all have safe defaults โ no action required):
arena:
builtin-veinminer: false # VeinMiner now opt-in (was always-on)
show-build-progress: true # BossBar during arena build
abilities:
disabled: [] # blacklist ability names
enabled-only: [] # whitelist mode (empty = disabled)
spi-override-allow: false # allow SPI abilities to replace built-ins
Breaking Changes
Ingredient.mat/Ingredient.amountpublic fields removed โ useingredient.material()/ingredient.amount()- VeinMiner disabled by default โ set
arena.builtin-veinminer: trueto restore previous behaviour - All other changes are backwards-compatible with existing saves, ability YAMLs, and config.yml
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:VxdGAFxk:y2zjZc1P"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:VxdGAFxk:y2zjZc1P"
}

