Prosecution / Defense
Design pattern addressing prosecution / defense, defining how this system creates engagement and supports the overall game experience.
Overview
As a core game system, prosecution / defense balances complexity with accessibility to engage diverse audiences. Designers must carefully balance the system's depth against its learning curve, ensuring that new players can engage while experienced players find room for mastery. The key to successful implementation lies in clear communication of rules, fair outcomes, and satisfying feedback for player actions.
Game Examples
Idle / Clicker Games
Idle / Clicker Games use this mechanic where players coordinate with teammates to build a competitive advantage. The mechanic creates natural tension and release cycles, resulting in memorable moments.
Fighting Games
Fighting Games use this mechanic where players weigh competing priorities to tell their own story. The system supports both casual and hardcore engagement, resulting in skill differentiation.
Pros & Cons
Advantages
- Rewards both creative problem-solving and team coordination
- Provides clear numerical feedback on player actions
- Provides long-term engagement for dedicated players
- Creates satisfying visual loops
Disadvantages
- Risk of tedium in multiplayer contexts
- Can create overwhelming when RNG is unfavorable
- Risk of frustration in multiplayer contexts
- Can create exploitation if not carefully balanced
Implementation Patterns
Story Engine
Optimized pattern for prosecution / defense that minimizes per-frame computation cost.
class ProsecutionDefenseEngine {
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();
}
}