Wave Defense

A versatile PvE and PvP engine featuring wave defense, customizable shops, and three competitive game modes for Minecraft

File Details

wavedefense-0.2.40.2.jar

  • R
  • Apr 20, 2026
  • 568.41 KB
  • 15
  • 1.20.1
  • Forge

File Name

wavedefense-0.2.40.2.jar

Supported Versions

  • 1.20.1

Curse Maven Snippet

Forge

implementation fg.deobf("curse.maven:wave-defense-1492909:7954404")
Curse Maven does not yet support mods that have disabled 3rd party sharing

Learn more about Curse Maven

Changelog

[0.2.40] - 2026-04-18

Added — Full i18n / Localization overhaul

The mod now fully integrates with Minecraft's translation system. Players with any interface language see all text in their own language — no hardcoded strings remain in player-facing output.

  • ~53 Java files fixed — replaced Component.literal("text") with Component.translatable("key") and I18n.get() throughout all GUI screens, game logic, network packets, and event handlers
  • 224 translation keys per language file, covering all UI screens, HUD strings, chat messages, tooltips, and admin menus
  • Added ~80 new translation keys to en_us.json and uk_ua.json: PvP HUD strings, lobby/portal/boundary messages, PlayerSettings, HudEdit, HudLayout presets, AdminMenu, server-side game messages, wave/round/match events, completion rewards
  • 6 new language files (complete translation of all 224 keys):
    • 🇩🇪 de_de.json — Deutsch
    • 🇫🇷 fr_fr.json — Français
    • 🇪🇸 es_es.json — Español
    • 🇵🇱 pl_pl.json — Polski
    • 🇧🇷 pt_br.json — Português (Brasil)
    • 🇨🇳 zh_cn.json — 简体中文
  • WaveManager.java — added broadcastToLocation(String, Component) overload; changed endSessionForLocation to accept a Component directly; all 30+ broadcast calls converted to Component.translatable()
  • HudLayout.Preset — enum now stores a translation key instead of a raw display string; preset buttons rendered via Component.translatable()
  • WaveActionsScreen — tooltip system refactored from text-matching to Map<Button, String> (works correctly regardless of active language)
  • HudOverlay — PvP HUD status lines (pvp.buy_phasepvp.round_activepvp.waiting) converted from hardcoded Ukrainian to i18n keys
  • PlayerSettingsScreenHudEditScreenAdminMenuScreenCompletionRewardScreen — all labels, buttons, hints, and error messages converted to translatable keys
  • KeyBindings.java — "leaving location" and "shop unavailable in spectator" messages converted
  • All network packets (PurchaseItemPacketTeleportPacketImportLocationPacketExportLocationPacketAdminTeleportPacket) — server responses now use Component.translatable(), resolving client-side in the player's language

Fixed — Scroll buttons in 8 admin screens (critical UI bug)

Scroll buttons (▲/▼) in 8 admin screens were registered via addRenderableWidget() and fell under the scissor clip — they became invisible and unclickable when a list appeared.

Fixed (addRenderableWidget → addStatic):

  • AdminMenuScreen — location list
  • CompletionRewardScreen — reward list
  • WaveConfigScreen — wave list
  • PlayerMenuScreen — location list for player
  • PlayerShopScreen — item list
  • MobSelectionScreen — mob list
  • WaveMobsEditorScreen — wave mob list
  • LocationEditorScreen — mob spawn point list

Fixed — Memory leak on player disconnect

When a player disconnected while inside a location, playerDataplayerBackups, and reEntryCooldowns were not cleaned up. Added a PlayerLoggedOutEvent handler in EventHandler: on logout, surrenderPlayer() is called, properly restoring inventory and clearing all internal maps.

Fixed — reEntryCooldowns memory leak

Entries in reEntryCooldowns (UUID → timestamp) accumulated indefinitely. Added automatic removal of expired entries once per minute (every 1 200 ticks).

Fixed — PurchaseItemPacket (TOCTOU + NPE)

  • References to ShopPointsourceList, and ShopItem are now captured atomically
  • Added null checks at every step (guards against NPE when an admin edits the shop concurrently)

Fixed — ImportExportScreen rebuild race

rebuildWidgets() could run after the screen was already closed (packet arrives while the player has opened a different screen). Added a minecraft.screen == this guard before rebuild.

Optimization — getPlayersInLocation() per-tick cache

The method was called 40+ times per tick, each time iterating over all playerData (O(n) per call). It now builds a shared Map<String, List<ServerPlayer>> once per tick; all subsequent calls are O(1) lookups. The cache is invalidated on player join/leave.

Optimization — HudOverlay rendering

  • Eliminated duplicate mc.font.width() calls (previously computed separately for each line)
  • Block width is now calculated in a single pass