Browse/Narrative & Choice/Selfish / Selfless Choice
Narrative & Choice

Selfish / Selfless Choice

Game design pattern for selfish / selfless choice that creates meaningful player choices and engaging feedback loops.

Low complexity
4 examples
3 patterns

Overview

The selfish / selfless choice mechanic provides a framework that defines how players interact with this aspect of the game world. 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

Deck Builders

Deck Builders use this mechanic where players learn through failure to build a competitive advantage. Player choice meaningfully affects outcomes, resulting in narrative investment.

MMORPGs

MMORPGs use this mechanic where players explore the environment to optimize their strategy. The feedback loop reinforces player engagement, resulting in competitive depth.

Real-Time Strategy Games

Real-Time Strategy Games use this mechanic where players adapt to changing conditions to optimize their strategy. The system rewards both skill and knowledge, resulting in creative expression.

Martial Arts Games

Martial Arts Games use this mechanic where players respond to dynamic events to outperform other players. Player choice meaningfully affects outcomes, resulting in a deeply engaging gameplay loop.

Pros & Cons

Advantages

  • Creates satisfying haptic loops
  • Scales well from beginner to advanced play
  • Adds variety without excessive complexity

Disadvantages

  • May overwhelm solo players with too many options
  • Requires extensive QA testing to avoid edge cases
  • Can become trivial in the late game

Implementation Patterns

Quest Tracker

Core implementation pattern for handling selfish / selfless choice logic with clean state management.

class SelfishSelflessChoiceProcessor {
  currentNode: string = "greeting";
  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();
  }
}

Journal Resolver

Event-driven pattern that reacts to selfish / selfless choice changes and updates dependent systems.

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

Branching Engine

Event-driven pattern that reacts to selfish / selfless choice changes and updates dependent systems.

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