- Go 99.9%
- Dockerfile 0.1%
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JhRruHDTswJ2XVRSq6f3RE |
||
|---|---|---|
| .github/workflows | ||
| cmd | ||
| deploy | ||
| internal/gw | ||
| .gitignore | ||
| CONTRIBUTING.md | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| NOTICE | ||
| README.md | ||
tachyne-gw-bedrock
tachyne is an unofficial fan project, not affiliated with Mojang, Microsoft, or Minecraft's developer/publisher in any way. See the Disclaimer at the bottom.
Project status
Work in progress. tachyne is young and moving fast: a full survival game runs today, but expect rough edges, missing vanilla features, and breaking changes between updates. Bug reports are genuinely useful — please open a GitHub Issue with your client version/edition and what you saw. Contributions are welcome too: see CONTRIBUTING.md.
Just want to run a server? The quickstart repo brings up the whole stack in one command — Docker Compose or Kubernetes, classic infinite survival by default, real-Cape-Town earth mode as a variant.
What's implemented? Gameplay features live in the world engine, not the gateways — see tachyne-world's feature matrix for what to expect (implemented / partial / missing) as a player.
The tachyne gateway for Minecraft Bedrock edition (latest — currently 1.26.50 / protocol 2193 via gophertunnel): terminates Bedrock clients (RakNet + encryption + XBL login handled by gophertunnel), authorizes them via tachyne-access, and renders a tachyne-world — consumed over the domain attach protocol — into Bedrock wire format.
Unlike the Java fleet (per-protocol pods gw-java-770/gw-java-776), Bedrock runs ONE versionless gateway tracking the latest release: Bedrock clients auto-update, so the fleet doesn't fragment. Keeping current = bump the gophertunnel dep and rebuild; the engine never changes.
This gateway is internal-only — clients reach it through tachyne-ingress,
which owns the public <server-ip>:19132/udp and forwards RakNet datagrams to
this ClusterIP service (per-client UDP session). One hardened entrypoint; the
gateway pods aren't publicly exposed.
How it renders
- Blocks: canonical Java 1.21.11 state IDs → hashed Bedrock network
IDs (StartGame
UseBlockNetworkIDHashes=true; fnv1a-32 of the{name,states}LE NBT, dragonfly'snetwork_block_hash.goalgorithm) via the generatedbedrockBlockRIDstable — no dependency on Bedrock palette order across versions. Chunks re-encode through dragonfly'sworld/chunkpackage (sub-chunk v9, classic full-payload LevelChunk, cache off). - Items: full Bedrock item registry (
runtime_item_states) in StartGame; Java item ID → Bedrock identifier+aux viajavaItemBedrock. - Entities: canonical entity type → Bedrock actor identifier
(
bedrockEntityIDs, Geyser's mapping incl. the boat/villager_v2/etc exceptions);entity_identifiers.datsent verbatim as AvailableActorIdentifiers. Types with no Bedrock form (item frames, displays, mannequin) are skipped. - Biomes: Java biome name → Bedrock numeric ID (
bedrockBiomeIDs).
All tables are generated by scripts/gen_bedrock.py in tachyne-world from
GeyserMC/mappings (pinned at Geyser's Bedrock 1.26.50 update; its Java side is
matched onto ours by block name and properties), Geyser core's bedrock/
resources (1.26.50) and vanilla's own reports for the Java side — MIT-licensed
data consumed as facts, algorithms reimplemented. The generator refuses to
write a block state or item the target Bedrock version's palette and item
registry do not contain.
Run
TACHYNE_XBL_AUTH=off TACHYNE_ATTACH_TOKEN=dev \
TACHYNE_BACKEND=127.0.0.1:25500 TACHYNE_LISTEN=:19132 go run ./cmd/gw
Env: TACHYNE_LISTEN (udp :19132), TACHYNE_BACKEND (world attach addr),
TACHYNE_ATTACH_TOKEN, TACHYNE_ACCESS_URL/TACHYNE_ACCESS_TOKEN (door
policy; unset = OPEN, dev only), TACHYNE_XBL_AUTH=off (disable XBL
authentication — offline probes; NEVER in production), TACHYNE_MOTD.
Identity: an Xbox-authenticated player joins the world in Floodgate's
scheme. Their UUID is UUID(0, xuid), so it stays the same for the
account and never collides with a Java account. Their name is the
gamertag behind a ., with spaces as _ and at most 16 characters, so a
Bedrock name cannot clash with a Java player's.
Headless smoke
cmd/bedrockprobe is an offline Bedrock client: joins, spawns, decodes every
LevelChunk with dragonfly's NetworkDecode (what a real client does), asserts
terrain is present, prints a packet histogram.
go run ./cmd/bedrockprobe -addr 127.0.0.1:19132 -name probe1 -t 10s
Status / debt
- WORKING: login (XBL or off), StartGame, chunk streaming (terrain verified by probe), block updates, entity add/move/remove incl. other players (placeholder skin), player list, chat + commands + HUD text, movement (PlayerAuthInput → engine, absolute renders back), time, teleport, and the interaction bridge (melee/dig/place/use-item/hotbar/sneak via InventoryTransaction + PlayerAuthInput BlockActions); health, hunger, saturation and XP relayed as attribute updates; the death screen and the respawn button (Respawn packets both ways); hurt flashes and death animations as actor events; another breaker's crack overlay (a zombie on a door) as block-cracking level events, re-timed per stage as Geyser does; dropped items as item actors carrying their stack; the common sounds (mob voices, hits, chests, doors, explosions…) as level sound events; what entities hold and wear (mob equipment and armour packets); mob looks from metadata (burning, sneaking, sprinting, invisible, gliding, swimming and sleeping; babies; sheep colour and shearing; pets sitting, tamed and angry; bee stings and anger; creeper charge and fuse; slime and magma cube size; spiders climbing; zombies converting; villager and zombie villager profession, biome and tier; frog and axolotl variants; the enderman's carried block; the guardian beam target; name tags; primed TNT fuse); the Nether and the End (portal travel goes through Bedrock's dimension-change screen; their chunks render at the same absolute y inside Bedrock's shorter 0..127 and 0..255 ranges); advancement toasts ("Advancement Made!" over the English title when the player's progress completes one); boats and chest boats in their wood; crafting (the world's recipe book becomes CraftingData, the 2x2 grid and the crafting table's 3x3 live in Bedrock's UI window, and a craft request — recipe-book auto-craft included — becomes the world's own result-slot clicks); the anvil (renames ride ahead of the take) and the grindstone, whose results are whatever the world previewed; villager trading (the world's offers become Bedrock's trade screen addressed to the villager just used, and choosing an offer selects it in the world before the result is taken); the enchanting table (the world's three rows become Bedrock's enchant options, and picking one presses the world's button); the stonecutter (its recipes ride in the crafting data, and a cut picks the world's row before the take); the smithing table (netherite upgrades as transform recipes, armor trims through Bedrock's trim data and the tag-written trim recipe), the loom (Bedrock's pattern pick becomes the world's row), the beacon (the chosen effects live on its block entity, and the payment becomes the world's SetBeacon) and the cartography table (the world's preview, taken like the anvil's); books (a written book's pages, title and author ride on the stack as Bedrock book NBT, a book and quill's page edits and signing reach the world as the whole book, and a lectern shows its book off the block entity with page turns as the world's jump-to-page button); signs (standing signs come out of the chunk's block-entity section, edits and the world's sign frames become Bedrock sign block entities, the world's editor opens Bedrock's, and the edited side goes back as four lines); banners (layers in Bedrock's pattern codes on the base colour read off the block state), campfires (their four cooking items) and ringing bells, all as block entities from the chunk section or the world's frames; status effects (Bedrock's effect numbering; glowing, luck and dolphin's grace have no twin), abilities and game-mode changes (flight in creative), rain and thunder, other players' arm swings, the item-pickup animation, a server-set hotbar slot, difficulty, boss bars (an invisible stand-in carries the bar) and a ridden vehicle's snap-back; filled maps (the world's colour patches accumulate into a per-map texture in vanilla's palette, markers become Bedrock icons, the map id rides on the item, and the client's map requests are answered); scoreboards (objectives in the list, sidebar and below-name slots, per-owner lines as fake players, team prefix/suffix/colour on the names); the mount screen (a horse's saddle and armour, a donkey's or llama's saddle or carpet plus its chest, laid out as Bedrock's horse container on the animal, with the client told what each equipment slot takes); command autocomplete (the world's command names, each taking the rest of the line); the creative inventory (every mapped item listed, blocks under construction; taking, dropping and destroying become the world's creative slot sets, or declared clicks inside a container); dropping items (from a window, or the held stack in the world — the declared slot holds less and the world drops the difference); on-ground from the client's own vertical-collision input flag (so fall damage lands right); block-break, bone-meal, crit, explosion, poof and bubble particles as level events and sixty-odd more (flames, smoke, splashes, hearts, notes, portal, enchant glyphs…) as the named Bedrock particles Geyser's table maps them to; Bedrock players' own skins in each other's player lists; riding (the world's passenger lists become actor links so the client sits the player on the boat or cart, the ride carries the chunk window, and the full key state — forward/back/left/right, jump, sneak, sprint — steers server-driven vehicles); container windows (chests, barrels, shulker boxes, hoppers, dispensers, droppers, furnaces, blast furnaces, smokers and brewing stands open at the used block with their slots where Bedrock keeps them and the burn/cook/brew bars as container data; clicks reach the world through the per-window slot map).
- NOT YET: the Java advancements screen (Bedrock has no tree to show; completions toast and are announced in chat), taking a book off a lectern from its screen (walk up and break it, or use Java), the particles Geyser's table has no Bedrock name for, Java players' skins (the world runs without Mojang profiles, so Java players stay grey on Bedrock).
Deployment
Dockerfile builds a static Go binary into a minimal image. deploy/ holds
working Kubernetes manifests (the ones this project actually runs) — treat
them as examples: substitute your own image registry, hostnames, namespaces
and secrets before applying them to your cluster.
Credits
- gophertunnel (© Sandertv) — RakNet transport, encryption, and Bedrock login/packet handling (MIT).
- dragonfly — Bedrock chunk encoding and biome definitions (MIT).
- GeyserMC — Java↔Bedrock block/item/ entity/biome mapping data and protocol resources (MIT); the generated tables in this repo are built from their published mappings.
- go-gl/mathgl (BSD-3) and google/uuid (BSD-3).
- Protocol rendering facts come via the shared
tachyne-commonlibrary — see its credits.
Development transparency
tachyne is built by its maintainer working with an AI coding agent (Anthropic's Claude): substantial portions of the implementation were written by the model under human direction, and every change is reviewed, tested and deployed by the maintainer. The project's engineering discipline is designed for exactly this workflow — byte-oracle tests pin the wire format, full test suites gate every image build, and real-client verification signs off gameplay. Disclosed here for transparency; judge the code on its behavior.
License
Licensed under the Apache License, Version 2.0 — see LICENSE and NOTICE. Note §6: the license grants no rights to the tachyne name or any trademarks.
Disclaimer
tachyne is an unofficial, independent project. It is not affiliated with, endorsed, sponsored, or approved by Mojang Studios, Mojang Synergies AB, Microsoft Corporation, or any of their subsidiaries — the developer and publisher of Minecraft have no involvement with this project. "Minecraft" is a trademark of Mojang Synergies AB. This project contains no Minecraft game code; all game behavior is independently reimplemented, and data tables are built from openly licensed community datasets (see Credits).