Loading
Group Project
HardDriverz

HardDriverz is an arcade racing game where players customize karts to race across gravity-defying tracks. Racers collect power-ups, navigate loops, and compete for lap times across single-player and split-screen multiplayer modes.

Gameplay trailer

HardDriverz Official Gameplay Trailer

Core contributions

As UI systems programmer on the team, I implemented the in-game HUD and the messaging architecture connecting it to gameplay systems:

  • Split-screen HUD framework (UMG_HudPannel, BPC_KartHud): An adaptive HUD system that repositions layout anchors, sizes, and widget instances according to active player counts (1, 2, or 4 players). Each element (lap counter, pickup, ranking, timer) runs as an independent component.
  • Event bus (BP_EventModule, TABLE_RegisterEvent): A decoupled message bus allowing gameplay systems to broadcast events to the HUD without holding direct widget references. Designers add new event types by adding rows to a DataTable.
HardDriverz HUD overall demo
Complete HUD system overview showing all widget components working together during gameplay.
0:00
/0:00
Full HUD system walkthrough demonstrating real-time event-driven updates across all widget components.

Technical overview

The primary goal was maintaining responsive UI updates across varying player counts without polling in Tick functions. The framework uses a push-based architecture where gameplay actors broadcast state changes to the message bus, and widgets react only when their bound events fire.

Architecture

The Event Module coordinates communication between gameplay actors and HUD panels:

graph TD
subgraph Gameplay Logic
P[Player Pawn] --> BPC_KH[BPC_KartHud Component]
P --> BPC_L[BPC_LapCounter Logic]
P --> BPC_P[Pickup System]
end

subgraph Messaging Layer
EB[BP_EventModule Message Bus]
DB[TABLE_RegisterEvent] -- Defines --> EB
BPC_L -- Broadcasts --> EB
BPC_P -- Broadcasts --> EB
end

subgraph UI Framework
UHP[UMG_HudPannel Controller]
EB -- Triggers Update --> UHP
UHP --> LC[UMG_HudLapCounter]
UHP --> RK[UMG_HudRanking]
UHP --> PK[UMG_HudPickup]
UHP --> TM[UMG_HudTimer]
end

HUD implementation

Adaptive split-screen layouts

UMG_HudPannel handles layout transitions across screen configurations:

  • View modes: An E_Layout enum configures func_RearrangeLayout to shift widget anchors between single-player, two-player horizontal split, and four-player quad split modes.
  • Context injection: BPC_KartHud acts as an injection component on the player pawn, passing initial player references into the HUD on initialization to avoid runtime searches.
0:00
/0:00
Multi-layout HUD supporting dynamic split-screen rearrangement based on player count.
Split screen layout variations by player count
Split-screen layout configurations adapting to 1, 2, and 4 player modes.

Modular widget components

Each HUD element operates as a standalone unit with its own event subscriptions:

  • Ranking: Updates player positions along the track using track spline distances broadcast over the event bus.
Ranking widget component
Ranking Widget. Real-time placement tracking within the competitive HUD.
  • Timing and lap counters: The timer and lap counter cache incoming split events and update only when crossing sector gates, avoiding per-frame text updates.
Lap counter widget with adaptive layout
Lap Counter. Adaptive widget reacting to progression events with layout-aware positioning.
Time counter widget with adaptive layout
Time Counter. Performance-optimized timer component with adaptive positioning per split mode.
  • Pickup display: Displays the currently held power-up and updates when item state changes occur.
Pickup widget with adaptive layout
Pickup System Widget. Event-driven item tracking unit with layout-responsive positioning.

Global event bus

BP_EventModule standardizes messaging across systems:

  • DataTable registration: Designers register event definitions in TABLE_RegisterEvent, creating new events without modifying Blueprint graphs.
  • Typed event holders: Each event maps to a DA_EventHolder data asset, keeping event signatures consistent across UI, audio, and visual effects.

Design decisions

Push updates over polling

Widgets do not read game state on tick. Instead, updates fire only when gameplay systems broadcast events over the bus, minimizing layout invalidation costs during races.

Data-driven layout anchors

Split-screen layouts reuse a single UMG_HudPannel instance rather than maintaining distinct widget hierarchies per split mode. The panel adjusts anchor coordinates and visibility parameters based on player count.

Component independence

Individual HUD elements manage their own lifecycle and event subscriptions. Disabling or adding a widget does not affect other UI elements.

Designer-accessible event tables

Game events are registered in DataTables, allowing non-programmers to define new event channels for audio, VFX, and UI triggers.

Decoupled system boundaries

Gameplay pawns and lap systems do not store UI widget references. BPC_KartHud establishes references at startup, and subsequent communications pass through the event bus.