# Enhanced Input System Architecture

## Problem Statement
The project has **no input system specification** despite 230+ cross-references to a non-existent [`BPC_InputManager`](../02-player/13_BPC_InputManager.md) across existing blueprint specs. UE5's Enhanced Input System must be architected into the framework using a centralized [`SS_EnhancedInputManager`](Game Instance Subsystem) that manages Input Mapping Context push/pop, priority, platform profiles, and input mode coordination with [`SS_UIManager`](docs/blueprints/06-ui/44_SS_UIManager.md).

## Proposed Solution

```mermaid
flowchart TD
    A[Game Boot / GI_GameFramework Init] --> B[SS_EnhancedInputManager.Initialize]
    B --> C[Load DA_InputMappingProfile]
    C --> D[Cache platform-specific IMCs]
    
    E[GM_CoreGameMode.OnPlayerPossess] --> F[SS_EnhancedInputManager.PushDefaultContext]
    F --> G[Add IMC_Default Priority 0 via EnhancedInputLocalPlayerSubsystem]
    
    H[Gameplay Event] --> I{Context Switch?}
    I -->|Open Inventory| J[PushContext IMC_WristwatchUI Priority 10]
    I -->|Pick Up Item| K[PushContext IMC_Inspection Priority 20]
    I -->|Enter Hiding| L[PushContext IMC_Hiding Priority 5]
    I -->|Open Pause| M[SS_UIManager.ShowMenu + PushContext IMC_UI Priority 100]
    
    N[Exit Context] --> O[SS_EnhancedInputManager.PopContext]
    O --> P[Remove IMC, restore lower priority contexts]
    
    Q[SS_SettingsSystem.ApplyControlSettings] --> R[SS_EnhancedInputManager.RebindKey]
    R --> S[Update IMC mappings via DA_InputMappingProfile]
```

### Architecture Decision: Centralized Subsystem (Option A)
`SS_EnhancedInputManager` is a **Game Instance Subsystem**, matching the project's existing [`SS_UIManager`](docs/blueprints/06-ui/44_SS_UIManager.md), [`SS_SettingsSystem`](docs/blueprints/12-settings/105_SS_SettingsSystem.md), and [`SS_SaveManager`](docs/blueprints/05-saveload/35_SS_SaveManager.md) pattern. It manages all Input Mapping Contexts globally, while individual systems request context pushes via a clean API (function calls + dispatchers).

### Context Priority Ladder

| Priority | Context | Trigger | Overrides |
|----------|---------|---------|-----------|
| 0 | `IMC_Default` | Persistent gameplay | Nothing |
| 5 | `IMC_Hiding` | Enter hiding spot | Movement, Interact |
| 10 | `IMC_WristwatchUI` | Open watch/inventory | Movement, Look |
| 20 | `IMC_Inspection` | Pick up 3D item | All below |
| 100 | `IMC_UI` | Pause/Settings/Journal | Everything |

Higher priority = takes precedence. Multiple contexts can be active simultaneously.

### Input Actions (IA_) Master Registry

#### Axis2D Inputs
| Action | Value Type | Used In | Description |
|--------|-----------|---------|-------------|
| `IA_Move` | Axis2D | IMC_Default | W/A/S/D + Left Stick → locomotion |
| `IA_Look` | Axis2D | IMC_Default | Mouse XY + Right Stick → camera |
| `IA_Inspect_Rotate` | Axis2D | IMC_Inspection | Mouse/Right Stick → rotate item |
| `IA_UI_Navigate` | Axis2D | IMC_WristwatchUI, IMC_UI | D-Pad/Arrows → menu navigation |
| `IA_Hide_Look` | Axis2D | IMC_Hiding | Mouse/Right Stick → look while hidden |

#### Axis1D Inputs
| Action | Value Type | Used In | Description |
|--------|-----------|---------|-------------|
| `IA_Inspect_Zoom` | Axis1D | IMC_Inspection | Scroll/LT-RT → zoom item |
| `IA_Hide_Peek` | Axis1D | IMC_Hiding | W/S → lean forward in hiding |
| `IA_QuickSlotScroll` | Axis1D | IMC_Default | Scroll wheel → cycle quick slots |

#### Digital (Bool) Inputs — Gameplay
| Action | Used In | PC Default | Gamepad Default | Description |
|--------|---------|------------|-----------------|-------------|
| `IA_Interact` | IMC_Default | E / Left Click | X / Square | Pick up, hold for physics-drag |
| `IA_PrimaryAction` | IMC_Default | LMB | RT / R2 | Fire weapon / Swing tool |
| `IA_SecondaryAction` | IMC_Default | RMB | LT / L2 | ADS / Shield |
| `IA_Sprint` | IMC_Default | L-Shift | L3 | Run (triggers stamina + stress) |
| `IA_Crouch` | IMC_Default | C / L-Ctrl | B / Circle | Sneak / crawl |
| `IA_Vault_Climb` | IMC_Default | Spacebar | A / Cross | Contextual parkour |
| `IA_Jump` | IMC_Default | Spacebar | A / Cross | Basic jump (coexists with Vault via context) |
| `IA_Flashlight` | IMC_Default | F | D-Pad Up | Toggle light |
| `IA_QuickHeal` | IMC_Default | Q / H | D-Pad Down | Consume health item |
| `IA_Reload` | IMC_Default | R | Y / Triangle | Reload weapon |
| `IA_OpenWatch` | IMC_Default | Tab / I | View / Touchpad | Wristwatch UI |
| `IA_PauseMenu` | IMC_Default | Esc / P | Menu / Options | Pause game |
| `IA_QuickSlot1`–`IA_QuickSlot8` | IMC_Default | 1–8 | None | Direct quick slot selection |

#### Digital (Bool) Inputs — Context-Specific
| Action | Used In | PC Default | Gamepad Default | Description |
|--------|---------|------------|-----------------|-------------|
| `IA_Inspect_Flip` | IMC_Inspection | F | Y / Triangle | Flip document |
| `IA_Cancel_Drop` | IMC_Inspection | RMB / Esc | B / Circle | Exit inspection |
| `IA_UI_Select` | IMC_WristwatchUI, IMC_UI | E / Enter | A / Cross | Confirm/equip |
| `IA_UI_Combine` | IMC_WristwatchUI | C | X / Square | Item combination |
| `IA_UI_DropItem` | IMC_WristwatchUI | X | Y / Triangle | Drop from inventory |
| `IA_CloseWatch` | IMC_WristwatchUI | Tab / Esc | B / Circle | Lower arm |
| `IA_UI_Back` | IMC_UI | Esc / Backspace | B / Circle | Back one menu level |
| `IA_Hide_HoldBreath` | IMC_Hiding | Spacebar (Hold) | LT+RT (Hold) | Suppress breathing |
| `IA_Exit_Hide` | IMC_Hiding | C / Esc | B / Circle | Leave hiding spot |

#### New Input Types Added (beyond user's original list)
| Action | Value Type | Used In | Description | Rationale |
|--------|-----------|---------|-------------|-----------|
| `IA_Jump` | Digital | IMC_Default | Separate from Vault for non-contextual jumps | Prevents accidental climbing when player just wants to jump |
| `IA_QuickSlotScroll` | Axis1D | IMC_Default | Cycle through 8 quick slots | Natural controller wheel support for inventory |
| `IA_QuickSlot1`–`IA_QuickSlot8` | Digital | IMC_Default | Direct slot access (KB only) | Quick weapon/item switching |
| `IA_UI_Back` | Digital | IMC_UI | Universal back navigation | Separates "back" from "cancel" semantics |
| `IA_ToggleAccessibility` | Digital | IMC_UI | Toggle accessibility features mid-game | Required by [`BPC_AccessibilitySettings`](../02-player/104_BPC_AccessibilitySettings.md) |
| `IA_SkipCutscene` | Digital | IMC_Default | Hold to skip (contextual) | Already referenced by [`BPC_CutsceneBridge`](../07-narrative/64_BPC_CutsceneBridge.md) |

## File Structure

```
docs/
  blueprints/
    15-input/                              # NEW directory
      128_SS_EnhancedInputManager.md       # Central subsystem spec
    14-data-assets/
      129_DA_InputMappingProfile.md        # Data Asset for platform profiles

Content/
  Framework/
    Input/                                 # NEW directory
      Actions/                             # IA_* Input Action assets
        IA_Move.uasset
        IA_Look.uasset
        IA_Interact.uasset
        ... (all 30+ IA_ assets)
      Contexts/                            # IMC_* Input Mapping Context assets
        IMC_Default.uasset
        IMC_Inspection.uasset
        IMC_WristwatchUI.uasset
        IMC_Hiding.uasset
        IMC_UI.uasset
    DataAssets/
      DA_InputMappingProfile.uasset        # Platform profiles
```

## API Contracts

### SS_EnhancedInputManager Interface

```cpp
// === Public Functions ===

// Initialize with a profile
void Initialize(DA_InputMappingProfile Profile);

// Context management (stack-based)
void PushContext(E_InputContext ContextType, int32 PriorityOverride = -1);
void PopContext(E_InputContext ContextType);
void SetContextPriority(E_InputContext ContextType, int32 NewPriority);
TArray<E_InputContext> GetActiveContexts() const;
bool IsContextActive(E_InputContext ContextType) const;

// Input state queries (read-only for other systems)
bool IsActionPressed(FName ActionName) const;
float GetActionValue1D(FName ActionName) const;
FVector2D GetActionValue2D(FName ActionName) const;

// Key rebinding (called by SS_SettingsSystem)
void RebindKey(FName ActionName, FKey NewKey, E_InputPlatform Platform);
void ResetToDefaultBindings(E_InputPlatform Platform);
TMap<FName, FKey> GetCurrentBindings(E_InputPlatform Platform) const;

// Input mode coordination with SS_UIManager
void SetInputModeUIOnly();
void SetInputModeGameOnly();
void SetInputModeGameAndUI();
```

### Enums

```cpp
enum E_InputContext {
    Default = 0,
    Hiding = 1,
    WristwatchUI = 2,
    Inspection = 3,
    UI = 4
};

enum E_InputPlatform {
    PC_KeyboardMouse = 0,
    Xbox = 1,
    PS5_DualSense = 2
};
```

### Event Dispatchers

| Dispatcher | Payload | Description |
|------------|---------|-------------|
| `OnContextPushed` | `E_InputContext Context, int32 Priority` | Fired when a new context is activated |
| `OnContextPopped` | `E_InputContext Context` | Fired when a context is removed |
| `OnInputModeChanged` | `E_InputMode NewMode` | Syncs with SS_UIManager for cursor visibility |
| `OnKeyRebound` | `FName ActionName, FKey NewKey` | Fired after rebinding for UI update |
| `OnPlatformChanged` | `E_InputPlatform NewPlatform` | Fired on input device hot-swap |

### Communication Matrix

| Source | Target | Method | Data |
|--------|--------|--------|------|
| SS_EnhancedInputManager | UEnhancedInputLocalPlayerSubsystem | Direct (UE5 API) | Add/Remove Mapping Context |
| SS_EnhancedInputManager | SS_UIManager | Direct | Input mode changes |
| SS_EnhancedInputManager | SS_SettingsSystem | Direct | Key rebinding requests |
| SS_EnhancedInputManager | WBP_InteractionPromptDisplay | Dispatcher | Current action key icons |
| BPC_InteractionDetector | SS_EnhancedInputManager | Function Call | IsActionPressed for interact |
| BPC_FirearmSystem | SS_EnhancedInputManager | Function Call | GetActionValue1D for trigger |
| BPC_CutsceneBridge | SS_EnhancedInputManager | Function Call | PushContext/PopContext |
| BP_PuzzleDeviceActor | SS_EnhancedInputManager | Function Call | PushContext(Inspection) |

## Success Criteria

1. All 30+ Input Actions are created and mapped across all 3 platforms (PC, Xbox, PS5)
2. Context switching is seamless: pushing a higher-priority context overrides lower ones without blocking
3. Key rebinding via SS_SettingsSystem persists across sessions
4. Input mode changes (GameOnly ↔ UIOnly) correctly show/hide cursor
5. All existing specs that reference `BPC_InputManager` are updated to reference `SS_EnhancedInputManager`
6. Quick slot scrolling and direct selection work on both KB+M and gamepad
7. Hold inputs (HoldBreath, physics-drag) correctly trigger on hold and cancel on early release
8. Cutscene skip works via hold-to-skip (not tap)