Keyword-Based Dialogue
Design pattern addressing keyword-based dialogue, defining how this system creates engagement and supports the overall game experience.
Overview
Keyword-Based Dialogue represents a design pattern that balances complexity with accessibility to engage diverse audiences. Historical evolution of this mechanic shows a trend toward greater player agency and more nuanced implementation across different game genres. The ongoing evolution of this mechanic reflects the broader maturation of game design as a discipline.
Game Examples
Looter Shooters
Looter Shooters use this mechanic where players time their actions precisely to establish dominance in PvP. The system tracks multiple variables simultaneously, resulting in a deeply engaging gameplay loop.
Asymmetric Games
Asymmetric Games use this mechanic where players interact with NPCs to create unique character builds. Randomized elements ensure variety across sessions, resulting in personal achievement.
Extraction Shooters
Extraction Shooters use this mechanic where players invest in long-term growth to collect all available items. The learning curve is steep but rewarding, resulting in skill differentiation.
Pros & Cons
Advantages
- Provides long-term engagement for dedicated players
- Rewards both creative problem-solving and mechanical skill
- Reduces frustration while maintaining challenge
- Supports several viable strategies and approaches
Disadvantages
- Creates potential for cheese strategies by experienced players
- Can feel punishing if progression is too slow
- Increases memory requirements significantly
- Can create power creep if not carefully balanced
Implementation Patterns
Lore Database
A modular approach to keyword-based dialogue that separates concerns and enables easy testing.
class KeywordBasedDialogueManager {
currentNode: string = "start";
flags: Set<string> = new Set();
getDialogue() {
const node = DIALOGUE_TREE[this.currentNode];
return {
text: node.text,
choices: node.choices.filter(c =>
!c.requires || c.requires.every(f => this.flags.has(f))
)
};
}
choose(choiceIndex: number) {
const node = DIALOGUE_TREE[this.currentNode];
const choice = node.choices[choiceIndex];
if (choice.setsFlag) this.flags.add(choice.setsFlag);
this.currentNode = choice.next;
return this.getDialogue();
}
}Lore Database
A modular approach to keyword-based dialogue that separates concerns and enables easy testing.
class KeywordBasedDialogueEngine {
currentNode: string = "opening";
flags: Set<string> = new Set();
getDialogue() {
const node = DIALOGUE_TREE[this.currentNode];
return {
text: node.text,
choices: node.choices.filter(c =>
!c.requires || c.requires.every(f => this.flags.has(f))
)
};
}
choose(choiceIndex: number) {
const node = DIALOGUE_TREE[this.currentNode];
const choice = node.choices[choiceIndex];
if (choice.setsFlag) this.flags.add(choice.setsFlag);
this.currentNode = choice.next;
return this.getDialogue();
}
}Choice Evaluator
Core implementation pattern for handling keyword-based dialogue logic with clean state management.
class KeywordBasedDialogueManager {
currentNode: string = "intro";
flags: Set<string> = new Set();
getDialogue() {
const node = DIALOGUE_TREE[this.currentNode];
return {
text: node.text,
choices: node.choices.filter(c =>
!c.requires || c.requires.every(f => this.flags.has(f))
)
};
}
choose(choiceIndex: number) {
const node = DIALOGUE_TREE[this.currentNode];
const choice = node.choices[choiceIndex];
if (choice.setsFlag) this.flags.add(choice.setsFlag);
this.currentNode = choice.next;
return this.getDialogue();
}
}