Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Tags

The tags of a line or of a choice reach the game apart from the text, in the tags field of DialogueLine and of DialogueChoice. What they mean is up to the game.

:= start
Alice: #angry Give it back! #sound:alice_01
-> #hostile Refuse
-> Give it back #cost:3
---

A Tag has a name, and a value when one is written after the :. The value is kept as text, whatever it looks like: #volume:0.5 holds the string 0.5.

On a line

#![allow(unused)]
fn main() {
use bevy::prelude::*;
use bevy_replique::prelude::*;
fn react_to_tags(mut lines: MessageReader<DialogueLine>) {
    for line in lines.read() {
        for tag in &line.tags {
            match (tag.name.as_str(), tag.value.as_deref()) {
                // `#angry`
                ("angry", None) => info!("{:?} is angry", line.speaker),
                // `#sound:alice_01`
                ("sound", Some(sound)) => info!("playing {sound}"),
                // `#volume:0.5`
                ("volume", Some(volume)) => match volume.parse::<f32>() {
                    Ok(volume) => info!("volume set to {volume}"),
                    Err(_) => warn!("`{volume}` is not a volume"),
                },
                _ => {}
            }
        }
    }
}
let mut app = App::new();
app.add_systems(Update, react_to_tags);
}

The text of the line comes without its tags: here line.text is Give it back!.

On a choice

Each choice carries its own tags, which suits what the interface needs to know to draw it: an icon, a cost, a colour.

#![allow(unused)]
fn main() {
use bevy::prelude::*;
use bevy_replique::prelude::*;
fn show_choices(mut groups: MessageReader<DialogueChoices>) {
    for group in groups.read() {
        for choice in &group.choices {
            let hostile = choice.tags.iter().any(|tag| tag.name == "hostile");
            let cost = choice
                .tags
                .iter()
                .find(|tag| tag.name == "cost")
                .and_then(|tag| tag.value.as_deref());

            match (hostile, cost) {
                (true, _) => println!("[!] {}", choice.text),
                (false, Some(cost)) => println!("{} ({cost} coins)", choice.text),
                (false, None) => println!("{}", choice.text),
            }
        }
    }
}
let mut app = App::new();
app.add_systems(Update, show_choices);
}

Tags or commands?

A tag describes the line it is on, and arrives with it: a mood, a voice-over file, a portrait to show. A command is a step of its own, played between two lines, and the dialogue can wait for it. A sound that goes with a line is a tag; a door that opens before the next line is a command.

Checking the tags

A typo in a tag is silent: #angy is a valid tag that the game ignores. Declaring the tags of the project in a replique.toml lets replique check and the editor report the ones the game does not know. See the replique-cli README.