-
Notifications
You must be signed in to change notification settings - Fork 67
Part 1: Zero to Game
Squib is all about being able to change your mind quickly. Change data, change layout, change artwork, change text. But where do we start? What do we work on first?
The key to prototyping tabletop games is playtesting. At the table. With people. And printed components. That means that we need to get our idea out of our brains and onto pieces of paper as fast as possible. But! We also want to get the second (and third and fourth and fifth...) version of our game back to the playtesting table quickly, too. If we work with Squib from day one, our ability to react to feedback will be much smoother once we've laid the groundwork.
In this series of guides, we'll introduce you to Squib's key features. We'll take a more circuitous route than normal so we can pick apart what Squib is actually doing so that we can leverage its features.
The ordinary installation is just gem install squib
. See the Windows, OSX, and Linux pages for installation nuances and idiosyncracies for each operating system.
This guide also assumes you've got some basic Ruby experience, and you've got your tools set up (i.e. text editor, command line, image preview, etc). See [Part 0: Ruby Basics](Part 0: Ruby Basics) to see my recommendations.
Let's start with an idea for a game: Familiar Fights. Let's say we want to have players fight each other based on collecting cards that represent their familiars, each with different abilities. We'll have two factions: drones and humans. Each card will have some artwork in it, and some text describing their powers.
First thing: the title. It stnks, I know. It's gonna change. So instead of naming the directory after our game and getting married to our bad idea, let's give our game a code name. I like to use animal names, so let's go with Arctic Lemming.
$ squib new arctic-lemming
$ cd arctic-lemming
$ ls
ABOUT.md Gemfile PNP NOTES.md Rakefile _output config.yml deck.rb layout.yml
Go ahead and put "Familiar Fights" in the IDEAS.md file. [Why all the .md files?](Why Markdown)
If you're using Git or other version control, now's a good time to commit. See [Squib+Git](Squib + Git).
If you want to know what all of those files we just created are, check out squib new explained.
From a prototyping standpoint, we really have two directions we can work from:
- Laying out an example card
- Working on the deck data
There's no wrong direction here - we'll need to do both to get our idea onto the table. Go where your inspiration guides you. For this example, let's say I've put together ideas for four cards. Here's the data:
name | class | power |
---|---|---|
Ninja | human | Use the power of another player |
Pirate | human | Steal 1 card from another player |
Zombie | drone | Take a card from the discard pile |
Robot | drone | Draw two cards |
If you're a spreadsheet person, go ahead and put this into Excel (in the above format). Or, if you want to be plaintext-friendly, put it into a comma-separated format (CSV). Like this:
name,faction,power
Ninja,human,"Use the power of another player"
Pirate,human,"Steal 1 card from another player"
Zombie,drone,"Take a card from the discard pile"
Robot,drone,"Draw two cards"
Ok let's get into some code now. Let's first do a quick dissection of a "Hello, World" code snippet:
require 'squib'
Squib::Deck.new cards: 1 do
background color: 'pink'
rect
text str: 'Draw two cards.'
save_png
end
- Line 1: this code will bring in the Squib library for us to use. Keep this at the top.
- Line 2: By convention, we put a blank line between our
require
statements and the rest of our code - Line 3: Define a new deck of cards. Just 1 card for now
- Line 4: Set the background to pink. Colors can be in various notations, but Squib can also take in common color names
- Line 5: Draw a rectangle around the edge of the deck. Note that this has no arguments (Squib has TONS of options, and they all have sane defaults)
- Line 6: Put some text in the corner of the card.
- Line 7: Save our card out to a png file. This will be saved to
_output/card_00.png
Now let's incrementally convert the above snippet into just one of our cards. Let's just focus on one card for now, then we'll hook it up to our CSV and apply that to all of our cards.
You may have seen in some examples that we can just put in x-y coordinates into our commands. That's great for customizing our work later, but we want to get this to the table quickly. Instead, let's make use of Squib's built-in layouts feature. Layouts are a way of specifying some of your arguments in one place - a layout file. The squib new
command created our own layout.yml
file, but we can also use Squib's built-in layout file. Since we just need a title, artwork, and description, we can just use economy.yml
(inspired by a popular deck builder that currently has dominion over the genre). Here's how it that looks:
require 'squib'
Squib::Deck.new cards: 1, layout: 'economy.yml' do
background color: 'white'
rect layout: 'cut' # cut line as defined by TheGameCrafter
rect layout: 'safe' # safe zone as defined by TheGameCrafter
text str: 'Robot', layout: 'title'
text str: 'Draw two cards.', layout: 'description'
save_png
end
A few things to note:
- Black-and-white. We're now in black-and-white so that we can be printer-friendly.
-
Safe and Cut. We added two rectangles for guides based on the poker card template from TheGameCrafter.com. This is important to do now and not later. In most print-on-demand templates, we have a 1/8-inch border that is larger than what is to be used, and will be cut down (called a bleed). Rather than have to change all our coordinates later, let's build that right into our prototype. Squib can trim around these bleeds for things like
showcase
,hand
,save_sheet
, andsave_pdf
. - Title. We added a title based on our data.
-
layout: 'foo'. Each command references a "layout" rule. These can be seen in our layout file, which is a built-in layout called
economy.yml
(see ours on GitHub). Later on, we can define our own layout rules in our own file, but for now we just want to get our work done as fast as possible and make use of the stock layout.
Ok now we've got a basic card. But we only have one. The real power of Squib is the ability to customize things per card. So if we, say, want to have two different titles on two different cards, our text
call will look like this:
text str: ['Zombie', 'Robot'], layout: 'title'
When Squib gets this, it will:
- See that the
str:
option has an array, and put'Zombie'
on the first card and'Robot'
on the second. - See that the
layout:
option is NOT an array - so it will use the same one for every card.
So technically, these two lines are equivalent:
text str: ['Zombie', 'Robot'], layout: 'title'
text str: ['Zombie', 'Robot'], layout: ['title','title']
Ok back to the game. We COULD just put our data into literal arrays. But that's considered bad programming practice (called hardcoding, where you put data directly into your code). Instead, let's make use of our CSV data file.
What the csv
command does here is read in our file and create a hash of arrays. Each array is a column in the table, and the header to the colum is the key to the hash. To see this in action, check it out on Ruby's interactive shell (irb
):
$ irb
2.1.2 :001 > require 'squib'
=> true
2.1.2 :002 > Squib.csv file: 'data.csv'
=> {"name"=>["Ninja", "Pirate", "Zombie", "Robot"], "class"=>["human", "human", "drone", "drone"], "power"=>["Use the power of another player", "Steal 1 card from another player", "Take a card from the discard pile", "Draw two cards"]}
So, we COULD do this:
require 'squib'
Squib::Deck.new cards: 4, layout: 'economy.yml' do
data = csv file: 'data.csv'
#rest of our code
end
BUT! What if we change the number of total cards in the deck? We won't always have 4 cards (i.e. the number 4 is hardcoded). Instead, let's read in the data outside of our Squib::Deck.new
and then create the deck size based on that:
require 'squib'
data = Squib.csv file: 'data.csv'
Squib::Deck.new cards: data['name'].size, layout: 'economy.yml' do
#rest of our code
end
So now we've got our data, let's replace all of our other hardcoded data from before with their corresponding arrays:
require 'squib'
data = Squib.csv file: 'data.csv'
Squib::Deck.new cards: data['name'].size, layout: 'economy.yml' do
background color: 'white'
rect layout: 'cut' # cut line as defined by TheGameCrafter
rect layout: 'safe' # safe zone as defined by TheGameCrafter
text str: data['name'], layout: 'title'
text str: data['power'], layout: 'description'
save_png
end
Awesome! Now we've got our all of our cards prototyped out. Let's add two more calls before we bring this to the table:
-
save_pdf
that stitches our images out to pdf - A version number, based on today's date
require 'squib'
data = Squib.csv file: 'data.csv'
Squib::Deck.new cards: data['name'].size, layout: 'economy.yml' do
background color: 'white'
rect layout: 'cut' # cut line as defined by TheGameCrafter
rect layout: 'safe' # safe zone as defined by TheGameCrafter
text str: data['name'], layout: 'title'
text str: data['power'], layout: 'description'
text str: Time.now, layout: 'credits'
save_png
save_pdf trim: 37.5
end
The file _output/output.pdf
gets created now. Note that we don't want to print out the bleed area, as that is for the printing process, so we add a 1/8-inch trim (Squib defaults to 300ppi, so 300/8=37.5). The save_pdf
defaults to 8.5x11 piece of landscape paper, and arranges the cards in rows - ready for you to print out and play!
If you're working with version control, I recommend committing multiple times throughout this process. At this stage, I recommend creating a tag when you are ready to print something out so you know what version precisely you printed out.
Squib's job is done, for at least this prototype anyway. Now let's print this sheet out and make some cards!
My recommended approach is to get the following:
- A pack of standard sized sleeves, 2.5"x3.5"
- Some cardstock to give the cards some spring
- A paper trimmer, rotary cutter, knife+steel ruler - some way to cut your cards quickly.
Print your cards out on regular office paper. Cut them along the trim lines. Also, cut your cardstock (maybe a tad smaller than 2.5x3.5) and sleeve them. I will often color-code my cardstock backs in prototypes so I can easily tell them apart. Put the cards into the sleeves. You've got your deck!
Now the most important part: play it. When you think of a rule change or card clarification, just pull the paper out of the sleeve and write on the card. These card print-outs are short-lived anyway.
When you playtest, take copious notes. If you want, you can keep those notes in the PLAYTESTING.md file.
We've got a long way to go on our game. We need artwork, iconography, more data, and more cards. We have a lot of directions we could go from here, so in our next guide we'll start looking at a variety of strategies. We'll also look at ways we can keep our code clean and simple so that we're not afraid to change things later on.
Install: Windows OSX Linux Cygwin
Getting Started
Important
Advanced Squibbing
- The Mighty text Method
- Layouts
- Manipulating PNGs
- Manipulating SVGs
- Vector back end
- Rendering both BW and Color
- Colors
- Configuration Options
Real Project Histories
Squiblets
- Category specific template text
- Combining Multiple Columns
- One Icon Per Location
- One Location, Multiple Icons
- Google Sheets
- Rake Rendering Modes
- Autoscale Fonts
- Marketing Materials
- Autobuild with Guardfiles
- Wireframing with an SVG Editor
- Front to Back Printing
- Versioning Practices
- Icon Library: FontAwesome
- Icon Library: GameIcons
- Combining Multiple Columns
- Combine Multiple CSV Files
- Switch card background or invert theme
Tools
Contributing