Peaceful / Violent Choice
Implementation of peaceful / violent choice that defines how players interact with this aspect of the game, including feedback and progression.
Overview
As a core game system, peaceful / violent choice provides meaningful choices and consequences for player actions. The implementation varies significantly across genres, with each game adapting the core concept to fit its specific design goals and target audience. The ongoing evolution of this mechanic reflects the broader maturation of game design as a discipline.
Game Examples
Cooking Games
Cooking Games use this mechanic where players customize their experience to complete objectives efficiently. Visual and audio feedback make the interaction satisfying, resulting in build diversity.
Metroidvanias
Metroidvanias use this mechanic where players track multiple variables to discover hidden content. The mechanic integrates seamlessly with other systems, resulting in exploration incentives.
Cooperative Games
Cooperative Games use this mechanic where players solve environmental puzzles to survive increasingly difficult challenges. The feedback loop reinforces player engagement, resulting in emergent storytelling.
Pros & Cons
Advantages
- Enhances economic without disrupting core gameplay
- Enables mechanical player expression
- Adds accessibility without excessive complexity
Disadvantages
- Can create griefing if not carefully balanced
- Requires significant development time to implement well
- Can become irrelevant in the late game
- May reduce pacing if implemented poorly
Implementation Patterns
NPC Scheduler
Core implementation pattern for handling peaceful / violent choice logic with clean state management.
class PeacefulViolentChoiceManager {
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();
}
}Story Engine
Data-driven implementation that loads peaceful / violent choice configuration from external definitions.
class PeacefulViolentChoiceManager {
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();
}
}NPC Scheduler
A modular approach to peaceful / violent choice that separates concerns and enables easy testing.
class PeacefulViolentChoiceHandler {
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();
}
}