Replace the old dynamic /team invite system with a fixed GUI-based preset team implementation. Removes TeamManager, Team, TeamListener and the TeamCommand, and introduces PresetTeam, PresetTeamManager and GUI listeners/menus (TeamSelectionMenu/TeamSelectionListener). Codepaths that referenced teamManager were migrated to presetTeamManager (GameManager win/compass logic, Lunar rich presence, Oracle perk, scoreboards, tablist, lobby items). Lobby now shows a team wool item when teams are enabled and the tablist/scoreboard display and prefix logic were adapted to reflect preset teams. Configuration supports teams.enabled, teams.preset-count and teams.max-size; scheduled invite cleanup and old team-reset logic were removed accordingly.
Include the configured lunarclient.variantName in the game start Discord embed and expose both the lunar variant and the player's selected playstyle on the lobby/ingame scoreboards. Added placeholders to language file for variant and style. Files changed: GameManager.kt, ScoreboardManager.kt, and en_US.yml.
Add a delayed task (runTaskLater 10L) that retrieves the "world" and configures its WorldBorder: center at (0,0,0), size set to startBorder, damageBuffer set to 0.0 and damageAmount set to 1.0. Ensures the world border is initialized shortly after plugin startup/world load.
Prevent players from dropping kit-owned items when they die by filtering out kit items before dropping inventory contents. Added KitManager.isKitItem(player, item) which checks the player's selected kit and compares against the kit's cached items (using isSimilar). Also added the ItemStack import required for the new method.
Use Rank info in leaderboard display (adds playerrank, passes numeric score) and adjust message placeholders. Add prefix placeholder injection in LanguageManager. Introduce max-radius-teleport config and use it for player teleport on join. Restore broadcasting of player quit messages on disconnect. Enforce no-iron crafting before feast (deny craft, notify player & play sound) and cancel entity spawns until feast starts. Update config.yml with max-radius-teleport and refresh en_US language strings (add no_iron_before_feast and translate/update several GUI/perk entries).
Introduce LobbyItemManager to provide interactive lobby hotbar items (kits & perks) tagged via PersistentDataContainer and open the appropriate GUIs. Wire the manager into SpeedHG (field, init, event registration) and clear lobby items at game start in GameManager. Add ItemBuilder.pdc helper and necessary imports for setting PDC. Fix potion duration calculation to use invincibilityTime*20. Change AnchorKit icon/trigger material to ANVIL. Update config (border start/end/shrink and disable anti-runner) and update en_US language entries (lobby item names, leaderboard format, kit lore/formatting and small text fixes).
Introduce a full in-memory team system and integrate it into gameplay and UI.
- Add Team, TeamManager, TeamListener and TeamCommand to manage teams, invites, accept/deny, leave, kick and info. TeamManager stores teams and pending invites (INVITE_TTL_MS) using concurrent maps and exposes helper/query methods (areInSameTeam, allAliveInSameTeam, getInviterFor, cleanExpiredInvites, reset).
- Wire TeamManager into SpeedHG: initialize, schedule periodic invite cleanup, register command and listener, and reset teams on plugin disable.
- Update GameManager to consider teams for win conditions, build team winner names, exclude teammates from random teleport/compass logic, and credit all winning team members for stats/ranking.
- Move ability charge feedback out of individual kits into KitEventDispatcher: remove per-kit onFullyCharged overrides and add centralized ActionBar/sound feedback (sendChargeUpdateActionBar/sendChargeReadyActionBar). ActiveAbility no longer defines onFullyCharged.
- Make OraclePerk ignore teammates when finding nearest enemy.
- Add config entries for teams and corresponding language strings; tweak some default values in CustomGameSettings (gladiator arena radius/height and minor formatting changes).
These changes enable 2-player teams (configurable), friendly-fire prevention, invite lifecycle handling, and team-aware endgame logic.
Introduce three new kits (Anchor, Puppet, Tesla) and multiple perks, plus related plumbing and behavior changes. Key changes:
- Added kit implementations: AnchorKit (summon iron-golem anchor, knockback resistance/radius effects), PuppetKit (life-drain / fear abilities), TeslaKit (lightning active + passive knockback/fire aura).
- Register new kits and register new perks in SpeedHG startup.
- Added new perks: AdrenalinePerk (post-damage speed proc with cooldown), EnderbluePerk (ender-pearl fall damage handling), Ghost, Pyromaniac, Scavenger (and updated OraclePerk/PerkEventDispatcher usage).
- Extended Perk API (Perk.kt) with onEnderPearlDamage and onPostDamage hooks to support specialized damage handling and post-damage checks.
- PerkManager.isGhost added for checking Ghost perk selection and used to exclude ghost players from targeting/compass logic.
- GameManager.updateCompass now excludes ghost-perk players when computing compass targets.
- Updated PerkEventDispatcher and OraclePerk to integrate new hooks and behaviors.
- Minor language additions in en_US.yml to support new kits/perks.
These changes add new gameplay mechanics and ensure correct event dispatching for pearl/fall/post-damage cases and ghost invisibility to game tracking.
Introduce a complete passive perk system: Perk base class, PerkManager (registration, selection, lifecycle, persistence), and PlayerPerksRepository (DB schema + upsert/find). Add four example perks (Oracle, Vampire, Featherweight, Bloodlust) and a single PerkEventDispatcher to route combat/environment/kill events to active perks. Provide PerkSelectorMenu GUI and /perks command, integrate perk initialization, registration, application and cleanup into SpeedHG and GameManager, and hook load/evict into StatsListener. Also add language entries and register the command in plugin.yml. This change enables players to select up to two passive perks, persists selections, and dispatches relevant events to perk implementations.
Introduce a PodiumManager to run an end-of-round podium ceremony and integrate it into the lifecycle. Key changes:
- Add PodiumManager (new): builds podium columns, teleports and freezes top-3 players, spawns TextDisplay entities, posts staggered announcements, and runs a ranked firework show; includes cleanup to remove entities, blocks and cancel tasks.
- SpeedHG: initialize podiumManager and call podiumManager.cleanup() on disable.
- GameManager: trigger plugin.podiumManager.launch(winnerUUID) shortly after the win announcement.
- RankingManager: track elimination order during the round and expose getEliminationOrder() to determine placements.
- Rank: add sub-tier logic (I/II/III), firework color, and helper methods to produce formatted MiniMessage rank tags/components; improve cached component/prefix handling.
- ScoreboardManager: use Rank.getFormattedRankName(...) to show the formatted rank with sub-tier on scoreboards.
Purpose: provide a richer end-of-round experience (visuals, sounds, fireworks) and accurate top-3 determination using elimination order while adding rank sub-tiering and formatted rank output for UI elements.
Introduce a new RankingManager that implements a per-round Rank Rating (RR) system (placement + kill-based scoring, placement games, kill caps and RR interpolation). Wire the manager into the plugin (SpeedHG): add field + initialization. Integrate into GameManager: call startRound at game start, registerRoundKill on kills, and onPlayerResult for eliminated players and the winner; adjust some stats calls (addLoss/addWin kept alongside ranking updates). Add corresponding English language messages for placement progress and result notifications.
Introduce a /timer admin command with tab completion (speedhg.admin.timer) and a parseTimeToSeconds utility; add CommandSender.sendMsg extension and language strings. Add RecraftManager module that enforces a configurable recraft-nerf (reduces extra recraft points for alive players) and starts from GameManager; wire the new module into GameManager. Register mushroom-stew shapeless recipes for cocoa and cactus in plugin startup and tidy command registration. Update plugin.yml with permission/command entries and adjust imports as needed.
Introduce two new game modules (FeastManager and PitManager) to handle timed endgame events: announcements, world edits, loot generation, teleportation and escape-prevention logic. Add DiscordWebhookManager to send asynchronous webhook messages (embeds/text) and wire it into SpeedHG and GameManager to broadcast game start/end events. Integrate managers into the game loop and reset lifecycle (startGame), add config entries for Discord, and add corresponding language strings. Also include small tweaks (killer XP reward, minor formatting) and updated resource files.
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.
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.