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