Turret system completely non-functional — Adventure vs. Legacy API mismatch (BF-16) —
The crafting recipe assigned the "Sentry Turret" display name via the Adventure API
(meta.displayName(Component.text(...))). TurretListener.isTurretItem() read the name
with the deprecated Legacy API (meta.getDisplayName()), which always returns an empty
string when the name was set via Adventure — so the check never matched and
TurretManager.createTurret() was never called. Placing a crafted turret had no effect.
isTurretItem() now reads the Adventure displayName() component first, serialises it to
plain text, and falls back to the legacy accessor for pre-migration items.
onDisable() never called turretManager.cleanup() — turret data loss on restart (BF-17) —
CampfireManager.shutdown() was called in onDisable() but the analogous
TurretManager.cleanup() call was absent. cleanup() is responsible for cancelling the
internal firing task and flushing turrets_data.yml. Turrets placed during a session
without a prior auto-save were silently lost on server restart.
turretManager.cleanup() is now called from onDisable().
/zapoc reload wiped all zombie custom AI — missing scanExistingZombies() call (BF-19) —
loadConfig() (called by loadAllConfigs() at the start of every reload) called
trackedZombies.clear(). ZombieBehaviorTask iterates that collection each tick; after
a reload it was empty, so every living custom zombie lost its AI (no moans, no screaming,
no sun effect, no mutation) until the zombie died or new ones spawned.
scanExistingZombies() is now called at the end of the reload handler to repopulate
the map immediately.
/zapoc reload did not rebuild TurretManager — config changes had no effect (BF-18) —
TurretManager reads range, damage, and fire-rate-ticks only in its constructor.
After a reload the old instance kept running with stale values. The reload handler now
calls turretManager.cleanup() and recreates a fresh TurretManager, matching the
pattern already applied to StructureManager.
Feign-Death zombie permanently invulnerable and AI-less after server restart (BF-20) —
When a Feign-Death zombie "died", the code set invulnerable=true and AI=false, then
scheduled a BukkitRunnable to revive it after 3–5 s. If the server restarted during
that window, the task was discarded but the entity flags persisted in NBT — leaving an
immortal, motionless zombie that could never be killed. A new PDC key feign_active is
set at the start of feign-death and cleared on revive. ZombieCleanupListener.onChunkLoad
now detects this key and immediately invokes the shared SpecialZombieListener.reviveZombie()
method, which also handles the scheduled revive path.
CampfireManager.damageCampfire() triggered a full YAML write on every zombie hit (BF-21) —
saveCampfires() (atomic file I/O on the main thread) was called each time a zombie
attacked a campfire. With multiple zombies attacking multiple campfires simultaneously
during a Blood Moon, this caused significant main-thread stalls. Replaced with a dirty
flag: damage marks the campfire data as dirty, and the periodic task flushes to disk at
most once every ~5 seconds. Immediate saves are still performed when a campfire is
destroyed.
ZombieBehaviorTask.handleScreamer() read 6 YAML values per zombie per 0.5 s (BF-23) —
Every invocation of handleScreamer() called getZombiesConfig().getDouble/getString/getInt()
six times. With 20 Screamer zombies that is 120 YAML map lookups per 500 ms. All six
values (scream-chance, particle, particle-count, scream-range, darkness-duration,
message) are now cached in the same 5-second refresh cycle used by sun-effect config.
ZombieBehaviorTask.handleBreaker() read success-chance from YAML per zombie per 2 s (BF-24) —
zombie-breaking.success-chance was fetched from FileConfiguration inside the per-zombie
loop every 40 ticks. Now cached alongside the other task-level values.
PsychologicalHorrorTask.activeHallucinations used entity ID (int) as map key (BF-25) —
Entity IDs are 32-bit integers reused by the server after an entity despawns. Using
entity.getEntityId() as the map key could cause stale HallucinationData entries to
collide with or shadow new entries sharing the same recycled ID.
The key type is now UUID (entity.getUniqueId()), which is guaranteed unique per entity.
Campfire heal task used 3×3 chunk scan instead of 5×5 (BF-22) —
isInsideSafeZone() and onSpawn() were already corrected to 5×5 in a prior release,
but the heal loop inside startTask() still searched only 3×3 chunks (~32 block reach).
Tier-3 campfires have a 40-block radius, so players near the edge of the safe zone
were not receiving the Regeneration effect. The heal loop now uses 5×5, consistent with
all other campfire range checks.
data.yml, campfires.yml, and
turrets_data.yml files are fully compatible with 4.5.1.turrets_data.yml will
load and function normally. Turrets placed during a session that ended with a 4.5.0
server stop without an intermediate save may have been lost — this is the bug being fixed.
ZombieApocalypseSSS is a comprehensive Minecraft plugin that transforms your server into a thrilling zombie survival apocalypse. Featuring advanced zombie AI, evolving variants, player infection mechanics, psychological horror elements, and dynamic events