Some changes
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# Dialogue System
|
||||
|
||||
All authored text — NPC conversations, item pickup messages, battle narration — is written in `.dialogue` files and played back via `DialogueManager` (godot_dialogue_manager v3.10.4).
|
||||
|
||||
## Plugin
|
||||
|
||||
- Autoload: `DialogueManager` (registered in `project.godot`)
|
||||
- Plugin must be enabled in Godot → Project Settings → Plugins → Dialogue Manager
|
||||
- `.dialogue` files are imported as `DialogueResource` once the plugin is active
|
||||
- Dialogue files live in `dialogue/` organised by category (`npc/`, `item/`, `battle/`)
|
||||
|
||||
## DialogueAction — the Cutscene bridge
|
||||
|
||||
[cutscene/dialogue/DialogueAction.gd](../../cutscene/dialogue/DialogueAction.gd) is the glue between the `Cutscene` queue and `DialogueManager`. It runs a `.dialogue` file through `VNTextbox` line-by-line and returns `CUTSCENE_CONTINUE` when the last line is dismissed.
|
||||
|
||||
```gdscript
|
||||
# Add a dialogue step to any Cutscene
|
||||
cutscene.addCallable(DialogueAction.getDialogueCallable(
|
||||
load("res://dialogue/npc/test.dialogue"),
|
||||
"start", # title to begin from
|
||||
[entity] # extra_game_states: objects/dicts accessible in the .dialogue file
|
||||
))
|
||||
```
|
||||
|
||||
Movement is blocked automatically while dialogue runs because `VNTextbox` is open (`EntityMovement._canMove()` checks `UI.TEXTBOX.isClosed`).
|
||||
|
||||
## Writing .dialogue files
|
||||
|
||||
```
|
||||
~ title_name # entry point / jump target
|
||||
|
||||
Speaker: Line of dialogue.
|
||||
Another line with no speaker.
|
||||
|
||||
~ another_section
|
||||
Speaker: Variables resolve inline: {{some_property}}.
|
||||
=> END # end this dialogue
|
||||
```
|
||||
|
||||
**Key syntax:**
|
||||
- `~ title` — section anchor; use as the `title` argument to `DialogueAction`
|
||||
- `=> title` — jump to another section; `=> END` ends the dialogue
|
||||
- `{{variable}}` — resolves a property from any autoload or `extra_game_states` object
|
||||
- `do AUTOLOAD.method()` — call a method on any autoload (e.g. `do PARTY.BACKPACK.addStack(stack)`)
|
||||
- `set AUTOLOAD.property = value` — set a property
|
||||
- `- Option text` — response branch (indented lines handle each branch)
|
||||
- `[if condition]` — conditional line or response
|
||||
|
||||
**Mutations fire automatically** before the next dialogue line is returned — you do not handle them manually in GDScript.
|
||||
|
||||
## Passing runtime data to dialogue
|
||||
|
||||
Use `extra_game_states` to expose GDScript objects to `{{variable}}` tokens:
|
||||
|
||||
```gdscript
|
||||
class ItemDialogueState:
|
||||
var item_name:String
|
||||
var quantity:int
|
||||
|
||||
DialogueAction.getDialogueCallable(resource, 'start', [ItemDialogueState.new("Potato", 1)])
|
||||
```
|
||||
|
||||
Then in the `.dialogue` file:
|
||||
```
|
||||
Obtained {{item_name}} x{{quantity}}.
|
||||
```
|
||||
|
||||
## NPC entities
|
||||
|
||||
Set these two exports on an Entity node whose `interactType = CONVERSATION`:
|
||||
|
||||
| Export | Purpose |
|
||||
|---|---|
|
||||
| `dialogueResource:DialogueResource` | The `.dialogue` file to run |
|
||||
| `dialogueTitle:String` | Title (section) to start from (default `"start"`) |
|
||||
|
||||
After first enabling the plugin and reimporting, assign `dialogueResource` directly in the Inspector. Until then, assign it in code (see [TestMap.gd](../../overworld/map/TestMap.gd) for the pattern).
|
||||
|
||||
## Dialogue files
|
||||
|
||||
| File | Used by |
|
||||
|---|---|
|
||||
| `dialogue/npc/test.dialogue` | TestMap NPC (NotPlayer) |
|
||||
| `dialogue/item/pickup.dialogue` | `ItemAction` — item pickup text with `{{item_name}}` and `{{quantity}}` |
|
||||
| `dialogue/battle/narration.dialogue` | `BattleCutsceneAction` — move announcements, victory/defeat |
|
||||
|
||||
## Response branching (current limitation)
|
||||
|
||||
`DialogueAction` auto-selects the **first allowed response** when a line has multiple options. There is no in-game response UI yet. To add one, replace the auto-select block in `DialogueAction.dialogueCallable` with a call to your response menu and `await` its selection signal.
|
||||
Reference in New Issue
Block a user