Gamefic

Adventure Games and Interactive Fiction

Coding Guidelines

New Gamefic projects are structured to make building stories and adding features as convenient as possible. The guidelines listed here are intended as suggestions to help authors organize their code, manage complexity, and get the most use out of Gamefic’s capabilities.

Using the Autoloader

Projects include the gamefic-autoload gem to enable Zeitwerk code loading. (This feature might sound familiar if you’ve ever worked with Ruby on Rails.) Authors can create classes and modules in the lib directory that are automatically loaded according to Zeitwerk’s naming conventions without needing to require them.

# lib/mygame/chapter1.rb
module Mygame
  class Chapter1 < Chapter
  end
end

# lib/mygame/plot.rb
module Mygame
  class Plot < Gamefic::Plot
    append Chapter1 # The Chapter1 code gets loaded automatically without a `require`
  end
end

The Shared Module

It’s common for plots, subplots, and chapters to need access to the same modules. The Shared module provides a simple place to include them in all three.

# lib/mygame/shared.rb
module Mygame
  module Shared
    extend Gamefic::Scriptable

    include Gamefic::Standard # Plots, subplots, and chapters will include Standard
  end
end

Adding Extensions

Gamefic extensions are an easy way to add common features to your game. The gamefic-standard library is the most obvious example of an extension. The rules for enabling and extension can vary, but they usually involve three steps:

  1. Add the extension’s gem to your Gemfile (and run bundle install)
  2. Require the gem from your project’s main module (e.g., require 'gamefic-standard')
  3. Include its namespace in your Shared module (e.g., include Gamefic::Standard)

Refer to the extension’s README for more information.

Modules, Chapters, and Subplots

As games grow in size and complexity, putting all of your entities, responses, and hooks inside the Plot can get cumbersome. Gamefic provides several strategies for separating your game’s features into smaller, more manageable components. Among the options are scriptable modules, chapters, and subplots.

Modules: When you include a scriptable module in your narratives, all of its script components (entities, responses, etc.) get imported. Keep in mind that the module’s features will also be appended just like any other mixin, so any methods and constants defined in it will also be available in the narrative.

Chapters: Unlike including a scriptable module, appending a chapter does not import its methods and constants into the narrative. This can be useful if you want to encapsulate all the features of a narrative element in their own namespace. Note that appended chapters get initialized along with the plot and will continue running until you explicitly conclude them.

Subplots: If you want to create and discard narrative elements dynamically, consider using subplots. A subplot doesn’t start until you branch it from a plot. It also requires players to be assigned to it with the introduce parameter. If a subplot does not have any participating players, it will conclude automatically.