Browse/Narrative & Choice/Prosecution / Defense
Narrative & Choice

Prosecution / Defense

Design pattern addressing prosecution / defense, defining how this system creates engagement and supports the overall game experience.

Medium complexity
2 examples
1 patterns

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();
  }
}