Foom – Devlog #3

Too Many Resources

The most obvious issue out of the most recent playtest is that 6 types of resources is far too many to keep track of. For each card the player wants to buy they have to calculate the differences of three different numbers. Then they add the results of each of those sums to their bitcoin number. If the card is Space or Medical and they have some of those resources they add whatever is left to the appropriate type. If the result of all that is negative the player can’t afford a card.

It’s just about possible to do all of that in your head, but it is error prone. It’s also quite a lot of work to do every time and wasn’t very fun. The resource tracks from V2 helped but weren’t nearly enough.

The first order of business was to reduce that load. That involved a few changes:

  • The Medical and Space resource types are gone. They were there as an attempt to encourage specialization in certain kinds of cards, but I’m going to try to handle that a different way.
  • When a bitcoin is acquired it becomes a type of resource of the player’s choice, but that choice is permanent.
  • There are no longer any resource conversion trades possible between the remaining three resource types.

Awkward Game Endings

Another significant issue was with the leveling up process in the game. The way it worked in V2 was that players bought the next level from one of four level stacks. The level stacks were themed and had a high cost and a large reward. The final card in each stack was “you win”, so whoever hit level 4 first won the game.

The only thing I didn’t like about this system was pretty much everything. Having four extra stacks of cards was strange when everything else in the game was in the main deck. The stacks themselves were themed poorly and two of them ended up being pretty broken. Only having three steps to victory also seemed to take away from the drama of the end of the game a bit. And it was tough to tell if a player could even buy a victory on their next turn because of the difficulty determining if anybody could buy anything that I mentioned above.

The fix here is to replace the level up cards with “Advance” cards that represent permanent upgrades to a player’s capabilities. These are in the main deck and are dealt with just like all the other cards. The other change that will hopefully help these issues is that now the rule is that a player wins when they are the first to hit 10 resources in two types. There is more work to do here, but I think these will be a step in the right direction.

Events

The approach to event cards I added in V2 worked well. It was a little awkward to have events come out in the initial draws and the events themselves need work, but I like the direction things are headed.

Attacks

Between V1 and V2 all of the Attack cards were removed from the deck.  These are added back in V3 with a twist: Attack cards now cause a permanent resource cost to the player doing the attacking (and probably to the player being attacked.) I think these will need a bunch of tuning, but I think they’ll also work better than the “steal a card” attacks of earlier versions of the game.

Here is the latest version of the game if you want to see all the changes. Now I just have to rope some people into playtesting.

Foom – Devlog #2

You may have noticed the biggest change: The game has been renamed from Hard Takeoff to Foom. In my head they were equally as good because they’re basically synonyms. Once I started saying them out loud, though it was clear that Hard Takeoff is a terrible name for a game. And Foom is tremendously fun to say, so Foom it is.

I played v1 for the first time yesterday and learned a few things:

  • Keeping track of all those resources is difficult. Each turn each player had to count up their total in six different resources. Then they did a bunch of additional calculation to figure out what they could buy.
  • When players stack up the cards they buy they eventually end up with a huge stack and the deck shrinks to almost nothing.
  • The attack cards in v1 were half-assed and kind of all identical.
  • Players were unable to form any kind of consistent strategy with the only thing that persisted between turns being the shared river. It quickly filled up with crap nobody wanted and stayed that way for the rest of the game.
  • There was no consistency between any of the cards’ cost and what you get out of them.

Preliminary balancing

I attacked that last issue first. I wrote another script to process the same card source data and produce a CSV file of the cost and production of each card. It uses some estimated values for the benefits to reduce all production to one number.

  • Bitcoin = 1.0
  • Eyes = 0.85
  • CPU/Hands = 0.75
  • Medical/Space = 0.50

I also generated a curve of what I wanted each level of production to cost. Because more expensive cards are so much more efficient in terms of player actions, I wanted them to be less efficient in terms of resources provided. The numbers I settled on were:

  • 3 cost -> 1 benefit
  • 7 cost -> 2 benefit
  • 12 cost -> 3 benefit
  • 18 cost -> 4 benefit

All of that turned into a spreadsheet:

Card count cost output target cost target output
Mesh Networks 1 5 1.5 5 1.5
Behavioral Surgery 1 8 2.25 8.25 2.2
Quantum Computing 1 8 2.25 8.25 2.2
Resurrect Ray’s Dad 1 4 1.5 5 1.25
Cure for Cancer 1 12 3 12 3
Augmented Reality Contacts 1 6 1.7 5.8 1.75

Target Cost is how much the specified output should cost according to the curves above. Target Output is how much output the specified cost should result in. Once I had this data to look at I went through and tweaked each card up or down in cost or benefit to even them all out. This eliminated a bunch of cases where there were two cards with the same cost and wildly varied benefit levels.

Other tweaks for V2

The rest of the tweaks I made based on the play test were pretty straightforward. I added a scoring track so player could keep track of their current level of each resource. Then because they didn’t need the cards anymore, the rules changed to discard each card after it was played and replenish the deck.

For the attack cards, I was biting off quite a bit already, so I just removed them from the game for now. They will almost certainly return in some form in a future version.

To help with the difficulty with forming a strategy, I gave each player a three-card hand that persisted. That way player could keep cards they wanted to save up for.

Something I felt was missing from V1 was a representation of the mood of the human population. This took the form of event cards that affect the costs and benefits of other cards and persist for several turns. There are a dozen or so events in the main deck now and whenever a player draws one of these they replace the current event and then draw another card before proceeding with their turn. Thanks to everybody on Twitter for suggestions on how to accomplish this random scheduling of events with much complexity.

I also wanted to represent more of the different strategies an AI could take more explicitly in the game. I did this by having four different upgrade sequences instead of four copies of one sequence. The four sequences help with one of four things: taking multiple actions, drawing multiple cards, effectiveness of space cards, and effectiveness of medical cards. The rule was that you could buy off any stack, but only if the top card was your level plus one.

You can find the new cards here. I’ve actually played a game with V2 as of this writing, but I think I’ll save the results of that test for the next devlog.

Hard Takeoff – Devlog #1

This weekend’s work on the game happened in three phases. First was some brainstorming about what resources might be involved and how those would be represented on cards. Then I tried to actually “play” two AIs against each other with some proto-rules and proto-cards. After that I had a much better idea what a playable game would be and codified the hand-written changes on the brainstormed cards onto the first thing that could actually be called a “game”.

Brainstorming and Bootstrapping

Something I’d forgotten about the first week or two of Calvinball is how hard it is to get a game off the ground when all you have is a vague idea.  Once you have a game that has rules and an end condition you can follow a pretty simple pattern to make it better:

  1. Trick or cajole  3-4 victims into playing with you.
  2. Play and tweak the most egregious problems as you go.
  3. Revise the game to account for the biggest of the problems you found on step 2
  4. Go to step 1

If your game is sufficiently horrible and stays that way for a long time you might run into problems with step 1, but as long as you’re willing to laugh at how far it has to go that’s not likely to be a problem.

The real problem comes with being able to do step 2. If you don’t have a game yet you are going to have a hard time learning anything from sitting down with other people. You’re just inviting some of your friends to brainstorm game ideas with you which may or may not be productive. This is the part of building a new game that I wanted to get through this weekend.

I started in Word. I wrote down half a dozen or so resources that I wanted players to manage in the game:

  • Brainpower or CPU – Controls the complexity of what players can do
  • Hands – Represents ability to take actions in the real world
  • Money – Represents financial capability in the economy

From there I came up with a quick design for cards that looked like this:

Then I printed a bunch of blank cards and started writing down singularity-inspired names that might be useful concepts in the game.

Playtest #0

The game still wasn’t playable at this point, but that didn’t stop me from trying. I went through the cards I’d scribbled on and starting writing down some rough stats on each one. It was during this process that I started to think it might be useful to have a state that represents the AI’s awareness of the world. So I started drawing little eyes on the cards and include that as one of the stats.

The resulting cards all looked something like this:

Then it was time to play.  The basic rules went something like:

  1. Three cards form a “river” that any player can purchase cards from
  2. Player draws cards equal to their total Eye rating.
  3. Player can do one of two things each turn:
    • Buy a card from their hand or the river
    • Put the card face-down in front of them. These cards can be “spent” on subsequent turns for a value of three bitcoins.
  4. To buy a card the player must have stats equal to all three (CPU, hand, and eye) requirements. If the player doesn’t meet a requirement they can spend bitcoin 1:1 to make up the difference. If they don’t have enough coin but have other stats to spare they can spend those stats 2:1 for whatever they need.
  5. At the end of each turn the player discards whatever is left in their hand.

This kinda worked. It didn’t have any kind of win condition, so the game went on until I felt like I had enough to make another revision.

Hard Takeoff V1

Here are the cards that resulted from that first sort-of playtest. Significant changes from the hand-scribbled cards include:

  • Bitcoin is no longer a “cost” on any card. It’s just used to make up the difference. I started out with a bunch of cards about renting machine time or hiring temp workers but abstracted all that away into exchanging one resource for another.
  • The AI cards come in a stack that lets you level up over time. The first player to hit level 5 wins.
  • The primary way to gain additional CPU is to level up. Most of the other ways seemed a little silly when I actually tried to play them.
  • There are three bitcoin symbols on the backs of the cards to indicate that they count as temporary bitcoin when played that way.
  • All the numbers on the resource counts turned into icons.

The PDF is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives license. Feel free to download it and give it a try.  I haven’t actually tried to play it myself yet, so I make no guarantees about fun.

Hard Takeoff – Devlog #0

About a year ago I started working on a board game (code named “Calvinball” because at first I changed the rules often during the game.) That was an interesting process to go through and one I enjoyed. For the past couple of months I’ve had a new game bouncing around in my head that I’m going to try to make real. This time around I thought I would try to document the process a bit more.

This is the first in what will hopefully become a series of posts on Hard Takeoff, which is the working title for the new game. So far all I have are some vague ideas rattling around in my head:

  • Each player in the game plays a roughly human-equivalent AI.
  • A player wins the game by being the first AI to acquire the resources required to trigger an intelligence explosion.
  • Each player has a slightly different set of requirements to trigger that explosion. Each player also starts with a slightly different set of resources and abilities.
  • The game is about accumulating resources and capabilities as quickly as possible without being so obvious that the pesky humans take notice and try to stop the player.
  • The AIs in question are self-interested, but don’t particularly hate humans. At worst they are indifferent to the goals of humans. (That means they’re more like ELOPe than Skynet.)

In addition to these thematic and gameplay goals, there are also a couple of more practical limitations I’m going to try to impose on the game:

  • The game should be easily portable. I’m going to try to build it with only cards and no other pieces.
  • Game sessions should take about an hour.
  • This should not be a worker placement game because that’s what Calvinball is and I want to try something different.

And with that I’m going to go prototype some cards.  Here goes!

Tools for generating tabletop cards

I’ve been working on a board game for about a year now. The code name is Calvinball because I make so many rule changes in the middle of a game. It’s a worker placement and resource management game. This post is about my latest attempt to improve the tools I use to print the cards for that game.

I’m pretty comfortable in Visio so I started out with a big Visio document with all the cards in it. This was annoying because I had a zillion instances of everything and if I wanted to change the way one of the icons looked I would have to go retouch all the cards. So I did some scripting in Visio to automate some of that. Unfortunately that made each element complex enough that Visio runs out of memory and starts corrupting things. It’s also not nearly procedural enough for my tastes and made me to a bunch of redundant dragging and clicking.

When I was trying to bring up a second card game (a coop wilderness exploration thing) I tried something completely different. Using Django and Python I generated the cards in HTML and then printed them from the browser. This kinda worked, but HTML is really not meant to have tight registration on its printed output so getting the front and back of cards to line up was constantly a problem. There were also strange scale and background color problems depending on what options I forgot to pick in the print dialog. So this approach wasn’t very satisfying either.

This weekend I started working on a new technique, and so far that’s going pretty well. I build card templates as SVG files in Inkscape. Then I load those with a Python script, process them a bit and dump out a card-specific SVG file. Then I use more Python to combine blocks of card files into pages. Then I turn those pages into PDFs and use PDFtk to make one big PDF with everything in it. At that point a PDF reader (I use FoxIt) can print everything in one batch.

The card templates are pretty straightforward. Here is one of them:

All the information required to render the cards is in one big list of dictionaries. When I get the rest of the cards switched over I’ll make this representation more powerful:

	cards = [
		{
			"params" : {
				"cardtitle" : "Construction Zone",
				"carddescription" : "Players take one victory point when they build a building.",
				},
			"back" : "back_goal",
			"front" : "front_goal",
		},
		{
			"params" : {
				"cardtitle" : "Research Center",
				"cost" : "RRR",
				},
			"back" : "back_goal",
			"front" : "front_goal_donate",
		},
		{
			"params" : {
				"cardtitle" : "Breeding Stock",
				"carddescription" : "Players take one victory point when they opt to not gain a colonist and instead donate it to the galactic core.",
				},
			"back" : "back_goal",
			"front" : "front_goal",
		},
		{
			"params" : {
				"cardtitle" : "One for All",
				"carddescription" : "Players take one victory point when they make a donation.",
				},
			"back" : "back_goal",
			"front" : "front_goal_allforone",
		},
	]

The code to combine the two is too long to paste inline, but the whole python script to do all of this is here. It walks through every entry in the cards list loading the front and back templates for each card. Then it tries to find elements for each entry in the “params” dictionary and replace the text of that element. You may have some difficulty getting this to run on any computer other than mind. Install lxml and svg_stack into Python, and put Inkscape and PDFtk in your path and you should be most of the way there.

One tricky bit is that the node layout for flowing text is different from a single line of text. This function finds the node with the text in it in each case:

def FindNode( root, name ):
	el = root.findall( ".//n:text[@id='" + name + "']/n:tspan", xmlNamespaces)
	if( el ) :
		return el[0]

	el = root.findall( ".//n:flowRoot[@id='" + name + "']/n:flowPara", xmlNamespaces )
	if( el ):
		return el[0]

	return None

It’s also worth noting that flowRoot doesn’t seem to work anywhere but Inkscape. Apparently it was in the final spec for some version of SVG that nobody supports. I use it for descriptions on some cards where I need word wrapping.

The other kind of parameterization that’s currently supported is recoloring or hiding the resource icons to match the cost string on the card definition. That just finds paths under a group with a special ID and sets their style to something specific to that resource type:

resourceStyles = {
	"F" : "fill: #16CD22; stroke: #000000; stroke-width: 0.5;",
	"E" : "fill: #D5FF2D; stroke: #000000; stroke-width: 0.5;",
	"M" : "fill: #404040; stroke: #000000; stroke-width: 0.5;",
	"R" : "fill: #FF69F7; stroke: #000000; stroke-width: 0.5;",
	"C" : "fill: #0000F7; stroke: #000000; stroke-width: 0.5;",
}
hiddenResourceStyle = "opacity:0"

def SubstCost( root, cost ):
	for n in range( 0, 15 ):
		style = hiddenResourceStyle
		if( n < len( cost ) ):
			style = resourceStyles[ cost[n] ]

		el = root.findall( ".//n:g[@id='cost" + str(n) + "']/n:path", xmlNamespaces )
		for path in el:
			path.set( "style", style )

The card SVG files are all dumped into a directory that contains all the script's output. For my game I write card back and fronts for every card. Most of the cards in my game are double-sided so having a shared back between multiple cards is actually kinda rare. You might be able to do something less spammy. Here are all the files generated by my initial test case:

From there the script builds "pages" where a page is a list of svg filenames. With standard 2.5" x 3.5" cards you can fit 8 cards on an 8.5" x 11.00" page, so every 8 cards forms a page. The pages alternate between fronts and backs with the fronts shown top to bottom and the backs shown bottom to top (to match the duplex feature on my printer.) If there aren't an even multiple of 8 cards blank cards are added to the pages so that each page is exactly 7" x 10". See lines 140-170 in the script for the code that does this pagination.

Using the lists of SVG filenames the script uses a Python module called svg_stack to combine them into bigger SVG files. svg_stack has horizontal and vertical box layouts, but it's pretty easy to combine those two to get a 2x4 grid to fit 8 cards per page. those cards are then written out to an SVG file that looks like this:

From there it's a quick trip through the Inkscape command line to converting that 7" x 10" SVG into a 7" x 10" PDF:
inkscape -f output\page0.svg -A output\page0.pdf

And once I have a bunch of those files I can cat them all together with pdftk:
pdftk output\*.pdf cat output output\allcards.pdf

Then you can print the whole thing in a PDF reader. In FoxIt I have to make sure to turn off scaling and auto-center on an 8.5"x11.0" page when I print:

Hopefully that brain dump is useful to somebody! I sure wish I'd had something like this to read yesterday morning.