Phase 9: implement forge-1_7_10 leaf (WS, deltas, chat, link, reconciliation, player tracking)

Ports the full feature set proven by forge-1_12_2 (Phases 1-2-3-7-7b) to MC 1.7.10's
older, pre-block-state Forge/FML generation: Forge1710ChunkAdapter reads raw Block+meta
via Chunk/ExtendedBlockStorage instead of IBlockState, hooks BlockEvent/ChunkEvent/TickEvent
under cpw.mods.fml, and MCMapperMod/LinkCommand/Forge1710ChatBridge adapt to 1.7.10's
CommandBase/ChatComponentText/ServerConfigurationManager API shapes. No MultiPlaceEvent hook
at this Forge version (falls back to the reconciliation sweep for multi-block placements).
Verified against real Forge 10.13.4.1614-1.7.10 via ./gradlew :forge-1_7_10:build.
This commit is contained in:
2026-08-09 22:13:45 +02:00
parent 890ce46c4f
commit 0d8e670cd8
5 changed files with 482 additions and 8 deletions
+12 -5
View File
@@ -14,8 +14,10 @@ in Claude Code's plan mode.
- `forge-1_12_2/`**primary leaf**, MC 1.12.2 Forge. First implemented; this is the actual
driving use case (an Enigmatica 2 modpack server). Builds with legacy ForgeGradle 2.3 via
anatawa12's Gradle-7-compatible fork (see `THIRD_PARTY_NOTICES.md`).
- `forge-1_7_10/` — MC 1.7.10 Forge. Second priority. Builds with legacy ForgeGradle 1.2, same
fork family, one Forge-tooling generation further back.
- `forge-1_7_10/` — MC 1.7.10 Forge (Phase 9). Second priority, fully wired against the same
`common` interfaces as `forge-1_12_2`. Builds with legacy ForgeGradle 1.2, same fork family, one
Forge-tooling generation further back — pre-block-state (raw `Block` + metadata int, no
`IBlockState`) and pre-FML-repackage (`cpw.mods.fml.*`, not `net.minecraftforge.fml.*`).
- `neoforge-26_1/` — MC 26.1.2 (NeoForge, assumed). Lowest MVP priority. Structurally scaffolded,
not yet wired into the default build (see `settings.gradle`).
@@ -43,7 +45,7 @@ needs Gradle 8+ and JDK 17+ (ModDevGradle), incompatible with the legacy leaves'
within one Gradle invocation; see `settings.gradle`'s comment for the workaround until Phase 10
gives it a proper isolated build.
## Configuration (Phase 1: forge-1_12_2)
## Configuration (forge-1_12_2 and forge-1_7_10)
On first server start the leaf writes `config/mcmapper.cfg` with defaults. Set:
@@ -58,9 +60,14 @@ overworld chunks, and streams event-driven column deltas (block place/break) in
walks a bounded number of currently-loaded chunks per tick (`reconciliationChunksPerSweep`,
default 4) and re-sends any that drifted from what the backend last acknowledged, to catch
mutations event hooks miss (world-gen, other mods, `/fill`). Only the overworld is tracked —
other dimensions and `forge-1_7_10`/`neoforge-26_1` land in later phases. The WS client and
JSON encoding are hand-rolled (no third-party dependency) — see
other dimensions and `neoforge-26_1` land in a later phase. The WS client and JSON encoding are
hand-rolled (no third-party dependency) — see
`common/src/main/java/.../ws/SimpleWebSocketClient.java` and `.../json/MiniJson.java` for why.
`forge-1_7_10` implements the identical config/flush/reconciliation/player-tracking behavior
against 1.7.10's own API generation (see `Forge1710ChunkAdapter`'s javadoc for what differs) — it
has no `MultiPlaceEvent` hook (that class doesn't reliably exist at this Forge version), so
multi-block placements like doors/beds are only caught by the reconciliation sweep rather than
immediately, unlike `forge-1_12_2`.
### Player position tracking (Phase 7b)