Files
Dawn-Godot/.claude/docs/architecture.md
T

77 lines
2.9 KiB
Markdown

# Architecture
## Singletons (Autoloads)
Never instantiate these — access only via the global handle.
| Handle | Role |
|---|---|
| `SCENE` | Current scene state; `SCENE.setScene(SceneSingleton.SceneType.X)` to switch |
| `TRANSITION` | Fade in/out; `TRANSITION.fade(FadeType, duration, color)` |
| `BATTLE` | Battle state and fighter map |
| `PARTY` | Party members (`PARTY.getFullParty()`) and `PARTY.BACKPACK` inventory |
| `OVERWORLD` | Map switching with threaded loading |
| `COOKING` | Cooking mini-game lifecycle |
| `SAVE` | Persistence (stub) |
| `SETTINGS` | Runtime settings — `invertCameraX:bool`, `invertCameraY:bool` |
| `QUEST` | Quest management (stub) |
| `CUTSCENE` | Cutscene global (stub) |
| `DialogueManager` | godot_dialogue_manager v3.10.4 — parses and steps through `.dialogue` files |
| `UI` | Root UI accessor — `UI.PAUSE_MENU`, `UI.QUIT_DIALOG`, `UI.MAIN_MENU_DIALOG`, `UI.BACKDROP`, `UI.DEBUG_MENU`, `UI.GAME_MENU` |
## Scene Graph
```
RootScene (Node3D)
└─ overworld / battle / cooking / initial ← one shown at a time
RootUI (Control, always visible)
├─ DebugMenu
├─ GameMenu
├─ ChatBoxContainer (world-space dialogue textboxes)
├─ ModalBackdrop (repositions dynamically — see ui.md)
├─ PauseMenu
├─ QuitConfirmDialog
└─ MainMenuConfirmDialog
```
`RootScene` listens to `SCENE.sceneChanged` and shows/hides the correct sub-tree.
## Cutscene / Event Queue
`Cutscene` is the universal sequencing engine. It holds an `Array[Dictionary]` queue; each entry has a `"function": Callable` plus arbitrary data keys.
**Return codes from a callable:**
- `Cutscene.CUTSCENE_CONTINUE` — advance to next item
- `Cutscene.CUTSCENE_END` — stop the cutscene
- An integer index — jump to that position
**Insertion positions:**
- `Cutscene.CUTSCENE_ADD_END` — append (default)
- `Cutscene.CUTSCENE_ADD_NEXT` — insert immediately after current
**Callable pattern** — every action class exposes a pair:
```gdscript
# The actual callable (static, takes params:Dictionary, returns int)
static func myCallable(params:Dictionary) -> int:
...
return Cutscene.CUTSCENE_CONTINUE
# Factory that builds the dictionary for addCallable()
static func getMyCallable(arg) -> Dictionary:
return { "function": myCallable, "myArg": arg }
```
## Data Registry Pattern
Static registries (Item, Recipe) follow this pattern:
1. `enum Id { NULL, ... }` — typed identifier
2. `static var DATA:Array = []` — indexed by Id value
3. `static func define(params) -> Dictionary` — called at class load to populate `DATA`
4. `static var FOO = define({...})` — registers the entry as a static var
5. `static func get*(id) -> *` — typed accessors
## `_init(params:Dictionary)` Pattern
Non-Node data classes (`BattleFighter`, `BattleDecision`, `ItemStack`, etc.) use a single `params` dictionary constructor with `.get('key', default)` for optional fields.