RDForward

skill
SUMMARY

A modern modding toolchain for Minecraft rd-132211 onwards. Features a custom Fabric implementation, Multiplayer server, Android support, and cross-version compatibility.

README.md

RDForward ⏩

Modernizing History.

Play the first version of Minecraft.

On your phone.

With friends on PC...


Quick Start

Requires Java 21+ and an internet connection (first build only).

# First-time setup: downloads RubyDung from Mojang, decompiles, applies patches
./gradlew :rd-game:setupWorkspace

# Build everything (compile + test + fat JARs)
./gradlew buildAll

# Launch the game (single player)
./gradlew :rd-game:runClient

Why BuildTools?

RDForward uses a Spigot BuildTools-style build process. The original RubyDung code
(rd-132211) is Mojang's copyrighted property and cannot be redistributed. Instead, our
build tool downloads the original JAR from Mojang's CDN, decompiles it with Vineflower,
and applies our patches — all on your machine. Only the patches (our modifications) are
stored in this repository.

Developer Workflow

# After modifying decompiled source in rd-game/src/main/java/:
./gradlew :rd-game:rebuildPatches   # Saves your changes as patch files
# Commit the updated patches in rd-game/patches/

Multiplayer

RDForward adds multiplayer to RubyDung using the Minecraft Classic protocol. Players
can join a shared world, see each other, place/break blocks, and chat.

Running from Gradle (development)

Start the server:

./gradlew :rd-server:runServer

The server listens on port 25565 by default.

Start one or more clients (auto-connects to localhost):

./gradlew :rd-client:runMultiplayer

With custom server address or username:

./gradlew :rd-client:runMultiplayer -PmpServer=192.168.1.5:25565 -PmpUsername=Steve

Running from fat JARs (no build tools needed)

Fat JARs are self-contained — just Java 21+ is required. Build them with:

./gradlew fatJars       # Builds all 3 fat JARs
./gradlew buildAll      # Full build + fat JARs

Output locations:

  • rd-server/build/libs/rd-server-*-all.jar — Dedicated server
  • rd-client/build/libs/rd-client-*-all.jar — Modded client (Fabric Loader + multiplayer)
  • rd-game/build/libs/rd-game-*-all.jar — Vanilla game (single player, no mods)

Start the server:

java -jar rd-server-0.2.0-SNAPSHOT-all.jar           # Default port 25565
java -jar rd-server-0.2.0-SNAPSHOT-all.jar 12345      # Custom port

Start a client:

java -jar rd-client-0.2.0-SNAPSHOT-all.jar                            # Connects to localhost:25565
java -jar rd-client-0.2.0-SNAPSHOT-all.jar --server=example.com:25565  # Remote server
java -jar rd-client-0.2.0-SNAPSHOT-all.jar --username=Alice            # Custom name
java -jar rd-client-0.2.0-SNAPSHOT-all.jar --server=10.0.0.5:25565 --username=Bob

The --server and --username flags also work as JVM properties (must go before -jar):

java -Drdforward.server=example.com:25565 -Drdforward.username=Alice -jar rd-client-0.2.0-SNAPSHOT-all.jar

If no username is provided, the server auto-assigns one (Player1, Player2, etc.).

Multiplayer Features

  • Shared world — configurable dimensions (default 256x64x256), multiple level types (flat, rubydung, classic, alpha)
  • Player rendering — remote players shown as colored cubes with head rotation sync
  • Block sync — place/break blocks visible to all connected players with spawn protection
  • Chat and commands — in-game text messaging, 4-tier op permissions, /ban /kick /whitelist /tp /op /deop and more
  • Auto-naming — server assigns unique names, no duplicates allowed
  • Authentication — optional online-mode with Mojang session verification (Java 1.3+) and Xbox Live JWT validation (Bedrock)
  • Server configuration — vanilla-compatible server.properties with launcher-style version IDs
  • World conversion — auto-detects and converts between RubyDung, Alpha, and McRegion formats at startup
  • Legacy Console support — LCE TU19 (Windows64) clients can join via LAN discovery (UDP broadcast on port 25566) or direct connect, with full cross-play against all other client types
  • Grief protection — behavioral scoring system that distinguishes builders from griefers, with escalating responses (warning, freeze, kick), block ownership tracking, and a mod bypass API
  • Performance — async chunk generation, packet compression (Java 1.8+), flush coalescing, crash-safe atomic saves

Project Structure

This is a Gradle multi-module project:

Module Description
rd-game The game — decompiled RubyDung (generated by BuildTools, not in version control)
rd-protocol Networking — Netty-based packet codec, MC-compatible protocol, version translation
rd-world World persistence — Alpha-format NBT serialization, block registry, world conversion
rd-client Multiplayer client — networking, UI overlays, remote player rendering
rd-server Dedicated server — authoritative world state, tick loop, mod event dispatch
rd-bot Headless bot client for automated testing against the server
rd-e2e End-to-end visual regression tests using headless LWJGL3 clients
rd-e2e-agent Test agent for cross-version E2E scenarios (Java 8 compatible)
rd-api Shared API interfaces

Supported Protocols

The server accepts connections from a wide range of Minecraft clients simultaneously:

Protocol Family Versions Transport
RubyDung rd-132211 (the original) TCP, Classic framing
Classic c0.30 TCP, Classic framing
Alpha a1.0.15 through a1.2.6 TCP, 4-byte length prefix
Alphaver Cypress (modified a1.0.16) TCP, 4-byte length prefix
Beta b1.0 through b1.8 TCP, 4-byte length prefix
Release (pre-Netty) 1.0 through 1.6.4 TCP, 4-byte length prefix
Release (Netty) 1.7.2 through 26.1 TCP, VarInt framing
Legacy Console (LCE) TU19 (v1.6.0560.0) TCP, 4-byte length prefix
MCPE (legacy) 0.6.1 through 0.16.0 (protocols 9-91) UDP, RakNet
Bedrock 1.26.10 (protocol 944) UDP, RakNet

Protocol detection is automatic — the server identifies the client type from the first bytes of the connection and configures the Netty pipeline accordingly. LCE clients are detected by a server-sends-first handshake (300ms timeout), while all other TCP protocols are identified from the first client byte. Alphaver clients (which report the same protocol version as standard Alpha 1.1.0) are detected reactively after login via a client-specific skin request packet.

Key Design Decisions

  • MC-compatible protocol — packet IDs and wire format match real Minecraft across all supported versions
  • Netty for networking (same library modern MC uses) — scalable to 100+ players
  • ViaVersion-inspired version translation — block/action mapping between protocol versions
  • Alpha-compatible world format — worlds can be opened in Minecraft Alpha
  • LWJGL 3.4.1 — ported from LWJGL 2 for Java 21+ compatibility on all platforms (see below)
  • Fabric Loader + SpongePowered Mixin for mod loading and code injection
  • BuildTools approach — no copyrighted code in the repository
  • Lazy-loaded protocol infrastructure — Bedrock palettes, MCPE codecs, LCE packet registries, and version-specific registries are loaded only when a client of that type first connects
  • Canonical chunk serialization — chunks are serialized once into a version-independent intermediate form, then derived per-client protocol cheaply via palette remapping

Grief Protection

The server includes a smart grief detection system that uses behavioral scoring rather than simple rate limits. This allows fast builders to work unimpeded while catching players who destroy other people's builds.

How it works:

  • The server tracks block ownership (who placed each block)
  • Breaking another player's blocks earns grief points; breaking your own or natural blocks does not
  • New players (< 30 min session) receive double grief points
  • Points decay over time (halved every 60 seconds of no grief activity)

Escalating responses:

Score Response
5 Warning message
10 Block interactions frozen for 5 seconds
20 Kicked from the server

Operators are exempt from grief checks. Mods performing bulk block operations can bypass all checks via GriefProtection.runBypassed(() -> { ... }).

Building

Requires Java 21+ and Gradle 8.14+.

./gradlew :rd-game:setupWorkspace   # First-time only: download, decompile, patch

./gradlew build                     # Compile + test all modules
./gradlew fatJars                   # Build all fat JARs (server + client + game)
./gradlew buildAll                  # build + fatJars combined

# Individual fat JARs
./gradlew :rd-server:fatJar         # Server fat JAR only
./gradlew :rd-game:fatJar           # Vanilla game fat JAR only
./gradlew :rd-client:fatModdedJar   # Modded client fat JAR only

Gradle Run Tasks

Task Description
./gradlew :rd-game:runClient Launch vanilla RubyDung (single player, no mods)
./gradlew :rd-client:runModdedClient Launch via Fabric Loader (mods enabled, no multiplayer)
./gradlew :rd-client:runMultiplayer Launch modded client + auto-connect to localhost:25565
./gradlew :rd-server:runServer Launch dedicated multiplayer server

Server Configuration

The server generates a server.properties file on first run with vanilla-compatible settings:

Property Default Description
server-port 25565 TCP port for Java Edition clients
bedrock-port 19132 UDP port for Bedrock/MCPE clients
(auto) 25566 UDP port for LCE LAN discovery broadcasts (not configurable)
server-version rd-132211 World format — launcher-style ID (e.g. rd-132211, a1.2.6, b1.7.3, 1.8.9)
gamemode creative creative or survival
max-players 128 Maximum concurrent players
view-distance 5 Chunk render distance
spawn-protection 16 Radius around spawn where non-ops cannot modify blocks
online-mode false Require Mojang/Xbox authentication
white-list false Restrict access to whitelisted players
level-type rubydung World generator: flat, rubydung, classic, alpha
world-width/height/depth 256/64/256 World dimensions (for finite world types)

Override precedence: CLI args > system properties > file > defaults.

Operator Permissions

The server uses a 4-tier operator permission system (matching vanilla Minecraft):

Level Scope Example commands
1 Spawn bypass Can build in spawn-protected area
2 Cheats /tp, /give, /time
3 Player management /ban, /kick, /whitelist, /op
4 Server admin /stop, /save-all

Operator levels are stored in ops.txt (format: username:level). Command permission mappings can be customized in config/op-permissions.properties.

LWJGL 2 to LWJGL 3 Migration

The original RubyDung (rd-132211) was built against LWJGL 2.9.3. We ported it to
LWJGL 3.4.1 because LWJGL 2's Linux native libraries (liblwjgl64.so) depend on
SUNWprivate_1.1, a private JDK symbol removed in Java 9+. This makes LWJGL 2 unusable
on Linux with modern Java.

What Changed

LWJGL 3 is a complete API rewrite, not a drop-in upgrade. Key differences for developers:

LWJGL 2 LWJGL 3 Notes
Display.create() / setTitle() GLFW.glfwCreateWindow() GLFW replaces the Display class entirely
Keyboard.isKeyDown(int) GLFW.glfwGetKey(window, key) Key codes changed (e.g. Keyboard.KEY_W -> GLFW.GLFW_KEY_W)
Keyboard.next() / event loop glfwSetKeyCallback() Push-based callbacks instead of poll-based event queue
Mouse.getDX() / getDY() glfwSetCursorPosCallback() Must track deltas manually from absolute positions
Mouse.setGrabbed(true) glfwSetInputMode(GLFW_CURSOR, GLFW_CURSOR_DISABLED)
GLU.gluPerspective() Manual matrix math GLU was removed; perspective matrix built by hand
GLU.gluPickMatrix() Manual translate + scale
GLU.gluBuild2DMipmaps() glTexImage2D() + GL30.glGenerateMipmap()
GL11.glVertexPointer(size, stride, buf) GL11.glVertexPointer(size, GL_FLOAT, stride, buf) Explicit type parameter required
GL11.glGetFloat(int, buf) GL11.glGetFloatv(int, buf) Method renamed
Native extraction (manual) Auto-extracted from classpath LWJGL 3 native JARs handle this transparently
BufferUtils + (Buffer) casts BufferUtils (no casts needed) LWJGL 3 returns proper buffer types

Files Affected

All 7 game source files were modified:

  • RubyDung.java — window creation, input handling, GLU replacement
  • Player.java — keyboard input polling
  • Textures.java — mipmap generation
  • Tesselator.java — vertex array pointer calls
  • Frustum.java — GL state queries
  • Chunk.java, LevelRenderer.java — named GL constants

The NativeLauncher and FabricNativeLauncher were simplified since LWJGL 3 auto-extracts
natives from classpath JARs.

References & Acknowledgments

This project would not be possible without the following open source projects, tools, and community resources.

Libraries & Dependencies

Library Usage
Netty TCP networking framework (pipeline-based protocol handling)
CloudburstMC Protocol Bedrock Edition networking (RakNet + codec)
LWJGL 3 OpenGL/GLFW bindings for rendering and input
libGDX Cross-platform game framework (desktop + Android)
Fabric Loader Mod loading framework
SpongePowered Mixin Bytecode-level code injection for modding
Querz NBT NBT serialization for world persistence
ASM Java bytecode manipulation (transitive via Mixin)
SLF4J Logging facade

Protocol Research & Implementation References

Project / Resource How it helped
ViaVersion / ViaLegacy Primary reference for understanding wire format differences between Minecraft protocol versions (Alpha through Release 1.3.x). Version translation logic and packet format changes were cross-referenced against ViaLegacy's protocol classes.
GeyserMC Reference for Bedrock Edition protocol conventions — position semantics (eye vs feet level per packet type), rotation field ordering, and Bedrock chunk serialization patterns.
NukkitX Reference for Bedrock Edition protocol conventions and chunk serialization optimization patterns (palette caching, top-down empty section scanning).
PocketMine-MP Primary reference for legacy MCPE protocol versions 9 through 91 (0.6.1 to 0.16.0). Used for login sequences, spawn ordering, metadata formats, chunk wire formats, and version-specific field semantics across all supported MCPE versions.
Genisys Reference for MCPE 0.16.0 (protocol 91) attribute system, VarInt wire format migration, and adventure settings flag values.
ImagicalMine PocketMine-MP fork for MCPE 0.14.0 (protocol 45). Authoritative reference for v45 packet ID table (confirmed same 0x8F+ range as v34), 0x8E wrapper byte handling, and the standalone-vs-batch packet sending strategy.
Dragonfly Go-based Bedrock server. Referenced for chunk serialization optimization patterns alongside NukkitX and GeyserMC.
wiki.vg / minecraft.wiki Community-maintained Minecraft protocol documentation. Used for packet formats, field types, and version-specific wire format details across all supported protocol versions.
Minecraft Wiki Official Minecraft server JAR downloads for decompilation and protocol version history.
4J Studios LCE binary (Windows64 TU19) Reverse-engineered for Legacy Console Edition protocol support. Packet framing, login sequence, RLE+zlib chunk compression (compression.cpp), LAN discovery broadcast format (WinsockNetLayer.cpp), entity wire formats (short entity IDs, relative body rotation), and batch packet structure were derived from the compiled client binary.

Tools

Tool Usage
CFR Decompiler Decompiling Minecraft Alpha/Beta client and server JARs to verify exact wire formats, field orders, and client-side behavior.
Vineflower Decompiler used in the BuildTools setup process for RubyDung.
MultiMC Source of historical Minecraft client JARs (from its library cache) used for protocol analysis and decompilation.

Performance Optimization References

Techniques from these open-source Fabric mods and server forks were studied and adapted for RDForward's server:

Project What we learned
Lithium Chunk and broadcast optimizations — bulk long writes, lazy packet creation, ThreadLocal collection reuse, O(1) chunk-needed checks.
Krypton Networking micro-optimizations — batched VarInt writes, branchless frame decoding (from Netty PR #14050), zero-copy frame encoding, reusable cipher buffers, QuietDecoderException with no stack trace. Originally developed for Velocity/Paper.
ModernFix Allocation and encoding optimizations — pre-serialized UpdateTags packets, flat array palette builder eliminating Integer boxing, direct remap table lookups.
C2ME Chunk pipeline architecture — MPSC I/O thread, spiral delivery ordering, async serialization, fine-grained locking, ChunkHolder lifecycle, object pooling.
Starlight Skylight propagation — BFS with level+direction packing for efficient light recalculation.
Paper Server-side optimizations — async chunk generation with worker pool, flush coalescing via FlushConsolidationHandler, crash-safe atomic saves (write to .tmp then rename), nanosecond tick timing, ReadWriteLock for concurrent world reads.
Spigot Performance patterns — incremental dirty chunk saves, snapshot-based lock-free block reads.
Velocity VarInt encoding and frame handling primitives that Krypton's optimizations are derived from.

Inspiration

Project Influence
Spigot BuildTools Inspired the build approach — downloading copyrighted code at build time rather than redistributing it.

AI Assistance

Tool Role
Claude Code (Anthropic) Co-developed major features including protocol version support, Bedrock/MCPE integration, LCE cross-play, grief protection, Alphaver compatibility, E2E test infrastructure, and performance optimizations.

License

MIT License — see LICENSE for details.

Yorumlar (0)

Sonuc bulunamadi