Gamefic

Adventure Games and Interactive Fiction

Subplots

Subplots are discrete narratives that happen inside a larger plot. They have most of the same features of a plot, with the additional features of encapsulation and disposability. The subplot maintains its own entities, actions, and scenes that are accessible to the plot but contained in a separate namespace. When the subplot concludes, it automatically cleans up its own data. Subplots can be started and concluded during runtime at will.

A Simple Example

In this example, the player enters the MagicWand subplot with the CONJURE command. The subplot concludes when the player waves the wand, and the wand is automatically destroyed.

require 'gamefic-standard'

class MagicWand < Mygame::Subplot
  script do
    @wand = make Item, name: 'magic wand'
    
    introduction do |actor|
      actor.tell "You conjure a magic wand. WAVE it to make something happen."
      @wand.parent = actor
    end

    respond :wave, @wand do |actor, wand|
      actor.tell "The wand disappears in a puff of smoke."
      conclude
    end
  end
end

Mygame::Plot.script do
  introduction do |actor|
    actor.tell "Use the CONJURE command to conjure a magic wand."
  end

  respond :conjure do |actor|
    branch MagicWand, introduce: actor
  end
end

Extending Gamefic::Subplot

Define subplots by subclassing Gamefic::Subplot. The subplot’s script method takes a block that will be executed when the subplot is instantiated, same as how Gamefic::Plot.script defines blocks for Gamefic::Plot. Much like a regular plot, the subplot can have its own introduction, entities, actions, and scenes.

Accessing Plot Entities from Subplots

Subplots do not have direct access to the plot. If you want to access a plot entity, the easiest way is to pass it as a config option to branch. In this example, we pass a random room to the subplot:

Mygame::Plot.script do
  respond :transport do |actor|
    branch Hyperspace, introduce: actor, room: entities.that_are(Room).sample
  end
end

class Hyperspace < Mygame::Subplot
  script do
    introduction do |actor|
      actor.parent = config[:room]
      actor.tell "You magically transport to #{the room}."
      conclude
    end
  end
end

If you want to make a permanent entity from a subplot, you can use the persist method. Entities created with persist will continue to exist after the subplot concludes.

Starting a Subplot

The branch method starts a subplot. You can indicate an actor (usually the player’s character) to add to the subplot with the introduce parameter:

respond :jump do |actor|
  branch Hyperspace, introduce: actor
end

Ending a Subplot

Use the conclude method from inside the subplot to end it. This example will conclude the subplot with the command ABRACADABRA.

class Abracadabra < Mygame::Subplot
  on_start do
    introduction do |actor|
      actor.tell "Say the magic word."
    end

    respond :abracadabra do |actor|
      actor.tell "Hocus pocus!"
      conclude
    end
  end
end

Scenes in Subplots

In addition to its own entities and actions, subplots can have their own scenes. Actors in the subplot can cue them like any other scene.

class AskForConclusion < Mygame::Subplot
  script do
    introduction do |actor|
      actor.tell "Enter FINISH to end the subplot."
    end

    respond :finish do |actor|
      actor.tell "Are you sure?"
      actor.cue :are_you_sure
    end

    yes_or_no :are_you_sure do |actor, props|
      if props.yes?
        actor.tell "Okay, it's over."
        conclude
      else
        actor.tell "It's still running."
      end
    end
  end
end

Rooms in Subplots

A subplot can make its own rooms, just like it can make any other entity. Keep in mind, however, that the subplot will destroy its rooms upon conclusion. Any plot entities, including the player’s character, will be ejected from the subplot’s rooms and left without a parent unless you explicitly set a new one.

Uses for Subplots

  • Organizing scenes into logical groups
  • Adding mini-games
  • Procedurally generating quests
  • Temporarily overriding actions
  • Adding “private” areas to multiplayer games
  • Encapsulating data to avoid naming conflicts

Next: Extending Gamefic with libraries