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.54.1.jar

  • R
  • Jun 1, 2026
  • 1.03 MB
  • 0
  • 1.20.1
  • Forge

File Name

wavedefense-0.2.54.1.jar

Supported Versions

  • 1.20.1

Curse Maven Snippet

Forge

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

Learn more about Curse Maven

[0.2.54.1] - 2026-06-02 (hotfix)

Fixed — Tacz bulk-add: capture all gun variants, not just defaults

TaczCompat.discoverGuns() deduplicated by gunId alone, which collapsed every NBT variant the gunpack author placed in the creative tab (a gun with default attachments vs. the same gun pre-fit with a scope, suppressor, paint job, etc.) into a single "default" entry. Bulk-add therefore lost the pre-built loadouts and the admin saw only one item per gun.

Dedupe key changed from gunId to a full stable-NBT key (item id + NBT compound minus the cosmetic display/Damage/RepairCost fields), mirroring the dedupe ItemSelectionScreen uses for the general picker. Every visually-distinct stack from the Tacz creative tabs now becomes a separate TaczGunEntry and a separate shop item.

Fixed — Tactical minimap facing arrow direction

MinimapRenderer.render() applied three sign inversions to the yaw vector when computing the facing-arrow tip, leaving the arrow rotated by 90°. Replaced with the correct Minecraft → screen transform: dx = -sin(yaw)dz = cos(yaw), then map straight to screen +x / +y.

Audit

Ran a thorough audit of 0.2.54 changes. Apart from the two fixes above:

  • Server-side stat double-count claims were false positives — EventHandler.onEntityDeath is if/else (PvP-kill or env-death, never both).
  • BulkAddShopItemsPacket handler / chunking math verified correct.
  • BBox NBT backward-compat: old saves missing bboxMin/bboxMax keys load as null and cleanly disable the minimap.
  • SyncTeammatesPacket.PlayerEntry overload pair is unambiguous — no positional-arg confusion at any call site.

[0.2.54] - 2026-06-02

Fixed — Tacz bulk-add crash with 107+ guns (CRITICAL)

TaczBulkAddScreen.addCategory() previously appended every gun to the location's shopItems list locally and then sent one UpdateLocationPacket containing the entire serialised location. With 100+ Tacz guns (vanilla + datapacks), the NBT payload exceeds Forge's safe channel size and the client disconnects on send (or the server fails to decode and drops the player).

New packet BulkAddShopItemsPacket (C→S) carries only:

  • the target location name
  • a batch of ShopItem entries (CompoundTag list)

Server appends, saves once, and broadcasts a single SyncShopPacket to players currently inside the location. Permission check requires level 2+.

ChunkingTaczBulkAddScreen now splits the gun list into batches of 25 items per packet (~6-8 KB each). Even a 500-gun datapack now adds in 20 small packets instead of one ~250 KB monster, eliminating the crash and giving realistic progress on slow connections.

Added — Optional location bbox + tactical PvP minimap

Location gains 3 optional fields:

  • bboxMin / bboxMax — two corner BlockPos defining an axis-aligned cube
  • minimapEnabled — toggle for the tactical HUD

A new section "🗺 Location BBox & Minimap" appears at the top of the LocationEditor Special tab with:

  • "Here" buttons for each corner (uses player's current position)
  • "✕" clear buttons
  • A minimap on/off toggle (disabled until both corners are set)

When minimapEnabled is true AND both corners are set AND the player is in a PvP match, a new MinimapRenderer draws a top-down tactical map in the bottom-left of the HUD (96×96 px):

  • BBox region scaled to fit, with 3×3 grid lines
  • Dots for every teammate (data from existing ClientTeammatesManager)
  • Local player marker (bright green) + facing-direction indicator
  • Dead teammates shown in grey
  • Enemies are NOT shown by design — no wallhack

Teammate position sync

SyncTeammatesPacket.PlayerEntry extended with (double x, y, z, float yaw)WaveManager.syncTeammates() populates positions; ClientTeammatesManager stores them for the minimap. Existing per-second sync (added in 0.2.53.7) keeps dots moving in real time.

New files

  • network/packets/BulkAddShopItemsPacket.java
  • gui/MinimapRenderer.java

New translation keys (× 8 langs)

section.bboxbbox.corner1_unset / corner2_unsetbbox.set_herebbox.minimap_on / minimap_offbbox.hint (7 keys total).


[0.2.53.7] - 2026-06-02

Fixed — Anti-cheat hitbox disable now covers PvE too

ClientEventHandler.onClientTick() previously only disabled the client-side hitbox renderer when data.isInPvp() was true. PvE players could keep F3+B turned on and see mob outlines through walls. Now the check is isInPvp() || isInWave() — any active Wave Defense session forces hitbox rendering off.

Fixed — Teammate HUD HP bars not updating in real time

syncTeammates() was called only at join / leave / death. While a teammate took damage between deaths the HUD bar stayed full. Added a 20-tick periodic sync in WaveManager.onServerTick() so each active location pushes a fresh SyncTeammatesPacket to every player once per second.

Fixed — BR border damage during initial wait phase

BattleRoyaleManager.tick() was applying border damage to players outside the (still-static) radius even during the configured "initial wait" phase — i.e. before the border started shrinking. Damage now applies only after the initialWaitTicker reaches zero, giving players the intended grace period to spread out.

Added — Tile mode in admin shop editor

ShopEditorScreen (global shop view) gains a tileMode toggle next to the "Add item" / "Tacz bulk" buttons, mirroring the PlayerShopScreen UX. Tile mode shows shop items as 112×84 cards with the primary icon, name, buy/sell prices, availability trigger badge, plus Edit / Delete buttons inside each tile. List mode (default) is unchanged.

Reuses the existing wavedefense.shop.view_tiles / wavedefense.shop.view_list translation keys.


[0.2.53.6] - 2026-06-01 (hotfix)

Fixed — PvP Standard round ending instantly after BUY phase

Two players who picked the same team (either through spawn-point misconfiguration or by both clicking the same team in the selector) would see the match end the moment the BUY phase finished. PvpRoundState.checkRoundWinner() returns the team-name once every alive player belongs to a single team — which is the right answer during a round in progress, but is wrong at round start when there's nobody on the other team yet.

checkRoundWinner() now additionally verifies that at least 2 distinct teams have ever been registered in the match before declaring a winner. If only one team is represented (degenerate setup or opponents not yet joined), it returns null instead.

Side effects:

  • BR/DM/CtP/KotH untouched — they use their own win predicates (checkBrWinnercheckDmWinnerCapturePointManager).
  • Standard matches with pvpRoundTimeLimitSec > 0 will still end on timeout if opponents never join (handled by the existing time-limit logic).
  • startActiveRound() now broadcasts a yellow  warning if the round starts with only one team represented, plus logs to the server log so the admin immediately understands the configuration issue.

Fixed — IndexOutOfBoundsException on PvP join with stale spawnIndex

PvpRoundManager.addPlayerToPvpLocation() did location.getPvpSpawnPoints().get(spawnIndex) with no bounds check. A stale TeleportPacket (admin deleted a spawn point between team selection and join) or a malicious client could throw IOOBE, leaving the player half-joined (playerBackups populated, no session).

Now:

  • Empty spawn-points list → join rejected with wavedefense.msg.pvp_no_spawn_points message, backup cleared.
  • Out-of-range index → clamped to 0 with a server log warning.

New lang keys (× 8 languages)

wavedefense.msg.pvp_no_spawn_pointswavedefense.msg.pvp_insufficient_teams