Gamefic

Adventure Games and Interactive Fiction

Getting Started

This section covers installing Gamefic and writing your first game.

Prerequisites

Gamefic authors should have a basic understanding of the Ruby programming language. Ruby basics are beyond the scope of this document, but here are some resources for beginners:

System Requirements

Gamefic requires Ruby 2.2.2 or higher. It works on Windows, Mac, and Linux.

Many features of the Gamefic SDK also require Node.js, but this section covers basics that should work with Ruby alone.

Install the SDK

Run the following command to install the Gamefic SDK:

$ gem install gamefic-sdk

Create a Project

Use the gamefic init command to create a new project:

$ gamefic init mygame
$ cd mygame

The Project Folder

After your project is initialized, the contents of the folder should include the following:

/mygame
  /lib
    /mygame
      plot.rb
      subplot.rb
    mygame.rb
  /spec
  Gemfile
  main.rb
  Rakefile
  README.md

main.rb

This is the first script that will run when you start your game. Your game code can be split into as many files as you want, but main.rb always runs first.

lib

The lib directory contains the ruby code that creates and manages your game. The project starts with three files:

  • mygame.rb - The entry point for your game code.
  • mygame/plot.rb - The main plot of your game. In this section, most of the changes we make will belong here.
  • mygame/subplot.rb - The base class for subplots. How to use this class will be covered later.

spec

The spec directory contains RSpec configuration and barebones unit tests for RSpec and RSpec::Opal. See the section about unit tests for more information.

Testing the Project

It’s already possible to test the project from the command line. Make sure you’re in the project’s directory and run the following:

$ rake ruby:run

Hello, world!

>

The game will accept commands, but since we haven’t added anything to the story yet, there’s not much to do except quit.

The Introduction

Open plot.rb in a text editor. Right now it should have just a few lines of code:

module Mygame
  class Plot < Gamefic::Plot
    UUID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

    include Gamefic::Standard

    seed do
      # Make entities here
    end

    script do
      introduction do |actor|
        actor.tell "Hello, world!"
      end
    end
  end
end

The UUID is a unique ID for your game. It’s useful for submitting your game to collections that require them, such as the Interactive Fiction Database. It’s safe to delete if you don’t think you need it.

The require calls import everything you need to get started. Only the gamefic require is mandatory.

The gamefic-standard library bootstraps many features that are commonly useful in adventure games. It’s analogous to Inform’s Standard Rules library.

script indicates a block of code that should run within the context of the game.

The introduction method defines a block of code to be executed when the game begins. The actor parameter is the player’s character.

The actor.tell call sends a formatted text message to the user. We can also use the introduction to initialize various player attributes, such as the room where they start the game. We’ll explore those features as we start to add more stuff to the game world.

Adding a Room

Most physical elements in a plot–the player’s character, the rooms, weapons, animals, furniture, etc.–are represented by entities. The standard library provides a base entity called a Thing. All other entities are subclasses of Thing.

Scripts use the make method to add entities to the plot. Here we’ll modify plot.rb to add a room and put the player in it:

module Mygame
  class Plot < Gamefic::Plot
    UUID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

    include Gamefic::Standard

    seed do
      @forest = make Room, name: 'forest', description: 'A thick green forest.'
    end

    script do
      introduction do |actor|
        actor.parent = @forest
        actor.tell "You're in a forest."
      end
    end
  end
end

The first parameter to the make method is the entity type. There are lots of other attributes you can set with optional keyword arguments. The exact attributes can vary based on the entity’s type, but name and description are universal.

The parent attribute puts one entity inside another. In this case, the actor’s parent becomes the forest. (You’ll probably want a character’s parent to be a room in most cases, but any entity’s parent can be any other entity, with only a few limitations.)

Now that we have a location, there’s a little more we can do in our next test:

$ rake ruby:run

You're in a forest.

> look around

A thick green forest.

Adding More Rooms

We can start building the map by making more rooms and connecting them. Modify plot.rb again:

module Mygame
  class Plot < Gamefic::Plot
    UUID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

    include Gamefic::Standard

    seed do
      @forest = make Room, name: 'forest', description: 'A thick green forest.'
      @path = make Room, name: 'path', description: 'A cobblestone path.'
      @forest.connect @path, direction: 'north'
    end

    script do
        introduction do |actor|
          actor.parent = @forest
          actor.tell "You're in a forest."
        end
      end
  end
end

The connect method creates a portal between two rooms with an optional direction. In this example, the path will be north of the forest.

Run the test again:

$ rake ruby:run

You're in a forest.

> look around

Forest

A thick green forest.

There is an exit north.

> go north

You go north.

Path

A cobblestone path.

There is an exit south.

> go south

You go south.

Forest

A thick green forest.

There is an exit north.

The connect method understands ten directions: north, south, west, east, northwest, southwest, northeast, southeast, up, and down. As the above example demonstrates, it automatically creates a portal that leads back in the opposite direction.

Other Types of Things

Next we’ll add a couple more things to the world.

# Add these lines to the bottom of the seed block

@bush = make Fixture, name: 'bush', description: "It's covered in tiny young buds waiting to bloom.", parent: @forest
@water_can = make Item, name: 'water can', description: 'A can of water.', parent: @path

This example includes two new types of entities: a Fixture and an Item. The main difference between them is portability. Players can typically pick up and carry items, while fixtures are immobile.

Run the game again and try interacting with the new entities.

$ rake ruby:run

You're in a forest.

> look around

Forest

A thick green forest.

You see a bush.

There is an exit north.

> look at bush

It's covered in tiny young buds waiting to bloom.

> take bush

You can't take the bush.

> go north

You go north.

Path

A cobblestone path.

You see a water can.

There is an exit south.

> take water can

You take the water can.

> look can

A can of water.

> go north

You don't see any exit "north" from here.

> go south

You go south.

Forest

A thick green forest.

You see a bush.

There is an exit north.

> drop can

You drop the water can.

> look around

Forest

A thick green forest.

You see a bush and a water can.

There is an exit north.

Actions

As demonstrated in the above examples, the standard library provides a lot of built-in commands, such as go, look, take, and drop. Commands are represented by subclasses of the Action class. We can add our own commands with the respond method.

The simplest form of respond accepts a verb and a block:

# Add this code to the bottom of the script block

respond :think do |actor|
  actor.tell "You ponder your predicament."
end

The :think symbol tells the game to trigger this action in response to the THINK command. Run the game to test it:

$ rake ruby:run

You're in a forest.

> think

You ponder your predicament.

Interacting with Things

Actions can be configured to interact with something in the game by adding more arguments to respond:

respond :water, Thing do |actor, thing|
  actor.tell "#{The thing} doesn't need any water."
end

This creates a WATER command that requires a direct object. The game will look for the direct object among the things in the player’s direct vicinity. Run the game again:

$ rake ruby:run

You're in a forest.

> look around

Forest

A thick green forest.

You see a bush.

There is an exit north.

> water bush

The bush doesn't need any water.

> water tree

I recognize 'water' as a verb but could not understand the rest of your sentence.

Watering the bush triggers the correct action. Watering the tree results in an error message because the game can’t find anything called a tree.

Conclusions

Characters have a conclude method that ends the game.

This example ends the game with a DISAPPEAR command:

respond :disappear do |actor|
  actor.tell "You disappear in a puff of smoke."
  actor.conclude :default_conclusion
end

The :default_conclusion is a scene that simply ends the game. Authors can create their own Conclusion scenes with more functionality, such as reporting achievements or tallying a final score. Refer to the Scenes section for more information about conclusions and other scene types.

Here is a more complicated version of the WATER command:

respond :water, Thing do |actor, thing|
  if @water_can.parent == actor
    if thing == @bush
      actor.tell "You water the bush."
      actor.conclude :default_conclusion
    else
      actor.tell "#{The thing} doesn't need any water."
    end
  else
    actor.tell "You don't have any water."
  end
end

In this version, the WATER command can only be used if the player has the water can. Nothing but the bush needs water. The game ends when the player waters the bush.

Next: Building Your Game World