Skip to content

ConsoleUI: Replace svc_layout HUD with FDF-driven screen controllers #114

Description

@corepunch

Context

The in-game HUD (ConsoleUI) is currently server-authored in g_ui_stubs.c — 1405 lines of hardcoded pixel coordinates generating UIFRAME structs sent via svc_layout. This duplicates layout data that Blizzard already ships in FDF files inside the MPQ archives.

Meanwhile, every menu screen in ui/screens/ follows a clean pattern: FDF for layout + generated binding header + screen controller for dynamic data.

Goal

Replace the server-authored svc_layout HUD with client-side FDF-driven screen controllers, matching the established ui/ pattern. Delete g_ui_stubs.c and the UIFRAME render path.

Blizzard's FDF files

All of these already exist in War3.mpq at UI/FrameDef/UI/:

  • ConsoleUI.fdf — Top/bottom decorative art bars
  • ResourceBar.fdf — Gold/lumber/supply/upkeep with named icons and text frames
  • UpperButtonBar.fdf — Quests/Menu/Allies/Chat buttons with full template inheritance
  • InfoPanelUnitDetail.fdf — Unit selection: name, armor, damage, speed, range, hero attributes
  • InfoPanelBuildingDetail.fdf — Building selection: name, armor, supply, build queue
  • InfoPanelItemDetail.fdf — Item selection: name, description
  • SimpleInfoPanel.fdf — Simplified variants (non-hero, cargo, ally resources)
  • CinematicPanel.fdf — Cinematic dialogue UI
  • InfoPanelTemplates.fdf — Shared text/label/value templates

Frozen Throne ConsoleUI.fdf extends the base with wider layout (ConsoleTexture05/ConsoleTexture06).

Architecture

stb_fdf.h — shared FDF library

Extract the FDF parser + frame API from ui_fdf.c into a single-header stb_fdf.h:

  • FRAMEDEF struct and types (frame point, frame type enum)
  • FDF parser (UI_ParseFDF, UI_EnsureFDF, template inheritance)
  • Programmatic frame API (UI_InitFrame, UI_SetPoint, UI_SetText, UI_Spawn, UI_FindFrame, etc.)
  • BZ_FDF_BIND_* macros and convenience macros

Both ui/ and game/ include this header. Write functions (UI_WriteFrame, UI_WriteLayout) are declared as extern stubs — each module provides its own implementation:

  • ui/ gets no-op stubs (client doesn't write svc_layout)
  • game/ keeps real implementations for any remaining server-authored layouts

ConsoleUI screen controller — client-side

One .c file per panel in ui/screens/:

Screen Controller Binding Header FDF
console_ui.c generated/console_ui.h ConsoleUI.fdf
resource_bar.c generated/resource_bar.h (exists) ResourceBar.fdf
upper_button_bar.c generated/upper_button_bar.h UpperButtonBar.fdf
info_panel.c generated/info_panel_unit_detail.h InfoPanelUnitDetail.fdf
info_panel_building.c generated/info_panel_building_detail.h InfoPanelBuildingDetail.fdf
info_panel_item.c generated/info_panel_item_detail.h InfoPanelItemDetail.fdf
cinematic_panel.c generated/cinematic_panel.h (exists) CinematicPanel.fdf

Data flow

  • Server sends raw game data via existing svc_unit_ui messages (uiCommandButton_t[], uiInventoryItem_t[], uiQueueItem_t[])
  • Server sends player resources in playerState_t stats fields (PLAYERSTATE_RESOURCE_GOLD, etc.)
  • Client console_ui.c loads FDF, binds frames, populates dynamic content (gold text, unit name, command buttons, inventory slots)
  • Client renders through ui_render.c — no separate UIFRAME render path

Procedural panels

Command card, inventory, portrait, minimap, build queue, tooltips — spawned programmatically but anchored to FDF-defined container parents (same pattern as ui_dialog.c).

What gets deleted

  • g_ui_stubs.c — entire file
  • UIFRAME struct and related types
  • cl_layout.c / cl_unit_layout.cUIFRAME render path (keep for transient messages only)
  • The hardcoded pixel-coordinate macros (INFO_PANEL_X, COMMAND_BUTTON_CENTER_X, etc.)

Implementation steps

  1. Create stb_fdf.h — extract from ui_fdf.c, keeping the parser + frame API. Update ui_local.h to include it.
  2. Generate binding headers — run fdfbindgen on ConsoleUI FDF files.
  3. Write screen controllersconsole_ui.c and per-panel controllers following the ui/screens/ pattern.
  4. Wire data flow — connect ui.UpdateUnitUI() and playerState_t stats to the screen controllers.
  5. Delete g_ui_stubs.c and remove UIFRAME render path from cl_layout.c / cl_unit_layout.c.
  6. Update AGENTS.md — document stb_fdf.h, the per-panel pattern, and the ConsoleUI workflow.

Related

  • See doc/games/warcraft-3/docs/ui.md for the Phase 8 migration plan
  • console_ui.c is listed as a recognized gap in the UI migration docs
  • generated/resource_bar.h and generated/cinematic_panel.h already exist as stubs for this exact architecture

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestuiUser interfacewarcraft-3Warcraft III specific features

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions