Introduce the HubScreen as the main interface for managing resources, units, and mission selection, integrating with the GameStateManager for dynamic data binding. Implement the MissionBoard component to display and select available missions, enhancing user interaction with mission details and selection logic. Update the GameStateManager to handle transitions between game states, ensuring a seamless experience for players. Add tests for HubScreen and MissionBoard to validate functionality and integration with the overall game architecture.
4.9 KiB
4.9 KiB
| description | globs | alwaysApply |
|---|---|---|
| Architecture, visuals, and integration logic for the HubScreen component - the persistent main menu of the campaign | src/ui/screens/HubScreen.js | false |
HubScreen Component Rule
The HubScreen is the persistent "Main Menu" of the campaign where the player manages resources, units, and mission selection. It is a View that consumes data from the GameStateManager singleton.
Integration Architecture
Data Sources
- Wallet:
gameStateManager.persistence.loadProfile().currency(or similar cached state) - Roster:
gameStateManager.rosterManager.getDeployableUnits() - Unlocks: Derived from
gameStateManager.missionManager.completedMissions
Navigation Flow
- Entry: GameStateManager switches state to
STATE_META_HUB.index.htmlmounts<hub-screen> - Mission Selection:
- User clicks "Mission Board"
<hub-screen>mounts<mission-board>overlay<mission-board>emitsmission-selected
- Squad Assembly:
<hub-screen>catches event- Transitions to
STATE_TEAM_BUILDER(passing the selected Mission ID)
- Deployment:
- TeamBuilder emits
embark - GameStateManager handles embark (starts GameLoop)
- TeamBuilder emits
Visual Layout (The "Dusk Camp")
Style: 2.5D Parallax or Static Art background with UI overlays.
Theme: A makeshift military camp at twilight. Torches, magical lanterns, supplies piled high.
A. The Stage (Background)
- Image:
assets/images/ui/hub_bg_dusk.pngcovers 100% width/height - Hotspots: Invisible, clickable divs positioned absolutely over key art elements
- The Tent (Barracks):
top: 40%, left: 10%, width: 20%. Hover: Glows Blue - The Table (Missions):
top: 60%, left: 40%, width: 20%. Hover: Glows Gold - The Wagon (Market):
top: 50%, left: 80%, width: 15%. Hover: Glows Green
- The Tent (Barracks):
B. Top Bar (Status)
- Left: Game Logo
- Right: Resource Strip
[💎 450 Shards] [⚙️ 12 Cores] [Day 4]
C. Bottom Dock (Navigation)
- A row of large, labeled buttons acting as redundant navigation
[BARRACKS] [MISSIONS] [MARKET] [RESEARCH] [SYSTEM]- State: Buttons are disabled/greyed out if the facility is locked
D. Overlay Container (Modal Layer)
- A centralized div with a semi-transparent backdrop (
rgba(0,0,0,0.8)) where sub-screens (Barracks, MissionBoard) are rendered without leaving the Hub
TypeScript Interfaces
// src/types/HubInterfaces.ts
export interface HubState {
wallet: {
aetherShards: number;
ancientCores: number;
};
rosterSummary: {
total: number;
ready: number;
injured: number;
};
unlocks: {
market: boolean;
research: boolean;
};
activeOverlay: "NONE" | "BARRACKS" | "MISSIONS" | "MARKET" | "SYSTEM";
}
export interface HubEvents {
// Dispatched when the player wants to leave the Hub context entirely
"request-team-builder": {
detail: { missionId: string };
};
"save-and-quit": void;
}
Implementation Requirements
Component Structure
Create src/ui/screens/HubScreen.js as a LitElement:
- Imports: Import
gameStateManagersingleton andhtml,css,LitElement - State: Define properties for
wallet,unlocks, andactiveOverlay - Lifecycle: In
connectedCallback, readgameStateManager.persistenceto populate wallet/unlocks - Layout:
- Background img covering host
- Absolute divs for Hotspots
- Flexbox header for Resources
- Flexbox footer for Dock Buttons
- Centered div for Overlays
- Logic:
_openOverlay(type): Sets state_closeOverlay(): Sets state to NONE_onMissionSelected(e): Dispatchesrequest-team-builderto window/parent
- Lazy Loading: Use dynamic imports inside the
render()method
Conditions of Acceptance (CoA)
CoA 1: Live Data Binding
- On mount (
connectedCallback), the component must fetch wallet and roster data fromgameStateManager - The Top Bar must display the correct currency values
CoA 2: Hotspot & Dock Sync
- Clicking the "Mission Table" hotspot OR the "Missions" dock button must perform the same action: setting
activeOverlay = 'MISSIONS'
CoA 3: Overlay Management
- When
activeOverlayis'MISSIONS', the<mission-board>component must be rendered in the Overlay Container - Clicking "Close" or "Back" inside an overlay must set
activeOverlay = 'NONE'
CoA 4: Mission Handoff
- Selecting a mission in the Mission Board must dispatch an event that causes the Hub to dispatch
request-team-builder, effectively handing control back to the App Router
Event-Driven Architecture
- HubScreen must never directly call GameLoop or GameStateManager write operations
- All state changes must be communicated via CustomEvents
- Use
this.dispatchEvent(new CustomEvent('request-team-builder', { detail: { missionId } }))for navigation