|
RapidGameFramework
Reusable Godot managers for data-driven small games
|
s
These standards exist to prevent repeated browser/mobile layout regressions in menus, popups, lists, achievement pages, shops, inventories, and future game UI.
layoutManager.apply_responsive_shell(...), layoutManager.apply_vertical_budget(...), inventoryList, achievementScreen, statsPanel, resultsScreenController, and standard_settings_popup.Use layoutManager.apply_vertical_budget(...) for pages with mixed fixed and flexible controls.
The budget is authoritative. A page must be calculated from the viewport minus reserved header/footer/nav space, then every visible child region must be assigned a height inside that remaining budget. If fixed regions and flexible minimums cannot all fit, the framework scales them down and pushes excess content into the intended inner scroll regions. The page itself must not grow under the nav bar, even after selection changes, opening packs, changing result text, increasing text size, or switching tabs.
Recommended structure:
Do not size primary lists from item count, selected item, status message line count, or current content text. For example, a shop list should stay the same height when a booster pack is opened, a single is selected, or a result message changes.
Every dynamic page should have a smoke test that simulates its largest common content state, then calls layoutManager.vertical_budget_fits(...) against the reserved page height. This is the framework-level pass/fail check; screenshots are useful for review, but they are not the guardrail.
Composite widgets such as inventory tables, card grids, editors, and battle panels must be budgeted by the outer reusable widget, not only by an internal scroll body. The framework must be able to measure the widget's nested visible footprint and prove that it fits the reserved page height. Use layoutManager.measure_vertical_footprint(...) or layoutManager.vertical_budget_fits(...) in smoke tests for any page with nested reusable widgets. A test that only checks the parent panel height is insufficient.
Variable-length messages must use the framework scroll-frame pattern:
layoutManager.wrap_label_in_scroll_frame(...) to wrap existing status, battle log, purchase result, run result, or helper text labels.layoutManager.resize_text_scroll_frame(...) with content-derived visible line intent and min/max bounds. The frame may grow within its assigned fixed budget, but it must not push the main list/grid/nav off screen.resultsScreenController for match/run/battle-complete modals so action buttons stay in a fixed footer and result text scrolls in the middle.layoutManager or the relevant shared controller and add a headless smoke assertion there.Use the right primitive for the interaction:
PopupPanel through shared controllers for true modal panels such as settings, stats, achievements, result screens, confirmations, and menu subpages.PanelContainer for local popovers attached to a specific card, tile, artifact, inventory row, or HUD icon.PopupPanel for small local detail popovers. Godot popup window sizing can interact with theme minimums and viewport clamping, causing the popover to stretch like a full-height panel.size, custom_minimum_size, top-left anchors, z_index, opaque background style, and viewport-clamped position.data/games/<game_id>/achievements.json.statsManager global achievement state before rendering rows so a new save cannot make previously unlocked achievements appear locked.data/build_profiles, because individual exports may exclude build profile catalogs.achievementScreen.render_page(...) with a visible scrollable collection area.achievementScreen.show_popup(...) or update_popup(...) with the shared viewport clamp.audioManager immediately, and refresh only the visible speaker icon.Recurring UI bugs should map to these shared owners:
statsManager owns global unlock state, and achievementScreen owns row rendering, filtering, popup/page sizing, and global-state refresh before render.layoutManager owns page region allocation, popup viewport clamps, framed status/result text, bottom navs, and density/theme application.settingsManager owns stored audio flags, audioManager owns bus synchronization, and start/menu screens only own the icon control.inventoryList and adapters own reusable list sizing, tooltip metadata, sorting, and selection behavior.resultsScreenController, statsPanel, and achievementScreen own modal shells with scrollable content and fixed actions.When a scene has custom behavior in any of these areas, it must either call the shared owner or document why the shared owner is insufficient and extend the shared owner first.
Whenever a shared UI helper, menu page, popup, list, or achievement screen is changed, add or update headless smoke coverage for the rendered behavior:
PopupPanel.The test should fail when the player-visible contract fails. Avoid checking only internal state or one guessed node path when the problem is a rendered page.
Before calling a UI issue complete: