
Bevy Dialogue System
Bevy 0.20 dialogue data: line tables in a resource, the current line index on a...
Install
npx skills add thedivergentai/Game-Dev-Agentic-Skills --skill bevy-dialogue-system -g -a claude-code -y- Repository
- thedivergentai/Game-Dev-Agentic-Skills917
- Category
- Writing
- Updated
- 19d ago
- License
- LGPL-3.0
- Context cost
- Mediumabout 2,316 tokens
- Runs scripts
- No, instructions only
What it does
Bevy 0.20 dialogue data: line tables in a resource, the current line index on a component, and choice flags filtered before the write. Use when lines or choices advance. Keywords: Bevy, dialogue, line index, choices, ECS.
Bevy dialogue system
When to use
Load this when lines, choices, or speaker ids advance. Rendering the line is bevy-ui-text.
ECS shape
- Components: a line id and a speaker id that you define.
- Resources: run-wide tables live in a resource (bevy-data-resources), not an autoload.
- Systems: mutate those components on
Updateor the fixed timestep. Use.chain()when damage must land before death. - Messages: one-shot facts (hit, pickup, quest advance) go through bevy-events-messaging. This file does not add a new event type name.
Engine counterparts
| Godot idea | Bevy idiom |
|---|---|
| Line table | A resource of ids and strings. |
| Current line | A component that stores the line index. |
| Portrait | An image handle via bevy-asset-scenes. Layout is bevy-ui-layout. |
Scope
Dialogue data is a resource of lines plus a component that stores the current line index. Rich text rendering belongs on bevy-ui-text.
[dependencies]
bevy = "0.20"
#[derive(Clone)]
struct LineDef {
speaker: &'static str,
text: &'static str,
next: Option<usize>,
}
#[derive(Resource)]
struct DialogueTable {
lines: Vec<LineDef>,
}
#[derive(Component)]
struct LineMark {
index: usize,
open: bool,
}
fn advance_line(
keys: Res<ButtonInput<KeyCode>>,
table: Res<DialogueTable>,
mut marks: Query<&mut LineMark>,
) {
if !keys.just_pressed(KeyCode::Space) {
return;
}
for mut mark in &mut marks {
if !mark.open {
continue;
}
let Some(line) = table.lines.get(mark.index) else {
mark.open = false;
continue;
};
match line.next {
Some(next) => mark.index = next,
None => mark.open = false,
}
}
}
