Repository navigation
Game: Rework keypads and route ShowImage through the Dialog API - #3337
Merged
Merged
Conversation
Image dialogs are shown through DialogFactory.show only. ShowImageUI reads its image and transition speed from the DialogContext, so the ShowImageComponent/ShowImageSystem path that managed its own overlay entity is removed, together with ShowImageText, which only that path used. DialogUtils.showImagePopUp and ShowImageFactory use DialogFactory.show. KeypadComponent and TextKeyPadComponent no longer hold overlay or UI-open state; their dialogs are already owned by the Dialog API. Refs #2734
KeypadUI renders from the client-side KeypadComponent, which no generic sync created, so opening a numeric keypad without a room-specific sync (e.g. the Keypad prefab) crashed the multiplayer client. KeypadSync encodes the entered digits, code length, digit-count flag and unlocked state in snapshot metadata, like TextKeypadSync does for text keypads. The code itself stays on the server; the client component uses placeholder digits of the synced length.
Spawn events carry the KeypadSync metadata and the room clients apply it, like TextKeypadSync, so a keypad has its client component even when its first snapshot state arrived before the spawn.
LastHour already sends keypad.* metadata with a different encoding, so the generic numeric keypad keys use numericKeypad.*, matching textKeypad.*.
Numeric and text keypads use the same KeypadComponent for their input and display state and check answers through their TaskComponent: NumericCodeTask for numeric keypads, FreeTextTask for text keypads. NumericCodeTask resolves its code on every check, so the Keypad prefab can still take its code from another prefab. * KeypadFactory.submit unlocks the keypad on a correct answer and clears the input after a wrong one unless clearOnWrong is off. The Keypad and Text Keypad prefabs expose this as a property, defaulting to clearing. * The keypad dialogs accept only their own buttons from clients and render an empty keypad until the first synchronized state arrives. * KeypadSync replaces TextKeypadSync and covers both keypad kinds, including the default spawn handler in GameLoop. * The Last Hour and System Recovery use the generic keypad sync instead of their own, so clients no longer receive the door codes. Their door actions and tracking run in the task callbacks; The Last Hour counts complete wrong codes for its achievement and save itself. * Foundation keeps its own keypad dialog, evaluation and sync on top of the shared component.
The server now caps text keypad input like numeric input, so a client cannot grow the synchronized text without bound. Keypad dialogs read the optional component directly, and both System Recovery keypads share one door helper.
Numeric and text keypads render through one KeypadUI with a layout per kind, and KeypadFactory applies their buttons on the server, accepting only the buttons of the layout. * Text keypad answers must fit the 32-character input limit; the factory throws IllegalArgumentException and the prefab rejects longer answers. * KeypadComponent uses unlocked() / unlocked(boolean). * Foundation keypads use the default keypad dialog type and the generic KeypadSync, so FoundationSnapshotTranslator is gone and the Wizard runner uses the default snapshot translator. Foundation keeps its own keypad evaluation. * The System Recovery keypad callbacks read their components directly.
Images are shown through the Show Image prefab or DialogUtils.showImagePopUp.
Foundation keypads apply their buttons through KeypadFactory.press, so both kinds of keypads accept and sound the same buttons. Numeric codes are limited to 8 digits like the hidden input limit, and the Keypad prefab validates its code with KeypadFactory.isNumericCode.
Flamtky
marked this pull request as ready for review
October 30, 2026 04:28
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.
Closes #2734
Keypad, Text Keypad und ShowImage laufen vollständig über die Dialog API (
DialogFactory.show,DialogContext). Kein System und keine Komponente verwaltet mehr eigene Dialog- oder Overlay-Entities. Beide Keypads funktionieren gleich und prüfen über Tasks.ShowImage
ShowImageUIist der Renderer fürDialogType.DefaultTypes.IMAGEund liest Bildpfad undIMAGE_TRANSITION_SPEEDaus demDialogContext.ShowImageComponent,ShowImageSystemundShowImageTextentfallen.DialogUtils.showImagePopUpzeigt das Bild überDialogFactory.show. Die unbenutzteShowImageFactoryentfällt; Bilder an Objekten entstehen über das Prefab „Show Image“.Keypads
KeypadComponent. Sie hält nur Eingabe und Anzeige: eingegebener Text, entsperrt, maximale Länge, ob die Länge mit*angezeigt wird, und ob eine falsche Antwort die Eingabe leert.TaskComponentdes Keypads:NumericCodeTaskbeim Keypad,FreeTextTaskbeim Text Keypad.NumericCodeTasklöst den Code bei jeder Prüfung auf, sodass das Keypad-Prefab seinen Code weiter von einem anderen Prefab bekommen kann. Reaktionen auf Antworten hängen anTaskComponent.onCorrect/onWrong.KeypadFactory.submitist der eine Absende-Pfad: Erst laufen die Task-Callbacks, dann wird das Keypad bei richtiger Antwort entsperrt oder bei falscher Antwort geleert. Das Leeren lässt sich abschalten; die Prefabs Keypad und Text Keypad haben dafür die Property „Clear On Wrong“ (Standard: an).KeypadUImit je einem Tastenlayout.KeypadFactorywendet die Tasten auf dem Server an und nimmt nur die Tasten des jeweiligen Layouts an. Codes haben höchstens 8 Ziffern, Text-Keypad-Antworten höchstens 32 Zeichen; Factory und Prefabs lehnen längere ab. Bis der erste Zustand ankommt, zeigt der Client ein leeres Keypad.KeypadSyncüberträgt den Anzeigezustand beider Keypad-Arten in Spawn- und Snapshot-Metadaten. Codes und Antworten bleiben auf dem Server; vom Zahlencode kennt der Client nur die Länge.KeypadSync;FoundationSnapshotTranslatorentfällt, der Wizard-Runner nutzt den Standard-Snapshot-Translator. Foundation wendet die Tasten überKeypadFactory.pressan; die Auswertung bleibt bei Foundation.PROTOCOL_VERSIONist 18, weil sich die Keypad-Metadaten geändert haben.Bilder
Bild-Dialog, Keypad nach richtigem Code, Text Keypad nach richtiger Antwort (GameOfGames, gehostet mit zweitem Client)