77 lines
2.9 KiB
Markdown
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.
|