Minimal dialogue system featuring Animal Crossing style animalese voices for Godot 4. Each character speaks in a distinct synthesised voice by playing phoneme sounds per letter, driven by a simple plain-text .dialogue script format.
Inspired by Equalo's animalese-generator and used MattMarch's ACVoicebox as the base reference. Letter sounds taken from the same repo.
- Copy the
addons/dialogot/folder into your game project'saddons/folder. - In Godot: Project → Project Settings → Plugins, enable Dialogot.
This registers
DialogueManageras an autoload singleton automatically. - Add a
Voiceaudio bus in Project → Project Settings → Audio → Buses and attach anAudioEffectPitchShifteffect to it. The bus name must match theaudio_busfield on yourVoiceProfileresources (default:"Voice").
Open the project directly in Godot. DialogueManager is already registered as an autoload in project.godot and the example scene is set as the main scene.
addons/dialogot/ is the plugin — treat it as read-only. Updating the plugin means replacing that folder entirely, so never put game content inside it.
All game-specific files live in your own project tree, alongside your other assets:
res://
├── addons/dialogot/ ← plugin, do not modify
├── dialogues/ ← your .dialogue scripts
│ ├── act1/intro.dialogue
│ └── act2/boss.dialogue
├── characters/ ← CharacterProfile .tres files
│ ├── goofy.tres
│ └── donald.tres
├── voices/ ← VoiceProfile .tres files
│ └── gruff_old_man.tres
└── ui/dialogue/ ← custom dialogue box scenes
└── RPGBox.tscn ← extends BaseDialogueBox
All plugin types (VoiceProfile, CharacterProfile, DialogueParser, BaseDialogueBox, Dialogot) are registered globally when the plugin is enabled, so your files can reference them from anywhere without imports.
Note on sample VoiceProfiles:
addons/dialogot/VoiceProfiles/contains starter presets for reference. Copy any you want to use into your ownvoices/folder rather than referencing them by path directly — that way a plugin update can never change them under you.
Dialogue is written in plain .dialogue text files. To make them visible and editable in the Godot editor, add dialogue to Editor → Editor Settings → Docks → FileSystem → Textfile Extensions.
# Lines starting with # are comments.
[CHARACTER_NAME]
This is a line of dialogue.
[OTHER_CHARACTER auto_advance=true delay=1.5]
This line advances automatically after 1.5 seconds.
It supports [wave]BBCode[/wave] effects and [b]bold[/b] text.
- Each
[NAME]header starts a new dialogue line. auto_advance=trueskips waiting for player input.delay=<seconds>sets how long to wait before auto-advancing (default0.5).- Blank lines between paragraphs are ignored.
- Unknown character names produce a speakerless line (no crash).
A VoiceProfile is a .tres resource that controls how a character sounds. Create one via Inspector → New Resource → VoiceProfile, or duplicate one from addons/dialogot/VoiceProfiles/.
| Property | Description |
|---|---|
base_pitch |
Base pitch multiplier |
pitch_range |
Random pitch variance per phoneme |
inflection_shift |
Extra pitch added on questions (?) |
speed |
Playback speed |
word_gap |
Pause between words (seconds) |
sentence_gap |
Pause after sentence-ending punctuation (seconds) |
audio_bus |
Name of the audio bus to use (must have a PitchShift effect) |
A CharacterProfile is a .tres resource that binds a display name, portrait texture, and voice to a character.
var giovanni := CharacterProfile.new()
giovanni.display_name = "Giovanni"
giovanni.portrait = preload("res://assets/giovanni_portrait.png")
giovanni.voice = preload("res://voices/giovanni.tres")Or create them as .tres files in the inspector and preload them.
var file := FileAccess.open("res://dialogues/intro.dialogue", FileAccess.READ)
var script := DialogueParser.parse(file.get_as_text(), {
"GIOVANNI": preload("res://characters/giovanni.tres"),
"LUCIFERO": preload("res://characters/lucifero.tres"),
})
DialogueManager.run_script(script)Instance addons/dialogot/DialogueUI.tscn into your scene. It connects to DialogueManager automatically and handles display, voicing, and input.
Player advances dialogue with the ui_accept action (default: Enter / Space). Pressing it mid-line skips to the end of the current line; pressing it again advances to the next.
DialogueManager.dialogue_started # emitted when run_script() is called
DialogueManager.dialogue_finished # emitted after the last line
DialogueManager.line_started(line) # emitted at the start of each DialogueLine
DialogueManager.line_finished(line) # emitted at the end of each DialogueLineThe dialogue box uses Godot's Theme system. Assign a custom Theme resource to the DialogueUI Control node (or to individual child nodes) in the inspector. Font overrides on NameLabel (a Label) and TextLabel (a RichTextLabel) follow standard Godot theme property overrides.
The visible panel is a PanelContainer named Box inside DialogueUI.tscn. To restyle it, instance the scene, select Box in the inspector, and set a theme_override_styles/panel override with a StyleBoxFlat or StyleBoxTexture.
For a completely different layout, create a new scene whose root script extends BaseDialogueBox and override show_line(line: DialogueLine):
extends BaseDialogueBox
func show_line(line: DialogueLine) -> void:
$MyLabel.text = line.text
# wire up your own Dialogot node, portrait, etc.Use your scene instead of DialogueUI.tscn. BaseDialogueBox already handles on_dialogue_started / on_dialogue_finished (show/hide), so you only need to implement show_line.
