Test-first from here on (per request after Phase 2's backend commit): LinkCodeGenerator has a standalone test (common/src/test) written and confirmed failing before the implementation existed. common: LinkCodeGenerator produces a 6-character code from an unambiguous charset (excludes 0/O/1/I/L — it gets read off a chat line and typed back). BackendConnection grows sendLinkRequest (now actually implemented, was a Phase 1 stub), sendChatMessage, and setChatListener/ ChatListener for inbound web->game chat, all wired into DefaultBackendConnection's existing JSON wire protocol. forge-1_12_2: LinkCommand (/mcmapper link) generates a code, resolves online/offline from the server's actual auth mode (MinecraftServer#isServerInOnlineMode), and shows it to the player. Forge1122ChatBridge implements the inbound half (injects web chat into real in-game chat via the player list) — injectWaypointShare is a documented Phase 4 stub, same pattern as sendLinkRequest was in Phase 1. MCMapperMod hooks ServerChatEvent to forward in-game chat out and wires the chat listener to the bridge. Verified end-to-end against a live MCMapper-Backend instance through the real Java client (not a stand-in): a mod-generated link code correctly redeems via the backend's HTTP endpoint to an account with the mod- supplied username, and a browser chat message correctly round-trips all the way to the mod's live ChatListener callback.
common
Loader-agnostic Java: protocol types, config model, and the interfaces each leaf module
(forge-1_7_10, forge-1_12_2, neoforge-26_1) implements against its own Minecraft/Forge
API generation.
This module is not consumed as a compiled binary dependency. The legacy leaves (1.7.10,
1.12.2) target Java 8; neoforge-26_1 targets a modern JDK. To avoid cross-version binary
compatibility issues, each leaf module adds common/src/main/java directly to its own source
set (see the sourceSets.main.java.srcDirs line in each leaf's build.gradle) and compiles it
itself, once per leaf, against its own toolchain. Keep this module free of any
Minecraft/Forge/NeoForge API usage — it must compile standalone under plain javac.
Layout
protocol/— wire types shared with the backend (delta events, chat/waypoint payloads, link request/response). Mirrors the WS protocol described in the root plan.config/— the common config model (backend URL, server token, tracking/reconciliation intervals) each leaf loads via its own loader-specific config system.json/,ws/— the hand-rolled JSON codec and RFC 6455 WS clientDefaultBackendConnectionis built on (no third-party dependency, for the same "no shading through legacy ForgeGradle" reason this module stays dependency-free generally).
Testing
bash run-tests.sh
Compiles src/main/java + src/test/java and runs every *Test.java class's main(). No
JUnit/Gradle — same "must compile standalone under plain javac" constraint as the module
itself, and test code never ships in the mod jar so it doesn't need to match either leaf's JDK 8
target. Anything needing a live Forge/Minecraft world (event hook wiring, world reads) isn't
unit-testable this way — those stay integration-tested against a real running
MCMapper-Backend instance instead (see the Phase 1/2 commit messages for how that's been done
so far).