From b883712c2ae95938eecb3728d0ca72ec142c8799 Mon Sep 17 00:00:00 2001 From: kayos Date: Sat, 7 Mar 2026 11:26:28 -0800 Subject: [PATCH] docs: add CHANGES.md with full changelog --- CHANGES.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 CHANGES.md diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 00000000..abf3a568 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,59 @@ +# Changelog — Dynmap NeoForge 1.21.1 Port + +All changes relative to the upstream `neoforge-1.20.6` module. + +--- + +## [Unreleased] — canOcclude() fix + +### Changed +- `DynmapPlugin.initializeBlockStates()`: replaced `isSolidRender(EmptyBlockGetter.INSTANCE, BlockPos.ZERO)` with `canOcclude()` + +### Why +`isSolidRender()` triggers a Guava `LoadingCache` lookup that deadlocks when performance mods (e.g. `modernfix`) use lazy/deferred block state cache generation. This causes the server watchdog to kill the process after a ~60s hang during world load. + +`canOcclude()` reads a precomputed boolean directly from the block state with no cache involvement — functionally equivalent for Dynmap's purposes and safe with all mods. + +--- + +## [2026-03-07] — Runtime fixes + build improvements + +### Fixed — API changes (1.21.1) +- `DynmapPlugin`: `ServerTickEvent` listener updated to `ServerTickEvent.Post` + - NeoForge 21.x made `ServerTickEvent` abstract; registering the base class directly no longer works +- `DynmapPlugin.initializeBlockStates()`: replaced `isSolidRender(null, ...)` with `isSolidRender(EmptyBlockGetter.INSTANCE, BlockPos.ZERO)` + - 1.21.1 actually uses the BlockGetter parameter; passing null causes NPE +- `ForgeMapChunkCache`: replaced `visibleChunkMap` direct field access with `getChunks()` iteration + - `visibleChunkMap` field was removed in 1.21.1 +- `ForgeMapChunkCache`: replaced `getChunkToSend()` with `getLatestChunk()` + - `getChunkToSend()` was removed in 1.21.1 +- `ForgeWorld.getWorldName()`: replaced `serverLevelData.getLevelName()` with `getServerLevelData().getLevelName()` + - Field became private in 1.21.1 + +### Fixed — Build +- `build.gradle`: Fixed `shadowJar` configuration — DynmapCore libs now in `shadow` config (not just `implementation`) + - Was producing a hollow 80KB jar missing all core classes; now produces correct fat jar (~35MB) +- `build.gradle`: Added `build.dependsOn(shadowJar)` so standard `./gradlew build` produces the fat jar +- `build.gradle`: Forked javac heap capped at `-Xmx3g` via `JavaCompile.forkOptions` +- `gradle.properties`: Gradle daemon heap capped at `-Xmx2g` (was `-Xmx4g`, caused OOM on high-RAM hosts) + +### Notes +- Gradle wrapper must stay at **8.7** — upgrading to 8.14 breaks the `fabric-loom` plugin in other monorepo modules + +--- + +## [2026-03-07] — Initial 1.21.1 compile fix pass + +### Fixed — Compile errors (43 total) +All compile errors resolved when porting from the `neoforge-1.20.6` module baseline: +- NeoForge userdev Gradle plugin updated: `net.neoforged.gradle.userdev` → `7.1.20` +- NeoForge dependency version: `21.1.219` +- Various API removals/renames across `DynmapPlugin.java`, `ForgeMapChunkCache.java`, `ForgeWorld.java` +- Access transformer updated for 1.21.1 private field access patterns + - One AT warning remains (`read(ChunkPos)CompletableFuture` not found) — harmless, can be cleaned up + +--- + +## Format + +Entries are dated by session (not release), since this is a port-in-progress, not a versioned release.