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