# F1 Debug Menu Design

## Overview

An F1-toggled debug menu overlay that works regardless of the current scene. Introduces a new root scene (`game.tscn`) that hosts both the debug menu and the active game scene as children. The game pauses underneath while the debug menu is open.

## Scene Tree Structure

```
Game (Node, process_mode = PROCESS_MODE_ALWAYS)
├── DebugMenu (CanvasLayer, layer 100)
│   ├── Panel (PanelContainer)
│   │   ├── SceneList (VBoxContainer of Buttons)
│   │   └── CommandInput (LineEdit)
│   └── ResultLabel (Label, brief flash for command output)
└── ActiveSceneContainer (Node)
    └── <currently loaded scene>
```

- `Game` is the new main scene, replacing `strategy_phase.tscn` as the entry point in `project.godot`.
- `DebugMenu` uses a high `CanvasLayer` (layer 100) so it always renders above the active scene.
- `ActiveSceneContainer` is a plain `Node` whose child gets swapped when changing scenes.
- `Game` has `process_mode = PROCESS_MODE_ALWAYS` so it can receive F1 input even while the tree is paused.

## Responsibilities

### Game (`game.gd`)

Thin shell only:

- F1 input toggles `DebugMenu` visibility.
- When debug menu opens: sets `ActiveSceneContainer.process_mode = PROCESS_MODE_DISABLED`.
- When debug menu closes: sets `ActiveSceneContainer.process_mode = PROCESS_MODE_INHERIT`.
- Loads the default scene (strategy_phase) into `ActiveSceneContainer` at startup.
- Passes a reference to `ActiveSceneContainer` to `DebugMenu` at `_ready()`.

### DebugMenu (`debug_menu.gd`)

Owns all debug functionality:

- **Scene registry**: hardcoded array of scene entries.
- **Scene swapping**: frees old child of `ActiveSceneContainer`, instantiates new scene, applies setup if present.
- **Command console**: parses input, dispatches to registered commands or falls back to expression eval.
- **Command registration**: holds an explicit `Array[ConsoleCommand]` populated at `_ready()`.

## Scene Swapping

### Registry Format

A hardcoded array in `DebugMenu`:

```gdscript
var scene_registry: Array = [
    { "name": "Strategy Phase", "path": "res://scenes/strategy_phase.tscn" },
    { "name": "Strategy Phase (Test Data)", "path": "res://scenes/strategy_phase.tscn", "setup": "test_data" },
    { "name": "Main Menu", "path": "res://scenes/main_menu.tscn" },
    { "name": "Visual Novel", "path": "res://scenes/vn_scene.tscn" },
    { "name": "Dialogue", "path": "res://scenes/dialogue_scene.tscn" },
]
```

### Swap Flow

1. Free the current child of `ActiveSceneContainer`.
2. Instantiate the new scene from `path` and add as child.
3. If the entry has a `"setup"` key, call a setup method on `DebugMenu` that applies that configuration to the new scene instance.
4. Close the debug menu and signal `Game` to unpause.

### Setup Hooks

Setup functions live in `DebugMenu`, dispatched by matching the `"setup"` string key. This keeps test configurations self-contained within the debug system.

## Command Console

### Input

A `LineEdit` at the bottom of the debug panel. On Enter:

1. Split input text — first token is the command name, rest are arguments.
2. Check against registered commands by matching `get_command_name()`.
3. If found, call `run()` with args and context.
4. If no match, fall back to Godot's `Expression` class (evaluated with the active scene as base instance).
5. Show the result (or error) in `ResultLabel`, then hide it after 2 seconds using a `Timer` or `create_tween()`.

### Command Pattern

Base class:

```gdscript
class_name ConsoleCommand

func get_command_name() -> String:
    return ""

func get_help_text() -> String:
    return ""

func run(args: Array, context: Dictionary) -> String:
    return ""
```

Each command extends `ConsoleCommand` and overrides these three methods. The `context` dictionary provides access to the active scene container, debug menu reference, and other shared state without coupling commands to specific nodes.

Commands are explicitly registered in an `Array[ConsoleCommand]` in `DebugMenu._ready()`.

### Starter Commands

- **`help`** — lists all registered commands with their help text.
- **`swap <name>`** — scene swap by name (matches against registry entry names).
- **`list_scenes`** — prints available scene registry entries.

### Expression Eval Fallback

Uses Godot's `Expression` class. The expression executes with the current active scene as the base instance, allowing direct access to nodes and properties in the loaded scene. Errors are displayed in `ResultLabel`.

## File Organization

```
nodes/
├── game.gd                          # Thin shell
├── debug_menu.gd                    # Scene registry, command console, swap logic

resources/resource_definitions/
├── console_command.gd               # Base class

resources/console_commands/
├── swap_command.gd
├── help_command.gd
├── list_scenes_command.gd

scenes/
├── game.tscn                        # New root scene (new main_scene in project.godot)

prefabs/
├── debug_menu.tscn                  # CanvasLayer with panel, buttons, input, result label
```

Existing scenes are unchanged — they are loaded as children of `ActiveSceneContainer` instead of being the root.

## Key Decisions

- **No autoload**: The debug menu is a UI node, not a headless service. The `XXXServer` autoload pattern is reserved for game services like a future `SceneManagerServer`.
- **Explicit command registration**: Commands are listed in an array rather than auto-discovered from a folder. Simpler and more readable for a small number of commands. Can be swapped to auto-discovery later if needed.
- **Single-line output**: `ResultLabel` shows one result at a time with a brief display. No scrollable history for now.
- **Hardcoded scene list**: Entries can carry setup data/context, which auto-discovery from `.tscn` files wouldn't support.
