## [4.0] - 2026-03-12 - Update Checker + Version Bump
### ✨ New Features
- **Modrinth Update Checker** — The plugin now checks for new versions on Modrinth during server startup.
- Runs fully **async**; won't lag the main thread even if the network is slow.
- If an update is available: Prints a clear console notification showing current vs. latest version.
- Admins with the `zapoc.admin` permission receive a chat notification upon joining (delayed by 2 seconds to avoid being buried by other login messages).
- Can be completely disabled via `update-checker: false` in `config.yml`.
- Class: `UpdateChecker.java` — implements `Listener` to hook into `PlayerJoinEvent`.
### 🐛 Bug Fixes
- **Messages never loaded (Critical)** — `loadConfig()` called `saveResource("messages_vi.yml")`, but the file is located at `language/messages_vi.yml` inside the JAR. `saveResource` threw a startup exception, leaving `messagesConfig` empty—resulting in every `getMessage()` call returning `§cMissing key: ...`. Fixed by using the correct sub-path and ensuring parent directories are created if missing.
- **`/zapoc panic` spawned vanilla zombies** — The command called `ZombieSpawnService.transformZombie(z, "random")`, but `"random"` is not a valid key in the `zombieTypes` map. This caused `data == null`, making the method return immediately without applying stats, AI, or types. All 15 panic zombies were plain vanilla. Fixed by calling `ZombieSpawnService.randomizeZombie(z)`.
- **Supply drop interval ignored config** — `WorldEventTask.calculateNextDrop()` attempted to read `plugin.getPluginConfig().getLong("supply-drop.interval")` from `config.yml`, but the key is actually defined in `events.yml`. The interval always defaulted to the hardcoded 18,000 ticks. Fixed by reading from `plugin.getEventsConfig()`.
- **Sun effect settings ignored config** — `ZombieBehaviorTask.handleSunEffect()` attempted to read `sun-effect.mode`, `sun-effect.light-threshold`, and related keys from `plugin.getPluginConfig()` (`config.yml`), but those keys reside in `sun-effect.yml`. Sun slow/burn modes always used hardcoded defaults. Fixed by reading from `plugin.getSunEffectConfig()`.
### ⚠️ Minor Fixes
- **Bleeding tick check unreliable** — `PlayerStatusTask` used `Bukkit.getCurrentTick() % 40 == 0` to throttle bleeding damage to every 2 seconds. Because the server tick counter and task invocation aren't perfectly aligned, the check fired inconsistently. Replaced with a local `tickCount` field incremented on each run.
- **`canSpawnMutated()` allowed 2 Mutated per chunk** — The method returned `count < 2` despite a comment explicitly stating the design cap is 1 per chunk. Adjusted to `count < 1`.
- **`ZombieApocRefactored.java` removed** — Cleaned up a dead-code class from a previous refactor attempt. It was never used as the main class and contained inverted command logic. Deleted entirely.
Developer information
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle.
maven { name = "Modrinth"; url = "https://api.modrinth.com/maven" }