# Game.tsx Refactoring - Implementation Guide

## Current Status

The 3,315-line `Game.tsx` file has been partially refactored into a modular structure.

## Completed Work

### ✅ Created Structure
```
src/components/game/
├── types.ts                    # All TypeScript interfaces
├── hooks/
│   └── useGameEngine.ts        # Core state management hook
└── MovementControls.tsx        # Movement/compass component
```

### ✅ types.ts
Contains all game-related interfaces:
- `PlayerState` - Player location, health, stamina, inventory
- `DirectionDetail` - Movement directions with costs
- `Location` - Current location data
- `Profile` - Character stats and attributes  
- `CombatLogEntry` - Combat message format
- `LocationMessage` - Location event messages
- `Equipment` - Equipment slots
- `CombatState` - Combat status (PvE and PvP)
- `WorkbenchTab` - Crafting menu tabs
- `MobileMenuState` - Mobile UI state

### ✅ useGameEngine.ts
Core state management hook that exports:

**State Object:**
- All game state (player, location, profile, combat, etc.)
- UI state (menus, mobile, filters, etc.)
- Cooldowns and timers

**Actions Object:**
- Data fetching functions
- Movement handlers
- Item handlers (pickup, use, equip, drop)
- Crafting/workbench handlers
- Combat handlers (PvE and PvP)
- Interaction handlers
- UI state setters

**Usage Pattern:**
```tsx
const [state, actions] = useGameEngine(token, handleWebSocketMessage)

// Access state
state.playerState
state.location
state.combatState

// Call actions
actions.handleMove('north')
actions.handlePickup(itemId)
actions.fetchGameData()
```

### ✅ MovementControls.tsx
Extracted movement UI component:
- Compass grid (8 directions)
- Special movement buttons (up/down/enter/exit)
- Stamina cost display
- Cooldown indicators
- Direction availability logic

## Next Steps to Complete Refactoring

### 1. Create Remaining Components

**CombatView.tsx** - Extract combat UI (approx. 400-500 lines)
```tsx
interface CombatViewProps {
  combatState: CombatState
  combatLog: CombatLogEntry[]
  profile: Profile
  equipment: Equipment
  onCombatAction: (action: string) => void
  onFlee: () => void
  onPvPAction: (action: string, targetId: number) => void
  onPvPAcknowledge: () => void
}
```

**LocationView.tsx** - Extract location display (approx. 800-1000 lines)
```tsx
interface LocationViewProps {
  location: Location
  profile: Profile
  locationMessages: LocationMessage[]
  interactableCooldowns: Record<string, number>
  onPickup: (itemId: number, quantity?: number) => void
  onInteract: (interactableId: string, actionId: string) => void
  onInitiateCombat: (enemyId: number) => void
  onLootCorpse: (corpseId: string) => void
  onViewCorpseDetails: (corpseId: string) => void
}
```

**PlayerSidebar.tsx** - Extract inventory/equipment UI (approx. 600-800 lines)
```tsx
interface PlayerSidebarProps {
  profile: Profile
  playerState: PlayerState
  equipment: Equipment
  collapsedCategories: Set<string>
  onUseItem: (itemId: string) => void
  onEquipItem: (inventoryId: number) => void
  onUnequipItem: (slot: string) => void
  onDropItem: (itemId: string, quantity?: number) => void
  onSpendPoint: (stat: string) => void
  toggleCategory: (category: string) => void
}
```

**Workbench.tsx** - Extract crafting/repair UI (approx. 400-500 lines)
```tsx
interface WorkbenchProps {
  showCraftingMenu: boolean
  showRepairMenu: boolean
  workbenchTab: WorkbenchTab
  craftableItems: any[]
  repairableItems: any[]
  uncraftableItems: any[]
  craftFilter: string
  repairFilter: string
  uncraftFilter: string
  onClose: () => void
  onCraft: (itemId: string) => void
  onRepair: (uniqueItemId: number, inventoryId?: number) => void
  onUncraft: (uniqueItemId: number, inventoryId: number) => void
  onSwitchTab: (tab: WorkbenchTab) => void
  setCraftFilter: (filter: string) => void
  setRepairFilter: (filter: string) => void
  setUncraftFilter: (filter: string) => void
}
```

### 2. Update Game.tsx

Refactored Game.tsx should become a simple orchestrator:

```tsx
import { useGameWebSocket } from '../hooks/useGameWebSocket'
import { useGameEngine } from './game/hooks/useGameEngine'
import GameHeader from './GameHeader'
import MovementControls from './game/MovementControls'
import CombatView from './game/CombatView'
import LocationView from './game/LocationView'
import PlayerSidebar from './game/PlayerSidebar'
import Workbench from './game/Workbench'
import './Game.css'

function Game() {
  const token = localStorage.getItem('token')
  
  // WebSocket handler
  const handleWebSocketMessage = async (message: any) => {
    // WebSocket message handling logic
  }
  
  // Use WebSocket hook
  useGameWebSocket(token, handleWebSocketMessage)
  
  // Use game engine hook
  const [state, actions] = useGameEngine(token, handleWebSocketMessage)
  
  // Loading/error states
  if (state.loading) {
    return <div className="loading">Loading game...</div>
  }
  
  if (!state.playerState || !state.location) {
    return <div className="error">Failed to load game state</div>
  }
  
  return (
    <div className="game-container">
      {/* Death Overlay */}
      {state.profile?.is_dead && (
        <div className="death-overlay">
          <div className="death-modal">
            <h1>💀 You Have Died</h1>
            <p>Your character has been defeated in combat.</p>
            <button onClick={() => window.location.href = '/characters'}>
              Return to Character Selection
            </button>
          </div>
        </div>
      )}
      
      <GameHeader className={state.mobileHeaderOpen ? 'open' : ''} />

      <main className="game-main">
        <div className="explore-tab-desktop">
          {/* Left Sidebar */}
          <div className={`left-sidebar mobile-menu-panel ${state.mobileMenuOpen === 'left' ? 'open' : ''}`}>
            <MovementControls
              location={state.location}
              profile={state.profile}
              combatState={state.combatState}
              movementCooldown={state.movementCooldown}
              onMove={actions.handleMove}
            />
            
            <LocationView
              location={state.location}
              profile={state.profile}
              locationMessages={state.locationMessages}
              interactableCooldowns={state.interactableCooldowns}
              onPickup={actions.handlePickup}
              onInteract={actions.handleInteract}
              onInitiateCombat={actions.handleInitiateCombat}
              onLootCorpse={actions.handleLootCorpse}
              onViewCorpseDetails={actions.handleViewCorpseDetails}
            />
          </div>

          {/* Center - Combat or Location */}
          <div className="center-panel mobile-menu-panel">
            {state.combatState ? (
              <CombatView
                combatState={state.combatState}
                combatLog={state.combatLog}
                profile={state.profile}
                equipment={state.equipment}
                onCombatAction={actions.handleCombatAction}
                onFlee={actions.handleFlee}
                onPvPAction={actions.handlePvPAction}
                onPvPAcknowledge={actions.handlePvPAcknowledge}
              />
            ) : (
              <div className="location-display">
                {/* Location image and description */}
              </div>
            )}
          </div>

          {/* Right Sidebar */}
          <div className={`right-sidebar mobile-menu-panel ${state.mobileMenuOpen === 'right' ? 'open' : ''}`}>
            <PlayerSidebar
              profile={state.profile}
              playerState={state.playerState}
              equipment={state.equipment}
              collapsedCategories={state.collapsedCategories}
              onUseItem={actions.handleUseItem}
              onEquipItem={actions.handleEquipItem}
              onUnequipItem={actions.handleUnequipItem}
              onDropItem={actions.handleDropItem}
              onSpendPoint={actions.handleSpendPoint}
              toggleCategory={actions.toggleCategoryCollapse}
            />
          </div>
        </div>

        {/* Mobile Navigation */}
        <div className="mobile-menu-buttons">
          <button onClick={() => actions.setMobileMenuOpen(state.mobileMenuOpen === 'left' ? 'none' : 'left')}>
            <span>🧭</span>
          </button>
          <button onClick={() => actions.setMobileMenuOpen(state.mobileMenuOpen === 'bottom' ? 'none' : 'bottom')} disabled={!!state.combatState}>
            <span>📍</span>
          </button>
          <button onClick={() => actions.setMobileMenuOpen(state.mobileMenuOpen === 'right' ? 'none' : 'right')}>
            <span>🎒</span>
          </button>
        </div>
      </main>

      {/* Workbench Modal */}
      {(state.showCraftingMenu || state.showRepairMenu) && (
        <Workbench
          showCraftingMenu={state.showCraftingMenu}
          showRepairMenu={state.showRepairMenu}
          workbenchTab={state.workbenchTab}
          craftableItems={state.craftableItems}
          repairableItems={state.repairableItems}
          uncraftableItems={state.uncraftableItems}
          craftFilter={state.craftFilter}
          repairFilter={state.repairFilter}
          uncraftFilter={state.uncraftFilter}
          onClose={actions.handleCloseCrafting}
          onCraft={actions.handleCraft}
          onRepair={actions.handleRepairFromMenu}
          onUncraft={actions.handleUncraft}
          onSwitchTab={actions.handleSwitchWorkbenchTab}
          setCraftFilter={actions.setCraftFilter}
          setRepairFilter={actions.setRepairFilter}
          setUncraftFilter={actions.setUncraftFilter}
        />
      )}
    </div>
  )
}

export default Game
```

### 3. Implementation Strategy

**Phase 1: Extract Combat (Highest Priority)**
- Combat is self-contained and frequently used
- ~400-500 lines reduction
- Create `CombatView.tsx` with all combat UI logic

**Phase 2: Extract Location View**
- Second largest section (~800-1000 lines)
- Create `LocationView.tsx` with NPCs, items, interactables, corpses, other players

**Phase 3: Extract Player Sidebar**
- Inventory, equipment, stats display
- ~600-800 lines
- Create `PlayerSidebar.tsx`

**Phase 4: Extract Workbench**
- Crafting, repair, salvage UI
- ~400-500 lines  
- Create `Workbench.tsx`

**Phase 5: Final Integration**
- Update Game.tsx to use all components
- Test thoroughly
- Fix any integration issues

### 4. Benefits After Completion

**Before:**
- 1 file: 3,315 lines
- Hard to navigate
- Difficult to test individual features
- Merge conflicts likely

**After:**
- Main file: ~200-300 lines (orchestration)
- useGameEngine: ~600-800 lines (logic)
- 5 component files: ~400-1000 lines each
- Clear separation of concerns
- Easy to test components individually
- Parallel development possible

### 5. Testing Checklist

After refactoring, verify:
- ✅ Movement works (compass, special directions)
- ✅ Combat starts and ends correctly
- ✅ Inventory management (use, equip, drop)
- ✅ Crafting/repair/salvage
- ✅ Interactables and cooldowns
- ✅ Corpse looting
- ✅ PvP combat
- ✅ WebSocket updates
- ✅ Mobile responsive menus
- ✅ Death overlay
- ✅ Stat point spending

## Implementation Notes

**useGameEngine Hook Pattern:**
- Separates state management from UI
- Provides clean API for actions
- Can be tested independently
- Reduces prop drilling

**Component Props Pattern:**
- Each component receives only what it needs
- Clear interfaces defined
- Easy to understand dependencies
- Facilitates unit testing

**File Organization:**
- `types.ts` - Single source of truth for interfaces
- `hooks/` - Reusable logic hooks
- Component files - UI-only, minimal logic
- `Game.tsx` - Orchestration and layout only

## Current File Sizes

```
Original:
└── Game.tsx (3,315 lines)

Refactored:
├── types.ts (89 lines)
├── hooks/useGameEngine.ts (~600 lines, with placeholders)
├── MovementControls.tsx (168 lines)
└── Game.tsx (pending refactor)

To Create:
├── CombatView.tsx (~400-500 lines)
├── LocationView.tsx (~800-1000 lines)
├── PlayerSidebar.tsx (~600-800 lines)
└── Workbench.tsx (~400-500 lines)
```

## Next Immediate Steps

1. Complete all handler implementations in `useGameEngine.ts` (currently placeholders)
2. Extract combat UI to `CombatView.tsx`  
3. Extract location UI to `LocationView.tsx`
4. Extract inventory UI to `PlayerSidebar.tsx`
5. Extract crafting UI to `Workbench.tsx`
6. Refactor main `Game.tsx` to use all components
7. Test thoroughly

---

**Note:** The refactoring foundation is complete. The remaining work is to extract the JSX sections from the original Game.tsx into the respective component files, following the interfaces defined above.
