124 lines
4.4 KiB
Markdown
124 lines
4.4 KiB
Markdown
|
|
# **Hub UI Specification: The Forward Operating Base**
|
||
|
|
|
||
|
|
This document defines the architecture, visuals, and integration logic for the **Hub Screen**. This is the persistent "Main Menu" of the campaign where the player manages resources, units, and mission selection.
|
||
|
|
|
||
|
|
## **1. Integration Architecture**
|
||
|
|
|
||
|
|
The HubScreen is a **View** that consumes data from the **GameStateManager** singleton.
|
||
|
|
|
||
|
|
### **Data Sources**
|
||
|
|
|
||
|
|
- **Wallet:** gameStateManager.persistence.loadProfile().currency (or similar cached state).
|
||
|
|
- **Roster:** gameStateManager.rosterManager.getDeployableUnits().
|
||
|
|
- **Unlocks:** Derived from gameStateManager.missionManager.completedMissions.
|
||
|
|
|
||
|
|
### **Navigation Flow**
|
||
|
|
|
||
|
|
1. **Entry:** GameStateManager switches state to STATE_META_HUB. index.html mounts <hub-screen>.
|
||
|
|
2. **Mission Selection:**
|
||
|
|
- User clicks "Mission Board".
|
||
|
|
- <hub-screen> mounts <mission-board> overlay.
|
||
|
|
- <mission-board> emits mission-selected.
|
||
|
|
3. **Squad Assembly:**
|
||
|
|
- <hub-screen> catches event.
|
||
|
|
- Transitions to STATE_TEAM_BUILDER (passing the selected Mission ID).
|
||
|
|
4. **Deployment:**
|
||
|
|
- TeamBuilder emits embark.
|
||
|
|
- GameStateManager handles embark (starts GameLoop).
|
||
|
|
|
||
|
|
## **2. 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.png covers 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.
|
||
|
|
|
||
|
|
### **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.
|
||
|
|
|
||
|
|
## **3. 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;
|
||
|
|
}
|
||
|
|
|
||
|
|
## **4. Conditions of Acceptance (CoA)**
|
||
|
|
|
||
|
|
**CoA 1: Live Data Binding**
|
||
|
|
|
||
|
|
- On mount (connectedCallback), the component must fetch wallet and roster data from gameStateManager.
|
||
|
|
- 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 activeOverlay is '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.
|
||
|
|
|
||
|
|
## **5. Implementation Prompt**
|
||
|
|
|
||
|
|
"Create src/ui/screens/HubScreen.js as a LitElement.
|
||
|
|
|
||
|
|
1. **Imports:** Import gameStateManager singleton and html, css, LitElement.
|
||
|
|
2. **State:** Define properties for wallet, unlocks, and activeOverlay.
|
||
|
|
3. **Lifecycle:** In connectedCallback, read gameStateManager.persistence to populate wallet/unlocks.
|
||
|
|
4. **Layout:**
|
||
|
|
- Background img covering host.
|
||
|
|
- Absolute divs for Hotspots.
|
||
|
|
- Flexbox header for Resources.
|
||
|
|
- Flexbox footer for Dock Buttons.
|
||
|
|
- Centered div for Overlays.
|
||
|
|
5. **Logic:** > \* \_openOverlay(type): Sets state.
|
||
|
|
- \_closeOverlay(): Sets state to NONE.
|
||
|
|
- \_onMissionSelected(e): Dispatches request-team-builder to window/parent.
|
||
|
|
6. **Lazy Loading:** Use dynamic imports inside the render() method'
|