Browse/Narrative & Choice/Resistance / Rebellion
Narrative & Choice

Resistance / Rebellion

Framework for implementing resistance / rebellion in games, covering the core loop, edge cases, and integration points.

Medium complexity
2 examples
2 patterns

Overview

Resistance / Rebellion is a fundamental game mechanic that balances complexity with accessibility to engage diverse audiences. The mechanic interacts with multiple other game systems, creating emergent gameplay that extends beyond its individual components. Modern implementations often combine this mechanic with procedural elements to increase variety and replayability.

Game Examples

Dungeon Crawlers

Dungeon Crawlers use this mechanic where players navigate branching paths to unlock new abilities and options. Each decision has cascading consequences, resulting in a sense of mastery.

Bullet Hell Games

Bullet Hell Games use this mechanic where players interact with NPCs to progress through the content. Player choice meaningfully affects outcomes, resulting in skill differentiation.

Pros & Cons

Advantages

  • Creates natural synergy between players
  • Provides long-term mastery goals for dedicated players
  • Creates natural cooperation between players

Disadvantages

  • Requires extensive stress testing to avoid edge cases
  • Requires significant development time to implement well
  • Risk of frustration in competitive environments
  • Can create power creep if not carefully balanced
  • May create a skill gap for new players

Implementation Patterns

Dialogue Coordinator

A modular approach to resistance / rebellion that separates concerns and enables easy testing.

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

Dialogue Manager

Core implementation pattern for handling resistance / rebellion logic with clean state management.

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