# skeg-16/sandbox-arena architecture

> Architecture diagram of the GitHub repository skeg-16/sandbox-arena, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-10-01). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/skeg-16/sandbox-arena
- Repository: https://github.com/skeg-16/sandbox-arena

## Overview

This is a browser-based 3D medieval battle sandbox with campaign and scenario modes. The player enters the arena, chooses a battleground or preset, selects units and formations, deploys forces, then observes or possesses a unit during combat; HUDs expose objectives, battle statistics, and health. The UI is backed by shared game state and a central engine that coordinates simulation systems. The source index documents additional rendering, terrain, fortification, and effects capabilities; links are shown only where the excerpts or index support them, so some subsystem connections remain unspecified.

Main entry points: [`src/sandbox/SandboxEngine.js`](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/SandboxEngine.js) (Sandbox Engine), [`src/App.jsx`](https://github.com/skeg-16/sandbox-arena/blob/main/src/App.jsx) (Arena App), [`src/store/useSandboxStore.js`](https://github.com/skeg-16/sandbox-arena/blob/main/src/store/useSandboxStore.js) (Game State), [`src/components/ScenarioPickerModal.jsx`](https://github.com/skeg-16/sandbox-arena/blob/main/src/components/ScenarioPickerModal.jsx) (Scenario Picker)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_interface["Arena Interface"]
  node_app["Arena App<br/>[App.jsx]"]
  node_canvas["3D Canvas"]
  node_navigation["Battle Navigation<br/>[TopNavHeader.jsx]"]
  node_unittray["Unit Selection<br/>[UnitTray.jsx]"]
  node_scenario["Scenario Picker"]
  node_presets["Preset Battles"]
  node_campaign["Campaign Setup<br/>[CampaignModal.jsx]"]
  node_environment["Environment Picker"]
  node_objectivehud["Objective HUD<br/>[ObjectiveHUD.jsx]"]
  node_possessionhud["Possession HUD<br/>[PossessionHUD.jsx]"]
  node_stats["Battle Statistics"]
end

subgraph group_runtime["Battle Runtime"]
  node_store["Game State<br/>[useSandboxStore.js]"]
  node_engine["Sandbox Engine<br/>[SandboxEngine.js]"]
end

subgraph group_combat["Combat Systems"]
  node_unit["Ragdoll Units"]
  node_ai["Battle AI<br/>[BattleAI.js]"]
  node_projectiles["Projectiles"]
  node_possession["Unit Possession"]
end

subgraph group_world["World Systems"]
  node_physics["Physics World<br/>[PhysicsWorld.js]"]
  node_scene["3D Scene<br/>[ThreeScene.js]"]
  node_terrain["Terrain<br/>[TerrainSystem.js]"]
  node_structures["Fortifications<br/>[StructureSystem.js]"]
  node_objectives["Objective Logic<br/>[ObjectiveSystem.js]"]
end

subgraph group_content["Game Content"]
  node_maps["Battleground Definitions<br/>[MapConfigs.js]"]
  node_unitconfig["Unit Definitions<br/>[UnitConfig.js]"]
  node_campaignconfig["Campaign Definitions<br/>[CampaignConfig.js]"]
  node_sound["Sound Synthesis<br/>[SoundSystem.js]"]
  node_materials["PBR Materials"]
end

node_player(("Player"))

node_player -->|"enters"| node_app
node_app -->|"renders"| node_canvas
node_app -->|"renders"| node_navigation
node_app -->|"renders"| node_unittray
node_app -->|"renders"| node_scenario
node_app -->|"renders"| node_presets
node_app -->|"renders"| node_campaign
node_app -->|"renders"| node_environment
node_app -->|"renders"| node_objectivehud
node_app -->|"renders"| node_possessionhud
node_app -->|"renders"| node_stats
node_canvas -->|"uses"| node_engine
node_navigation -->|"uses"| node_engine
node_unittray -->|"uses"| node_engine
node_scenario -->|"uses"| node_engine
node_presets -->|"uses"| node_engine
node_campaign -->|"uses"| node_engine
node_environment -->|"uses"| node_engine
node_possessionhud -->|"uses"| node_engine
node_stats -->|"uses"| node_engine
node_canvas -->|"reads state"| node_store
node_navigation -->|"reads state"| node_store
node_unittray -->|"reads state"| node_store
node_scenario -->|"reads state"| node_store
node_objectivehud -->|"reads state"| node_store
node_engine -->|"uses"| node_physics
node_engine -->|"creates"| node_scene
node_engine -->|"creates"| node_unit
node_engine -->|"uses"| node_ai
node_engine -->|"uses"| node_projectiles
node_engine -->|"uses"| node_possession
node_engine -->|"reads state"| node_store
node_unit -->|"loads definitions"| node_unitconfig
node_unit -->|"uses"| node_materials
node_terrain -->|"loads definitions"| node_maps
node_terrain -->|"uses"| node_materials
node_scene -->|"uses"| node_materials
node_scenario -->|"loads definitions"| node_maps
node_presets -->|"plays audio"| node_sound
node_objectives -->|"loads definitions"| node_maps

click node_app "https://github.com/skeg-16/sandbox-arena/blob/main/src/App.jsx"
click node_canvas "https://github.com/skeg-16/sandbox-arena/blob/main/src/components/CanvasContainer.jsx"
click node_navigation "https://github.com/skeg-16/sandbox-arena/blob/main/src/components/TopNavHeader.jsx"
click node_unittray "https://github.com/skeg-16/sandbox-arena/blob/main/src/components/UnitTray.jsx"
click node_scenario "https://github.com/skeg-16/sandbox-arena/blob/main/src/components/ScenarioPickerModal.jsx"
click node_presets "https://github.com/skeg-16/sandbox-arena/blob/main/src/components/PresetBattlesModal.jsx"
click node_campaign "https://github.com/skeg-16/sandbox-arena/blob/main/src/components/CampaignModal.jsx"
click node_environment "https://github.com/skeg-16/sandbox-arena/blob/main/src/components/EnvironmentPickerModal.jsx"
click node_objectivehud "https://github.com/skeg-16/sandbox-arena/blob/main/src/components/ObjectiveHUD.jsx"
click node_possessionhud "https://github.com/skeg-16/sandbox-arena/blob/main/src/components/PossessionHUD.jsx"
click node_stats "https://github.com/skeg-16/sandbox-arena/blob/main/src/components/BattleStatsOverlay.jsx"
click node_store "https://github.com/skeg-16/sandbox-arena/blob/main/src/store/useSandboxStore.js"
click node_engine "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/SandboxEngine.js"
click node_unit "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/ActiveRagdollUnit.js"
click node_ai "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/BattleAI.js"
click node_projectiles "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/ProjectileSystem.js"
click node_possession "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/PossessionController.js"
click node_physics "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/PhysicsWorld.js"
click node_scene "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/ThreeScene.js"
click node_terrain "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/TerrainSystem.js"
click node_structures "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/StructureSystem.js"
click node_objectives "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/ObjectiveSystem.js"
click node_maps "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/MapConfigs.js"
click node_unitconfig "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/UnitConfig.js"
click node_campaignconfig "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/CampaignConfig.js"
click node_sound "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/SoundSystem.js"
click node_materials "https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/PBRMaterialSystem.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_canvas,node_navigation,node_unittray,node_scenario,node_presets,node_campaign,node_environment,node_objectivehud,node_possessionhud,node_stats toneBlue
class node_store,node_engine toneAmber
class node_unit,node_ai,node_projectiles,node_possession toneMint
class node_physics,node_scene,node_terrain,node_structures,node_objectives toneRose
class node_maps,node_unitconfig,node_campaignconfig,node_sound,node_materials,node_player toneIndigo
```

## Components

### Arena Interface

- [Arena App](https://github.com/skeg-16/sandbox-arena/blob/main/src/App.jsx): `src/App.jsx`
- [3D Canvas](https://github.com/skeg-16/sandbox-arena/blob/main/src/components/CanvasContainer.jsx): `src/components/CanvasContainer.jsx`
- [Battle Navigation](https://github.com/skeg-16/sandbox-arena/blob/main/src/components/TopNavHeader.jsx): `src/components/TopNavHeader.jsx`
- [Unit Selection](https://github.com/skeg-16/sandbox-arena/blob/main/src/components/UnitTray.jsx): `src/components/UnitTray.jsx`
- [Scenario Picker](https://github.com/skeg-16/sandbox-arena/blob/main/src/components/ScenarioPickerModal.jsx): `src/components/ScenarioPickerModal.jsx`
- [Preset Battles](https://github.com/skeg-16/sandbox-arena/blob/main/src/components/PresetBattlesModal.jsx): `src/components/PresetBattlesModal.jsx`
- [Campaign Setup](https://github.com/skeg-16/sandbox-arena/blob/main/src/components/CampaignModal.jsx): `src/components/CampaignModal.jsx`
- [Environment Picker](https://github.com/skeg-16/sandbox-arena/blob/main/src/components/EnvironmentPickerModal.jsx): `src/components/EnvironmentPickerModal.jsx`
- [Objective HUD](https://github.com/skeg-16/sandbox-arena/blob/main/src/components/ObjectiveHUD.jsx): `src/components/ObjectiveHUD.jsx`
- [Possession HUD](https://github.com/skeg-16/sandbox-arena/blob/main/src/components/PossessionHUD.jsx): `src/components/PossessionHUD.jsx`
- [Battle Statistics](https://github.com/skeg-16/sandbox-arena/blob/main/src/components/BattleStatsOverlay.jsx): `src/components/BattleStatsOverlay.jsx`

### Battle Runtime

- [Game State](https://github.com/skeg-16/sandbox-arena/blob/main/src/store/useSandboxStore.js): `src/store/useSandboxStore.js`
- [Sandbox Engine](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/SandboxEngine.js): `src/sandbox/SandboxEngine.js`

### Combat Systems

- [Ragdoll Units](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/ActiveRagdollUnit.js): `src/sandbox/ActiveRagdollUnit.js`
- [Battle AI](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/BattleAI.js): `src/sandbox/BattleAI.js`
- [Projectiles](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/ProjectileSystem.js): `src/sandbox/ProjectileSystem.js`
- [Unit Possession](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/PossessionController.js): `src/sandbox/PossessionController.js`

### World Systems

- [Physics World](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/PhysicsWorld.js): `src/sandbox/PhysicsWorld.js`
- [3D Scene](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/ThreeScene.js): `src/sandbox/ThreeScene.js`
- [Terrain](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/TerrainSystem.js): `src/sandbox/TerrainSystem.js`
- [Fortifications](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/StructureSystem.js): `src/sandbox/StructureSystem.js`
- [Objective Logic](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/ObjectiveSystem.js): `src/sandbox/ObjectiveSystem.js`

### Game Content

- [Battleground Definitions](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/MapConfigs.js): `src/sandbox/MapConfigs.js`
- [Unit Definitions](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/UnitConfig.js): `src/sandbox/UnitConfig.js`
- [Campaign Definitions](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/CampaignConfig.js): `src/sandbox/CampaignConfig.js`
- [Sound Synthesis](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/SoundSystem.js): `src/sandbox/SoundSystem.js`
- [PBR Materials](https://github.com/skeg-16/sandbox-arena/blob/main/src/sandbox/PBRMaterialSystem.js): `src/sandbox/PBRMaterialSystem.js`

### Other components

- **Player**

## Connections

- Player → Arena App: enters (evidence: `src/App.jsx`)
- Arena App → 3D Canvas: renders (evidence: `src/App.jsx`)
- Arena App → Battle Navigation: renders (evidence: `src/App.jsx`)
- Arena App → Unit Selection: renders (evidence: `src/App.jsx`)
- Arena App → Scenario Picker: renders (evidence: `src/App.jsx`)
- Arena App → Preset Battles: renders (evidence: `src/App.jsx`)
- Arena App → Campaign Setup: renders (evidence: `src/App.jsx`)
- Arena App → Environment Picker: renders (evidence: `src/App.jsx`)
- Arena App → Objective HUD: renders (evidence: `src/App.jsx`)
- Arena App → Possession HUD: renders (evidence: `src/App.jsx`)
- Arena App → Battle Statistics: renders (evidence: `src/App.jsx`)
- 3D Canvas → Sandbox Engine: uses (evidence: `src/components/CanvasContainer.jsx`)
- Battle Navigation → Sandbox Engine: uses (evidence: `src/components/TopNavHeader.jsx`)
- Unit Selection → Sandbox Engine: uses (evidence: `src/components/UnitTray.jsx`)
- Scenario Picker → Sandbox Engine: uses (evidence: `src/components/ScenarioPickerModal.jsx`)
- Preset Battles → Sandbox Engine: uses (evidence: `src/components/PresetBattlesModal.jsx`)
- Campaign Setup → Sandbox Engine: uses (evidence: `src/components/CampaignModal.jsx`)
- Environment Picker → Sandbox Engine: uses (evidence: `src/components/EnvironmentPickerModal.jsx`)
- Possession HUD → Sandbox Engine: uses (evidence: `src/components/PossessionHUD.jsx`)
- Battle Statistics → Sandbox Engine: uses (evidence: `src/components/BattleStatsOverlay.jsx`)
- 3D Canvas → Game State: reads state (evidence: `src/components/CanvasContainer.jsx`)
- Battle Navigation → Game State: reads state (evidence: `src/components/TopNavHeader.jsx`)
- Unit Selection → Game State: reads state (evidence: `src/components/UnitTray.jsx`)
- Scenario Picker → Game State: reads state (evidence: `src/components/ScenarioPickerModal.jsx`)
- Objective HUD → Game State: reads state (evidence: `src/components/ObjectiveHUD.jsx`)
- Sandbox Engine → Physics World: uses (evidence: `src/sandbox/SandboxEngine.js`)
- Sandbox Engine → 3D Scene: creates (evidence: `src/sandbox/SandboxEngine.js`)
- Sandbox Engine → Ragdoll Units: creates (evidence: `src/sandbox/SandboxEngine.js`)
- Sandbox Engine → Battle AI: uses (evidence: `src/sandbox/SandboxEngine.js`)
- Sandbox Engine → Projectiles: uses (evidence: `src/sandbox/SandboxEngine.js`)
- Sandbox Engine → Unit Possession: uses (evidence: `src/sandbox/SandboxEngine.js`)
- Sandbox Engine → Game State: reads state (evidence: `src/sandbox/SandboxEngine.js`)
- Ragdoll Units → Unit Definitions: loads definitions (evidence: `src/sandbox/ActiveRagdollUnit.js`)
- Ragdoll Units → PBR Materials: uses (evidence: `src/sandbox/ActiveRagdollUnit.js`)
- Terrain → Battleground Definitions: loads definitions (evidence: `src/sandbox/TerrainSystem.js`)
- Terrain → PBR Materials: uses (evidence: `src/sandbox/TerrainSystem.js`)
- 3D Scene → PBR Materials: uses (evidence: `src/sandbox/ThreeScene.js`)
- Scenario Picker → Battleground Definitions: loads definitions (evidence: `src/components/ScenarioPickerModal.jsx`)
- Preset Battles → Sound Synthesis: plays audio (evidence: `src/components/PresetBattlesModal.jsx`)
- Objective Logic → Battleground Definitions: loads definitions (evidence: `src/sandbox/ObjectiveSystem.js`)
