Introduce MySQL persistence and an in-memory stats system with async saving.
- Add HikariCP & MySQL connector dependencies and relocate libs in build.gradle.kts.
- Add DatabaseManager (HikariCP) to manage connection pool and lifecycle.
- Add PlayerStats data model and PlayerStatsRepository for table creation, reads, upserts and batch upserts (with prepared statements).
- Add StatsManager: coroutine-based cache, dirty-flags, async batch saves, auto-save (every 5 minutes), load/save APIs and shutdown save.
- Add StatsListener: load on AsyncPlayerPreLoginEvent and save on PlayerQuitEvent.
- Wire DB and stats into main plugin: connect on enable (disable plugin on fail), initialize StatsManager, save/disconnect on disable, register leaderboard command and stats listener.
- Update GameManager to record kills/wins/deaths and adjust scrimScore on events.
- Add LeaderboardCommand and language entries for leaderboard output; expose command in plugin.yml.
- Add database configuration section to config.yml.
- Minor refactor: KitCommand plugin accessor changed to a getter.
These changes provide a robust, pooled DB connection and efficient stats persistence (batched/upserted) to reduce DB load and ensure data safety during shutdown.
Introduce a new Venom kit with aggressive (deafening wither beam) and defensive (shield of darkness) abilities by adding src/main/kotlin/.../VenomKit.kt. Wire the kit into the plugin: import and register Venom in SpeedHG (extracted registerKits()), and extend KitEventDispatcher to handle projectile interactions for Venom defensive playstyle (cancel/stop projectiles and reflect thrown potions). Update en_US.yml: add Venom localization/messages, adjust default prefix and some kit/scoreboard copytext, and add a no_permission message.
Introduce an abstract cachedItems property on Kit (ConcurrentHashMap<UUID, List<ItemStack>>) to track per-player kit items. Update implementations (BackupKit, GoblinKit, IceMageKit, TemplateKit) to override and initialize cachedItems. GameStateListener now checks dropped items against the selected kit cache and cancels drops (playing a sound) for kit items, and adds handlers to cancel item pickup/despawn outside active game states. Add necessary imports for ItemStack, UUID, ConcurrentHashMap and new event types.
Add support for passing Components as placeholders in LanguageManager (getComponent, getMessageList) and add Player extension overloads (sendMsg, trans) that accept component pairs. Replace usages of legacy serialized strings with direct Component placeholders across kits, scoreboard, and listeners (remove legacySerializer imports/usages). Also normalize placeholder keys (remove angle brackets in ConnectListener) and scope legacySerializer as private in Extensions.
Introduce a BackupKit and allow players holding it to change kits mid-game while preventing normal kits from being picked once the game started. Changes:
- Add BackupKit implementation (kit with no abilities/items used for mid-round kit selection).
- Update KitCommand: import BackupKit and GameState, add isIngame helper, disallow normal kit picks during INGAME/INVINCIBILITY, permit BackupKit to swap kits mid-game (but prevent picking the same kit) and apply playstyles accordingly.
- Fix GoblinKit to also copy/restore the target's playstyle when stealing a kit and restore the player's original playstyle after timeout.
- Tweak IceMageKit slow effect chance (now ~1/3 chance using random.nextInt(3) < 1).
- Update en_US.yml: add messages and kit strings for backup and icemage, adjust ability_charged color, and add game/cannot-pick messages.
Also includes small import and formatting adjustments.
Introduce a new IceMage kit and wire playstyle support across the plugin. Changes include:
- Add IceMageKit with aggressive/defensive active & passive abilities, item distribution, and lifecycle hooks; caches ability instances and given items to reduce allocations.
- Register IceMageKit in SpeedHG on plugin startup.
- Update KitCommand to require a playstyle argument, validate it, select the kit's playstyle, and provide tab-completion for playstyles.
- Extend KitEventDispatcher with IceMage-specific handlers: spawn a circular volley of snowballs on ability use (cancelling the original projectile), mark spawned snowballs with persistent data, and apply freeze/slow effects on hit.
- Adjust GoblinKit to use a plugin getter and make inner ability classes static to avoid capturing the outer instance.
- Update language lines and plugin.yml usage to reflect the new /kit <kitName> <playstyle> usage.
These changes implement the IceMage feature and ensure proper playstyle selection and event handling while keeping allocations low and behavior consistent.
Major refactor and bugfixes across language loading, kit lifecycle, and event handling:
- LanguageManager: Introduce LangData to hold string and list entries, load YAML lists alongside strings, and centralize retrieval (avoid reloading files at access time).
- GameManager: Use apply {} to configure worldBorder more concisely.
- KitManager.clearAll: Handle offline players by cleaning chargeData without calling lifecycle hooks (onActivate/onDeactivate cannot run for offline players).
- GoblinKit: Track per-player steal BukkitTask, cancel tasks on kit removal, only restore kits if player is still alive, and fix inventory removal by removing cached items and cleaning cache.
- KitEventDispatcher: Use null-safe chaining for victim passive hooks and early-return on non-block-position moves to ignore head-rotation events.
- GameStateListener: Add feastStarted flag placeholder and adjust iron ore handling/messages; add TODO for DB update.
- Extensions: Change legacySerializer visibility to internal.
These changes improve stability around scheduled tasks, offline cleanup, and language list support.
Include the default prefix as a placeholder when deserializing messages (LanguageManager). Pass the invincibility time placeholder in GameManager broadcasts. Unify GoblinKit action bar messages to a single "ability_charged" language key. ScoreboardManager now imports legacySerializer and serializes the selected kit display name for the scoreboard. Large update to en_US.yml: added many game/timer/title/antirunner/build/craft/commands translations, updated player welcome and scoreboard title coloring, and added kits.goblin names, lore, items and messages.
Introduce a full kit framework and supporting utilities.
- Add core kit API: Kit, Playstyle, ActiveAbility, PassiveAbility, AbilityResult, charge state and PlayerChargeData.
- Implement KitManager for registration, lobby selections, apply/remove/clear lifecycle and charge tracking.
- Add KitEventDispatcher listener to centralize kit event handling (interact, hits, move) and integrate passive/active hooks.
- Provide example kit implementations: GoblinKit (functional abilities) and TemplateKit (reference).
- Add utilities: ItemBuilder and WorldEditUtils (WorldEdit-based sphere creation).
- Integrate into plugin: SpeedHG now initialises KitManager, registers kits and KitEventDispatcher, applies kits at game start and clears on end.
- LanguageManager: add default message/list/component helpers.
- Build changes: bump Kotlin plugin to 2.2.0 and add WorldEdit compileOnly deps; also expose legacySerializer in Extensions.
These changes implement the kit feature set (items, abilities, charge/recharge flow) and wire it into the game lifecycle.
Large refactor removing many legacy subsystems (abilities, kit system, database repos, recraft, world manager, extensive config classes, lunar/luckperms integrations and various listeners/commands). Introduces a lightweight LanguageManager, AntiRunningManager, ScoreboardManager, ConnectListener and a SoupListener; simplifies the main SpeedHG plugin to initialize these components and register the connection listener. Build changes: update Gradle wrapper to 8.10, remove paperweight and several external dependencies, add fr.mrmicky:fastboard and simplify shadowJar/build task configuration. Adds default language resource (languages/en_US.yml) and updates plugin/config resources. Purpose: simplify and decouple the plugin, reduce dependency surface and prepare for a leaner, modular rewrite.