Skip to content

fix(maps): restore held and framed map rendering - #425

Closed
AlexProgrammerDE wants to merge 8 commits into
mainfrom
codex/fix-bedrock-maps
Closed

AlexProgrammerDE wants to merge 8 commits into
mainfrom
codex/fix-bedrock-maps

Conversation

@AlexProgrammerDE

@AlexProgrammerDE AlexProgrammerDE commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Restore filled maps in the hand and in item frames. Translate current Bedrock map packets in the regular protocol path, keep map IDs stable across item and pixel updates, and send Java frame entities the item and rotation stored in Bedrock block entities. Handle clicks on those synthetic entities without disconnecting.

Why the unusual changes are needed

  • Map ID replacement: Bedrock map UUIDs are 64-bit values, while Java's map component and map update packet use an integer ID. A per-connection table gives the item and its later pixel packets the same Java ID. When a filled map first appears, the proxy sends MAP_INFO_REQUEST with a zero client-pixel count. Zero means it has no map pixels yet, so the server sends the image.
  • Packet field decoding: Bedrock 1.26.51 encodes each optional map field with its own presence byte. Reading the old update mask left tens of thousands of pixel bytes unread, causing blank maps and disconnects. Tracked actors and decorations have separate presence fields. Tracked actor data is consumed, while the separate decoration list becomes Java map markers. Pixel dimensions and offsets are checked against the 128 by 128 map before allocation and forwarding.
  • Colors and transparency: The map pixel integer contains RGBA bytes in little-endian order. Reading it as ARGB swapped red and blue and produced the teal terrain seen during live testing. Fully transparent pixels become Java's empty map color. Opaque colors are matched to the nearest available Java map palette color in Lab space because Java cannot display arbitrary Bedrock RGB values. The match cache now uses the full RGB value: two nearby colors can require different Java palette entries even when they share a coarse color bucket. This removes an avoidable color error, but the fixed Java palette still means a perfect Bedrock pixel match is impossible.
  • Frame spawn position and facing: A Bedrock frame is a block; Java renders it as an entity. The Java entity is spawned at the center of the Bedrock block (+0.5 on each coordinate), with Bedrock's facing value in the entity data. The prior corner position misaligned the visible frame. The frame item and rotation come from the Bedrock block entity and are updated when that block entity changes, so an already filled frame and a newly filled frame both render.
  • Chunk palette lookup: Frame detection must use the original Bedrock palette indices. Java block-state remapping can reorder or coalesce the copied palette. Reading Bedrock tags through those remapped indices selected the wrong block state and caused the observed frame disconnect.
  • Click handling: The Java frame entity is synthetic and has no Bedrock actor ID. Its Java entity ID now maps back to the Bedrock frame block. Clicking it sends the existing Bedrock block-use transaction, including the selected item and face, instead of trying to look up a nonexistent Bedrock actor. The shared transaction helper keeps ordinary block use and frame use on the same path. Removing a frame clears both lookup directions.
  • Code placement and tests: The old experimental map translator and its storage were removed because map updates must work in the normal protocol path. JUnit dependencies support focused color conversion tests, including two nearby palette colors that collided in the old cache.

Verification

  • ./gradlew build --offline --no-daemon passes, including the color conversion tests.
  • On an isolated Bedrock 1.26.51 test server through ViaProxy, the Java client displayed a filled map in hand and in a newly placed frame. The user confirmed the frame worked without disconnecting and supplied a screenshot showing both maps.
  • A native Bedrock client joined the separate NetherNet test server and placed a filled map in a frame. Java and native Bedrock were tested on separate local server instances because the current unauthenticated ViaProxy NetherNet offer is rejected at signaling, before ViaBedrock receives gameplay packets. Cross-client viewing of the same NetherNet world remains unverified.

Translate Bedrock map updates in the regular protocol path and request map data when a filled map first appears. Populate item frame entities from block entity items and correct palette color conversion so held and framed maps render consistently.
Bedrock 1.26.51 sends an independent presence byte for each optional map field. Reading a legacy update mask left pixel data in the packet and produced blank maps or client disconnects. Decode the separate tracked actor and decoration lists and consume all pixel fields.

Live map pixels arrive as RGBA bytes in a little-endian integer. Use that channel order when selecting Java map palette colors so foliage does not appear teal.
Route Java clicks on synthetic item frames to Bedrock block use transactions, and keep the reverse frame entity lookup in sync with removal. Look up frame tags from the original Bedrock chunk palette because Java palette remapping can change its indices and previously caused a disconnect.

Cache map color matches by full RGB value within each conversion. Nearby colors can share a quantized key yet require different Java palette entries.
Merge the promoted protocol implementation into the map rendering PR. Reuse the core item interaction flow for framed maps, retain map requests for held items, and keep map packet handling registered once.
@AlexProgrammerDE

AlexProgrammerDE commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator Author

Only blocker on this right now is I gotta figure out if maps actually have the right colors for some blocks.
Mossy cobblestone looked kinda teal

Merge the current main branch and reconcile the map handlers with renamed core APIs. Apply the new Checkstyle rules to map translation and palette code while preserving held and framed map behavior.
Bring in the latest chunk completion and request scheduling changes while preserving held and framed map handling. The merged code passes the full Gradle build.
@AlexProgrammerDE
AlexProgrammerDE marked this pull request as ready for review September 25, 2026 10:12
@AlexProgrammerDE

Copy link
Copy Markdown
Collaborator Author

Bedrock:
image
Java:
image

@AlexProgrammerDE
AlexProgrammerDE requested review from Exterminate5573 and RaphiMC and removed request for RaphiMC September 25, 2026 10:13
Java exposes Bedrock frame blocks as synthetic entities, so its attack packet was discarded by the normal entity lookup. Route frame attacks to the block action path at the frame position and face.

Regenerate the player action and auth input IDs from the 1.26.51 metadata used by this bridge. The checked-in preview IDs prevented the server from interpreting block actions. Teach the enum generator to use ordinal IDs when the release metadata omits explicit binary values.
Restore the PR to its previous map scope while the frame attack behavior remains unverified.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant