Java Edition and Bedrock Edition are two different games that happen to share a name. They speak
different network protocols, use different authentication systems, and ship on different release cadences.
Yet on play.aowmc.com, a player on a Windows PC running Java and a player on a Nintendo Switch
running Bedrock can stand in the same chunk, trade items, and chat in the same channel.
This page explains exactly how that works — and where the seams still show.
1 The fundamental problem
Before we talk about bridges, it's worth being honest about what we're bridging. Java and Bedrock are not just "the same game with different launchers." They differ at every layer of the stack.
| Layer | Java Edition | Bedrock Edition |
|---|---|---|
| Transport | TCP on port 25565 |
UDP (RakNet) on port 19132 |
| Protocol | Mojang Java protocol, version-locked to the server jar | Bedrock protocol, version-locked to the client |
| Auth | Mojang / Microsoft account (Java entitlement) | Xbox Live account (Bedrock entitlement) |
| Encryption | Per-session AES, optional secure profile signatures | Per-session, baked into RakNet handshake |
| UI primitives | Chest GUIs, anvil text input, written books | Forms (modal / simple / custom), system chat input |
| Engine | Java VM, OpenGL renderer | C++ engine, native renderer per platform |
So our job is to put something in front of Paper that speaks Bedrock to the player and Java to the server. That "something" is actually three plugins working together: Geyser, Floodgate, and ViaVersion.
2 The three bridges
Here's the actual packet path on AoW SMP. Java players take the direct route on the left. Bedrock players take the translated route on the right.
The key trick: Paper itself does not know or care that Bedrock players exist. By the time a packet from a
Switch reaches Paper, it has been re-written into a perfectly valid Java protocol packet at version
1.21.8. Every plugin we run — including all 75 of our custom ones — treats every player as
a normal Java player. That is what makes cross-play actually scale.
3 Geyser, in depth
Geyser is the heart of the operation. It runs inside Paper as a Spigot plugin (so it shares the JVM and
can talk to other plugins), opens its own UDP listener on port 19132, and pretends to be a
Java server to the inside while pretending to be a Bedrock server to the outside.
What Geyser does on every Bedrock connection
- Accepts the incoming RakNet handshake on
UDP/19132. - Spins up a virtual emulated Java client session inside the same JVM.
- Translates each Bedrock packet (movement, block break, inventory click, form response) into the equivalent Java packet.
- Translates each Java packet coming back (chunk data, entity spawn, chat, GUI) into the equivalent Bedrock packet, including swapping chest GUIs for Bedrock Forms where appropriate.
Our Geyser config
| Key | Value | Why |
|---|---|---|
bedrock.port | 19132 | Standard Bedrock port so clients find us via "Add Server" with no custom port. |
remote.auth-type | floodgate | Bedrock players use Xbox auth via Floodgate. No Java account required. |
remote.use-direct-connection | false | Forces Geyser to connect to Paper through the normal network stack, so ViaVersion can sit in the middle and translate. |
passthrough-motd | true | Bedrock server list shows our real MOTD: AoW SMP - Java + Bedrock crossplay. |
use-direct-connection: false gotcha. The default in Geyser is
true — it shortcut-pipes packets straight into the server, skipping the network layer for
speed. That is great if your server is exactly the version Geyser emulates. It is broken for us,
because we need ViaVersion in the pipeline to translate Geyser's emulated client version into Paper
1.21.8. We pay a small CPU tax for going through the loopback; we get a working bridge in exchange.
4 Floodgate, in depth
Floodgate is what lets us keep online-mode=true while still admitting Bedrock players who
do not own a Java account. Without it, the only way to let Bedrock players in would be to disable Java
authentication entirely — which means anyone could log in as anyone. Hard no.
What Floodgate does
- Generates a shared secret at install time:
plugins/Geyser-Spigot/key.pem, which Geyser reads and Floodgate verifies. This is how Paper trusts that a "Bedrock" login is genuinely an Xbox- authenticated player and not someone spoofing it. - Issues each Bedrock player a deterministic offline UUID derived from their Xbox account, so permissions, balances, homes, and claims persist correctly across sessions.
- Prefixes Bedrock usernames with a
.so they never collide with a real Java name. If a Bedrock player's gamertag isSteve, in-game they appear as.Steve.
The dot prefix in practice
/msg .Steve hey, want to trade?
/pay .Steve 250
/tpa .Steve
/trust .Steve
Java player names do not have the prefix — type them as normal.
Paper settings that make this safe
| Setting | Where | Value | Why |
|---|---|---|---|
online-mode | server.properties | true | Real Mojang auth for Java clients. Floodgate handles Bedrock separately. |
enforce-secure-profile | paper-global.yml | false | Bedrock players don't have Mojang-signed chat keys, so we must not enforce them. |
perform-username-validation | paper-global.yml | false | The .Steve name contains a character Paper would otherwise reject. |
5 ViaVersion + ViaBackwards
Here is the subtle bit. Paper runs 1.21.8. Geyser, at any given moment, internally emulates the Java protocol version it was last built against — which may or may not be exactly 1.21.8. If those don't line up, the connection fails with a vague "Outdated server" message.
ViaVersion sits between Geyser's emulated client and Paper, and rewrites packets so they look like whatever protocol Paper is happy with. ViaBackwards handles the opposite direction — Paper sends packets at 1.21.8, ViaBackwards re-encodes them at the older version Geyser expects.
6 What works flawlessly
Once the three bridges are wired up correctly, a startling amount of the game just works for Bedrock players. The translation layer is mature enough that most of our 6 consolidated in-house packs were written without anyone touching Bedrock-specific code.
/guide tappable links work
Item dropsIdentical drop tables; same pickup rules
Mob behaviorMythic Champions, gear, loot all apply
Chat & commandsFull Adventure formatting
Particles & soundsTranslated to Bedrock equivalents
ClaimsGolden-shovel works; /trust .Name
Skills XPAuraSkills tracks Bedrock players normally
Economy/pay, /balance, /ah, /daily
Homes & warpsEssentials data is shared
The auction house is a particularly nice case. GlobalMarketplace is Bedrock-Forms-aware: when a
Java player opens /ah, they see a chest GUI; when a Bedrock player opens the same command,
they see a native Bedrock Form. Same data, two presentations. The plugin handles the fork; the player
never notices.
7 What feels different on Bedrock
Cross-play is excellent, but it is not invisible. Bedrock players should know the small papercuts going in — almost all of them are downstream of how Bedrock the game works on consoles, not of anything we can fix server-side.
| Friction | Why it happens | Workaround |
|---|---|---|
| Typing chat commands is awkward on a controller | Bedrock chat input is a system text box, not a free overlay | We expose tappable links in the welcome book (/guide) and in /help |
No F3 debug screen / no live coords |
F3 is a Java-client-only feature | Turn on coordinates in Bedrock world settings; use /spawn + /backtrack |
| No client-side mods (OptiFine / Sodium / minimap) | Bedrock has no mod loader — only Marketplace add-ons | Use the squaremap web map at map.aowmc.com and pin shared landmarks before long trips. |
| Anvil renaming feels different | Bedrock anvil UI is a native form, not a free text field | Just works; the field is at the top of the form |
| Some signs / written books look slightly off | Font metrics differ between editions | We keep server signs short and avoid hex colors on critical UI |
| Custom textures from Java resource packs don't apply | The two editions use entirely different texture formats | We use vanilla items/blocks only — by design — so the two editions render identically |
/msg requires the dot prefix for Bedrock recipients |
Floodgate prefixes Bedrock names to prevent collisions | Tab-complete works; or just remember: dot for Bedrock |
8 Why plugins and not mods
A reasonable question: if we wanted custom mobs, custom loot, custom worldgen, why not just write a Forge or Fabric mod? The short answer is that mods would break Bedrock cross-play, which is the whole point of this server.
This is the single most important rule in our custom-plugin charter: paper-api dependency only,
Adventure API for text, vanilla items and blocks only, server-side ADD-only logic. Every plugin
we ship — the guidebook/onboarding module in AoWInfra, the Champions module in AoWMythic, AoWChestLoot, all of them — was
written against that rule. The reward is that cross-play keeps working as we add features.
9 Quick reference
online-modeConnect strings
# Java client
Multiplayer → Add Server → play.aowmc.com
# Bedrock client (any platform)
Servers → Add Server
Name: AoW SMP
Address: play.aowmc.com
Port: 19132