feat(bedrock): render confirm and text input as native forms - #28
Open
hbrombeer wants to merge 1 commit into
Open
feat(bedrock): render confirm and text input as native forms#28hbrombeer wants to merge 1 commit into
hbrombeer wants to merge 1 commit into
Conversation
A themed GUI cannot be translated to Bedrock. The theme draws its panels with
private-use glyphs positioned by negative advance and composited by a Java
core shader; Geyser translates containers, not rendering, and the Bedrock
client has neither. What arrives is a bare container with missing-glyph text
where the interface should be — broken rather than plainer.
Bedrock's native answer is a form, and the two constructs with exact form
equivalents are also the two worst on Bedrock today:
confirmGui -> modal form. Its contract already matches: onCancel runs on
dismissal too, which is the form's own close semantics.
anvilInput -> custom form with one input. The only place Bedrock ends up
better served than Java, whose path needs the client to send
its rename field on roughly every keystroke and only once
slot 0 holds an item.
Both keep their signatures. The branch lives in an overridden open(), so every
existing call site is untouched and the choice of surface is made where it
belongs rather than by the caller.
Floodgate is NOT a dependency, and does not need to be. Its own
backend-to-client path is the floodgate:form plugin-message channel: the proxy
forwards a message from a server straight to the client, and routes the
response back whenever the form id has the 0x8000 bit clear — that bit means
"sent by a proxy", so a backend keeps it clear and owns its own id space. Read
out of FormChannel.createFormData rather than assumed.
The wire format is pinned by tests against Cumulus's own codecs, including the
escaping: a player who types a quote would otherwise truncate the JSON and the
form would be dropped by the client with nothing in any log.
Not covered here, deliberately: menus in general still need ordering and
labels the slot-based DSL does not carry, and genuinely spatial GUIs have no
form equivalent at all. Both stay translated containers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements variant A from library-gui — Bedrock GUI Concept.
Why translation is not an option
A themed GUI draws its panels with private-use glyphs positioned by negative advance, composited by a Java core shader pinned to
PackFormat(88). Geyser translates containers, not rendering — it can show a Bedrock player 54 slots and the items in them, but it runs no Java core shader and carries neither the font nor the advance model. What arrives is a bare container with missing-glyph text where the interface should be. Broken, not plainer.What this changes
confirmGuionCancelruns on dismissal too, which is exactly the form's close semanticsanvilInputBoth keep their signatures. The branch lives in an overridden
open(), so every existing call site is untouched and the choice of surface is made where it belongs rather than by the caller.Floodgate is not a dependency
That looked like the blocker — Floodgate ships no Minestom implementation. It turns out not to matter: Floodgate's own backend-to-client path is the
floodgate:formplugin-message channel, and its proxy handler forwards a message from a server straight to the client, then routes the response back whenever the form id has the0x8000bit clear. That bit means "sent by a proxy", so a backend keeps it clear and owns its own id space.Read out of
FormChannel.createFormDatain GeyserMC/Floodgate, not assumed:Verification
typevalue read out ofModalFormCodec,CustomFormCodec,FormTypeandComponentType. A rename upstream is a form that silently never appears, which is a test's job to catch rather than a player's.spotlessCheckclean.Still to verify against a live client
Reading a protocol is not running it. Two things this PR cannot prove on its own: that Velocity forwards the channel from a Minestom backend without dropping it, and that Geyser accepts a form whose id was minted by something other than Floodgate. Bedrock is live in stage, so both are one join away from an answer.
BedrockForms.install()must be called once at startup, or forms are sent and no response ever arrives.Deliberately not covered
Menus in general still need ordering and labels the slot-based DSL does not carry, and genuinely spatial GUIs have no form equivalent at all. Both keep rendering as translated containers — see the concept page's option B for when that changes.