hud state management extended
Guide for hud state management extended
HUD State Management - Extended Pattern
Problem Evolution
Original Issue: The game's HUD was visible on the Main Menu screen.
Original Fix: Modified
ui_main_layout to only render HUD when GameState::Playing.New Issue: After implementing player spawning for Tutorial mode, the HUD was not visible when clicking "New Game" because it transitions to
GameState::Tutorial, not GameState::Playing.Extended Solution
Root Cause
The HUD visibility check was too restrictive:
// Original fix (too restrictive)
if *game_state.get() != crate::GameState::Playing {
return;
}This hid the HUD in all states except
Playing, including Tutorial where gameplay occurs.Updated Implementation
File:
src/systems/ui/mod.rs (lines 261-267)Before (HUD only in Playing):
// Hide HUD if not in Playing state
if *game_state.get() != crate::GameState::Playing {
return;
}After (HUD in Playing AND Tutorial):
// Hide HUD if not in Playing or Tutorial state
let state = game_state.get();
if *state != crate::GameState::Playing && *state != crate::GameState::Tutorial {
return;
}Why This Pattern Works
GameState Hierarchy:
MainMenu: No HUD (menu-only UI)Tutorial: ✅ HUD visible (active gameplay)Playing: ✅ HUD visible (active gameplay)Login: No HUD (authentication UI)Paused: Could show HUD (future consideration)
Design Principle: Show HUD in any state where the player is actively controlling their character and interacting with the game world.
Pattern Generalization
Multi-State UI Rendering
When UI elements should appear in multiple game states, use explicit state checks:
fn render_gameplay_ui(
game_state: Res<State<GameState>>,
// ... other params
) {
let state = game_state.get();
// Pattern: Explicit inclusion list
let is_gameplay_state = matches!(
*state,
GameState::Playing | GameState::Tutorial | GameState::Paused
);
if !is_gameplay_state {
return;
}
// Render UI...
}Alternative Pattern: Exclusion list (when most states should show UI):
fn render_common_ui(
game_state: Res<State<GameState>>,
// ... other params
) {
let state = game_state.get();
// Pattern: Explicit exclusion list
let is_menu_state = matches!(
*state,
GameState::MainMenu | GameState::Login
);
if is_menu_state {
return;
}
// Render UI...
}When to Use Each Pattern
Inclusion List (recommended for HUD):
- Use when UI should appear in a small, specific set of states
- Safer: Adding new states won't accidentally show UI
- Example: Gameplay HUD (only in Playing, Tutorial)
Exclusion List:
- Use when UI should appear in most states
- Example: Settings button (everywhere except loading screens)
Verification
After applying the extended fix:
cargo run --bin legends_clientTest Steps:
- Launch game → Main Menu appears (no HUD) ✅
- Click "New Game" → Transitions to
Tutorialstate ✅ - HUD appears (health, mana, inventory) ✅
- Click "Continue" → Transitions to
Playingstate ✅ - HUD remains visible ✅
Verification Status: ✅ CONFIRMED - HUD correctly appears in both Tutorial and Playing states.
Related Patterns
State-Specific UI Components
For UI that should only appear in specific states, use run conditions:
app.add_systems(
Update,
render_tutorial_hints.run_if(in_state(GameState::Tutorial))
);This is more efficient than early returns because the system doesn't run at all when not needed.
Hybrid Approach
Combine run conditions with internal state checks for complex UI:
app.add_systems(
Update,
render_gameplay_ui.run_if(in_state(GameState::Playing).or_else(in_state(GameState::Tutorial)))
);
fn render_gameplay_ui(
game_state: Res<State<GameState>>,
// ... other params
) {
// System only runs in Playing or Tutorial
// Internal logic can differentiate between states if needed
if *game_state.get() == GameState::Tutorial {
// Show tutorial-specific UI elements
}
// Render common gameplay UI...
}Files Modified
src/systems/ui/mod.rs(line 261-267): Extended HUD visibility check to includeTutorialstate
Related Knowledge
- hud_state_management.md: Original HUD visibility fix (hiding on Main Menu)
- loh_player_spawning_system: Player spawning implementation that revealed this issue