Skip to content

feat(bedrock): add classic Dressing Room - #11

Closed
AlexProgrammerDE wants to merge 4 commits into
ViaVersionAddons:mainfrom
AlexProgrammerDE:codex/bedrock-dressing-room
Closed

AlexProgrammerDE wants to merge 4 commits into
ViaVersionAddons:mainfrom
AlexProgrammerDE:codex/bedrock-dressing-room

Conversation

@AlexProgrammerDE

@AlexProgrammerDE AlexProgrammerDE commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Add a Dressing Room entry to Bedrock settings with Steve, Alex, and one imported custom skin per account.
  • Preview the selected skin with Minecraft's rotatable player widget, preview an imported cape, choose the custom skin's arm size, and import or remove a cape.
  • Keep the controls and preview centered within the available screen height, clear of the title and footer.
  • Use the SDL3 file dialog available in Minecraft 26.3 to import PNGs. Drag and drop remains available and no extra native library is bundled.
  • Save appearances separately by Bedrock XUID and for offline play. Include the selected appearance in Bedrock login data while preserving the friend-world nonce.
  • Document PNG dimensions, next-connection behavior, and the limits of custom cape visibility.

Validation

  • ./gradlew check build passes, including appearance persistence and image validation tests.
  • ./gradlew runClient launches Minecraft 26.3 without a startup or mixin error and is running with the latest changes.
  • The SDL chooser interaction has not yet been exercised manually in the game client.

Review notes

Appearance changes take effect on the next Bedrock connection. This PR covers classic skins and capes; live skin updates and Character Creator assets need separate protocol and rendering work. Imported cape data does not unlock a Minecraft account cape. The login protocol carries cape image data, but visibility may depend on the server and other clients.

Let players select Steve, Alex, or an imported skin and cape for each Bedrock account. Send that appearance in the login client data while preserving the friend-world nonce. Changes apply on the next connection because live skin updates need a separate protocol path.
Use Minecraft’s player skin widget so the selected skin renders at the preview’s actual size and supports rotation. Position the controls, preview, and status relative to the available screen height so the title and footer do not collide with them.
Minecraft runs with AWT headless, so its AWT file dialog fails when importing skins or capes. Use LWJGL Native File Dialog on the UI thread and bundle its desktop native libraries. Clarify that an imported cape does not grant a Minecraft account cape and may not be shown by every server or client.
Minecraft 26.3 already runs its window through SDL3, whose asynchronous file dialog can select PNGs without another native dependency. Keep the callback and filter alive for the dialog lifetime, then hand the selected path back to the game thread.
@AlexProgrammerDE

Copy link
Copy Markdown
Collaborator Author

Research: owned Bedrock capes and persona packs

I traced the Bedrock Dressing Room cape flow with a signed-in account and verified the resulting catalogue entries against the account's Marketplace entitlements. This is a possible path for a later owned-cape picker alongside the custom PNG import in this PR.

  1. GET https://entitlements.mktpl.minecraft-services.net/api/v1.0/player/inventory returns account entitlements. Their offerIds and packId can be used to verify ownership.
  2. POST https://store.mktpl.minecraft-services.net/api/v2.0/layout/pages/DressingRoom_Capes returns cape names, thumbnails, ownership, item IDs, and packIdentity for the signed-in account. The request includes entitlements, inventoryVersion, listVersion, and recentlyViewed. Only entries backed by an entitlement should be offered as owned.
  3. POST https://20CA2.playfabapi.com/Catalog/GetItem resolves an item ID to its personabinary content URL and pieceType (persona_capes). The content URL served the archive when requested with Bedrock's libhttpclient/1.0.0.0 user agent; a browser user agent received 404.
  4. The downloaded archive contains ppack0.zip. Inside it, contents.json and the actual cape PNG are encrypted. I verified that decoding one owned cape's package produces a valid 64×32 PNG. The catalogue thumbnail is a rendered product image, so it cannot replace the cape texture.

The package format and a working decryption approach are shown in MerelyCapes. PlayFab's Get Item documentation describes the catalogue content URL, and the Bedrock pack format notes describe contents.json. These Minecraft-specific endpoints and the package key are undocumented dependencies. I have not added the key or decryption code to this PR.

How this could extend the Dressing Room

An account-scoped catalogue service could list owned capes with their real thumbnails, then download and decode the selected asset on demand. The appearance model would keep the official item, piece, and pack IDs separate from a custom file import. We would also need to verify the Bedrock login claims for official persona capes, handle token refresh, bound downloads and archive extraction, and avoid logging tokens or retaining decrypted assets across accounts.

The same entitlement, catalogue, and package pipeline could later discover owned Character Creator pieces, emotes, and skin-pack content. Those need separate work for geometry, animation, tinting, preview rendering, and the relevant Bedrock protocol fields. This PR remains scoped to classic skins and custom cape import.

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