Ludum Dare 30 Post-Mortem

What went right:

I felt like the scope was perfect for the limited amount of time I had this weekend. This was mostly luck, but I also knew when to quit tweaking and didn’t regret it.

The match-3 and block-dropping algorithms fell into place like magic. To be fair, I’d given it some forethought–I did a quick Unity refresher on Wednesday where I attempted to build the line-clearing mechanic of Tetris with help from this tutorial. However, that’s a much simpler algorithm and I didn’t have an exact plan. It was a leap of faith that paid off early, leaving all of Sunday for polish. (I’d probably remiss if I didn’t mention that the match-3 concept was inspired by the time I spent in SeishunCon‘s digital gaming room this year.)

I’m happy with the art. I didn’t stretch myself stylistically, and it’s not as crisp and detailed as what I’d hoped, but overall it feels pretty slick if you don’t look too closely. I love posting those screenshots because it feels like a “real” game (well, at least to me).

As in the past, adding a GVerb track covers over a multitude of recording sins. I’m going to say this a lot in this post, but this feels like cheating.

Driving 40 minutes back from the Knoxville Game Design meetup is always a good way to start thinking about design and algorithms.

What could have gone better:

I basically shoehorned a puzzle game into the theme. This was premeditated, mainly because I was itching to dip my toe into the genre. It restrained the scope by removing the need for level design, which helped. However, it also felt like cheating the system to start thinking about a game genre so early (especially since I feel like my LD29 entry was a much stronger “Connected Worlds” concept).

Overall gameplay was good, but not great. I’m happy with this in one sense–I didn’t make a ton of explicit design decisions, so I won the “go with whatever’s easiest” lottery. Still, I feel like the “flip or drop” choice is missing something. I enjoy the game, but I restart as soon as I clear out all of the obvious flip combos. Once I have to drop blocks, it’s like I’ve failed. I feel like a “flip or shift” mechanic would have been better.

What went wrong:

Because I wasn’t livestreaming, I tried to do a status update video on Friday night. OpenBroadcaster doesn’t work smoothly on my laptop. I wasted about an hour or so tinkering with OBS on a night I ended up staying up until 4am.

I don’t understand music. Originally, I picked the current chord progression as a base, then played some random notes over it on a second track. Seemed clever on Saturday, but on Sunday I realized it was too chaotic. After talking to Mike at the post-LD meetup, I think I need to study up on some music theory basics rather than hoping a clever experiment will pay off. (I feel like I’m reusing the same chord progressions and I always use a similar rhythm/picking pattern.)

Overall, I don’t feel like I stretched myself like I should have. I stick to the same style musically and artistically because I don’t have a lot of range. I stick to Unity because it’s all I know. To be honest, I’ve had a few good ratings in past LDs, so I avoid the unfamiliar because I want to keep that up. Next LD where I have the time, I need to set a few goals–for example, use Inkscape instead of GIMP, or use a digital tool like PxTone or Bfxr.

Prototyping a card game with nanDECK, part 3

In part 1, I covered why you might want to use nanDECK in prototyping a card game, and in part 2, I covered how to build a basic template.

Now, let’s look at some of the directives I used to build my Encounter deck template. In this case, I’m still using the Title, Description, and Count fields, but I’ve also added Life and Cards fields:

nanDECK Spreadsheet

Again, note that some cards intentionally leave these columns blank. I wanted to add some immediately resolved effects that should be distinguished from “standard” Encounters that remain in play until handled.

Using variables

In the simple example, we created a variable called [all] to save us from having to redefine our range in every directive. This was really a bit of lampshading on my part, because the syntax for “all cards in this spreadsheet” isn’t really clear. There are other reasons you might want to use them, though.

Let’s say we have a lot of text blocks on our card, that all stretch the entire length of the card. Rather than hard-coding the width value in every directive, we can reuse it as a variable:

[text_width]=4.58
font="arial",16,"",#000000
text=[all],[Title],0.25,0.25,[text_width],1,"left","top"

Note that we could define our margins the same way if we wanted. In this case, it’s just easier to type out “0.25″ than to write “[marginx]” every time and (these being prototypes) I don’t envision I’ll be tweaking layout much.

Conditional blocks

As I said earlier, I want to have two types of Encounter cards–”standard” Encounters with numeric stats, and Encounter cards that trigger effects when flipped. While I could separate these into different spreadsheets or create ranges in my script, that’s a huge hassle–I’m using nanDECK because I don’t want to have to micromanage my spreadsheets.

In this case, I want to use a conditional:

nanDECK conditionals

Let’s look at this conditional step-by-step. The first part starts out relatively simple–almost like what I covered in part 2:

[all]=1-{(Title)}
linkmulti=Count
link=fog-encounters-update20140719.csv
cardsize=5.08,8.89
page=21.59,27.94,LANDSCAPE,HVEO,#FFFFFF,[all]
[text_width]=4.58
font="arial",16,"",#000000
text=[all],[Title],0.25,0.25,[text_width],1,"left","top"
font="arial",12,"",#000000

We end by changing the font, but we don’t follow it up with a “text” directive that prints any text. Note that “font” and “text” directives don’t have to be back-to-back. nanDECK will remember the last “font” you specified.

Here’s where the logic happens. We want to check if “Cards” (one of the two stats that our “standard” Encounters will have) is empty. If it is, we just want to show the description. If it isn’t, we want to show all our numeric stats ahead of the description.

We start our block as follows, checking to see whether “Cards” is not a blank string of text.

if=[Cards]<>""

nanDECK’s “if=” seems a bit bizarre if you’re used to writing code, but remember, everything is a directive.

To explain the rest of this jumble of punctuation, note that Cards is encased in [brackets] to denote it’s a column in our spreadsheet, the “<>” operator means “is not equal to”, and the empty quotes (“”) refer to an empty string of text.

(Note that I’m not testing all of my stat columns here, but I could if my requirements were different. If you use one stat, you’re going to use both of them. )

What comes next is indented for readability, but this isn’t nanDECK’s requirement. Once it encounters that “if” directive, everything that follows will be executed only if it’s true. nanDECK is looking for an “else” or “elseif” directive.

Here we have more numbers, but if you remember part 2, you should be able to decipher this.

text=[all],"Cards:",0.25,1.25,2,1,"left","top"
text=[all],"Life:",0.25,2.25,2,1,"left","top"

We start out by creating labels for our numeric values, setting them along the left margin (0.25cm left) and 1cm apart from each other vertically (at 1.25cm and 2.25cm). Because the labels are small, we allow 2cm width.

 text=[all],[Cards],2.25,1.25,2,1,"left","top"
 text=[all],[Life],2.25,2.25,2,1,"left","top"

Next, we fill in the values. Because we’ve already reserved 2cm of width from the label, we set them at 2.25cm left, giving ourselves a bit of a margin. Since they’re on the same lines as the labels, our vertical values are the same. We’ll also allow 2cm here because numeric values will be short.

htmltext=[all],[Effect],0.25,3,[text_width],5.39

Finally, we display the Description as HTML just below the last numeric stat, and have it fill the rest of the space on the card.

Now, let’s handle what happens if we don’t have a value for [Cards]:

else
    htmltext=[all],[Effect],0.25,1,[text_width],7.39
endif

“Else” tells nanDECK that we want to switch, and handle the opposite case–what should happen if Cards does not have a value. (Note that you don’t have to have an “else” directive for every “if”.) In this case, we want to display the Description starting at the top of the card.

We finish off the block with an “endif” directive, which simply tells nanDECK that we’ve ended the “if” block.

This is, admittedly, a simple example–you can, for example, nest “if” blocks inside of each other, or use “elseif” directives to define multiple conditions.

This should be enough to get you started if you’re interested in using nanDECK. Remember, if you want to dive in to nanDECK, the manual will be your most valuable asset. It’s not always perfect, but it does cover every directive.

 

Prototyping a card game with nanDECK, part 2

In part 1, I covered why you might want to use nanDECK in prototyping a card game. Now, let’s get into the nuts and bolts of building a template.

A simple example

In my last post, I mentioned that Player Actions were simple title-and-description cards. In fact, that’s all that’s really in my spreadsheet: Title, Description, and Count (for the number of copies of each card in the deck). Note that I’ve also got a calculated field in my spreadsheet showing the total number of cards in the deck–in this case, 86.

Player Actions CSV

“Description” belies some complexity: I want to be able to include line breaks and, if possible, formatted text.

Of course, there’s the game design equivalent of a “code smell” here–if I’m regularly using the same mechanics over and over, then I probably need to introduce some keywords. And if I’m introducing multiple keywords, then maybe that needs to be its own column in my CSV, rather than a bold term that appears in the Description.

For example, my Action deck has a few cards that players can keep for semi-permanent effects, so why write out “players can keep this, can only have one copy, etc. etc.” on every card? Applying the label “Item” would be far simpler, and then refer the player to the rulebook.

Once we’ve got a spreadsheet set up in Excel or OpenOffice, we need it in a text format that nanDECK can read. To do this, go to Save As… and select either “Comma separated values” or “CSV.” Don’t worry too much about options, as the defaults will work for most scenarios–just make sure that the delimiter is CSV.

Save as CSV

Now, let’s take a look at the configuration I’m using for this deck. Note that every directive from this section is explained in the nanDECK manual. If you want to follow along, you can download the .nde file here (you’ll need to provide your own CSV file with Title, Description, and Count columns.)

nanDECK simple example

Building a template in nanDECK is somewhere between creating a configuration file, programming, and writing HTML. Every line starts with a directive (the text on the left side of the equals sign) that is passed a number of values (the list, separated by commas, on the right side of the equals sign).

Order is sometimes important, and you can create conditional blocks, but there’s typically not the sort of “flow control” you think of when programming. (Again, if your layout is getting that complex, you’re probably out of the prototyping stage anyway.)

First, we’ll set up a variable called [all], which will represent all cards in the set. The line below might be best read as “[all] represents a set of cards starting at 1 and ending with the last row that has a Title value.” (I’ve never found a reason not to do this. Multiple card formats probably should be stored in separate layouts and spreadsheets.)

[all]=1-{(Title)}

Next, we tell nanDECK that the “Count” field in our spreadsheet represents the number of copies of each card:

linkmulti=Count

We also tell nanDECK where to find that spreadsheet. In this case, we assume that we’re storing the CSV in the same folder as our nanDECK NDE file:

link=fog-actions-update20140719.csv

Next, we want to define the size of each card. nanDECK will use this to lay out our cards.

cardsize=5.08,8.89

I know what you’re thinking: those numbers look odd. That’s because nanDECK uses  centimeters, not inches. (Yes, it’s a hassle, but Google will easily do these translations for you.) We’re just talking about a normal 2″ x 3.5″ business card here: width first, then height.

We also need to tell nanDECK what size paper we’re using:

page=21.59,27.94,LANDSCAPE,HVEO,#FFFFFF,[all]

That’s a lot of parameters, but nanDECK should give us some hints (though we’ll really need to refer back to the manual on what it means):

nanDECK hints

Again, the first two parameters are in centimeters. We’re just telling nanDECK that our page is 8.5″ wide (21.58cm) by 11″ tall (27.94cm), in landscape mode, centered vertically and horizontally (the HV), has no printed guides on either odd or even pages (the EO), is white, and should be used for all cards in the set.

That’s a mouthful, but remember: if we stick with one type of paper for all our card prototyping, we can copy and paste this into every template without having to think about it.

Next, let’s actually write some text:

font="arial",16,"",#000000
text=[all],[Title],0.25,0.25,4.58,1,"left","top"

We’re telling nanDECK to use 16 point black Arial for whatever follows this TEXT directive. Then, we’re creating a text block on all cards in the set, with the Title value for each card printed out in the text block. Our text block should be indented 0.25cm from the top and left side of the card, and be 4.58cm wide by 1cm tall. (4.58cm + 0.25cm margins = 5.08cm wide card)

Note that we are defining the size of the text block, not just its position, which means it may get cut off. We’ll want to double check our layout against our card set before we actually print to make sure this doesn’t happen. (Typically, I print to PDF from nanDECK, review the PDF, and then print from there.)

To print the description, we do something similar:

font="arial",12,"",#000000
htmltext=[all],[Description],0.25,1,4.58,7.64

This time, we’re telling nanDECK that our text block containing the Description value for each card should be formatted as HTML. That means our <br/> tags will be interpreted as line breaks, and we can use <b> or <i> to format certain bits of text.

That’s all there is to it. If we type this into a nanDECK tab and click “Validate+Build,” we should see our cards to the right. We can then click “Table” to actually flip through our cards, ensuring that the randomization “feels” right.

The nanDECK Validate+Build and Table buttons

The nanDECK Validate+Build and Table buttons

In the next post, we’ll get into conditional formatting.

(Continued in part 3.)

Prototyping a card game with nanDECK, part 1

Sometime last year, I started playing around with prototyping a card game. At its core, it’s a hidden-loyalty game strongly influenced by The Resistance and Battlestar Galacticabut with combat influenced Lunch MoneyAs such, it’s required a lot of tweaking for the little playtesting I’ve done.

I recently dug up and updated my prototype, throwing away long-removed cards and reprinting heavily marked-up cards.

This has all been a rather painless process because I chose to use nanDECK for printing my prototypes. This allowed me to manage my deck lists in spreadsheets, which I then feed into nanDECK whenever I want to do a printing. (And deck list management was a concern for me, since I had three decks–Loyalty, Player Actions, and Encounters.)

I won’t say nanDECK is a useful tool for every deck you need to prototype. There are other programs that will spit out printable cards from a CSV–likely much, much easier to configure. nanDECK’s configuration is rather esoteric, and some of it feels like it slowly evolved out of bolted-on user requests.

In part 2 I’ll talk about how to actually write these configurations. But for now, let’s talk about the reasons you would (and wouldn’t) want to use nanDECK.

Reasons I used nanDECK

Testing card probabilities: My game contains multiple copies of the same card, so I wanted to be able to adjust the numbers to tweak the “feel” of the randomness (ideally, without having to print up cards). Fortunately, nanDECK has a “Virtual Table” feature that allows you to draw cards from a shuffled version of the deck.

nanDECK Virtual Table

My own card layouts and spreadsheets: My Encounter cards don’t fit into a simple title-and-description format. Some (but not all) Encounter cards include some numeric values.

While I could simply embed these in one long description, I wanted to make them columns in my CSV file. I also wanted my card template to conditionally hide these fields (and their labels) if they were empty in the spreadsheet.

Custom card formats: For simplicity and uniformity, I prototype with perforated Avery business card templates. This is extremely convenient for me, so long as I can make the cards fit the template. (If I was using Word, this would be easier, but it would also require me to copy-and-paste a lot of cards.)

I needed to be able to force my cards into a non-standard 2″ x 3.5″ format, and (more importantly) ensure these cards were laid out matching the perforations.

Cases where nanDECK wouldn’t be useful

Simple title-and-text cards: If your cards don’t benefit from a custom layout, then it’s probably not worth wrangling nanDECK’s templating system.

Unique cards: If there will be one and only one copy of each card in your deck, nanDECK isn’t going to be worthwhile. You’re better off using something like word (even if trying to maintain your card list might be a bit awkward).

Anything beyond initial prototyping: If you’re adding card art or you’re no longer juggling card text on a regular basis, nanDECK is more complicated than helpful. At this stage, you’re better off laying out cards in a desktop publishing or graphics application.

(Continued in part 2.)

Upcoming panels (7/29/2014)

AkaiCon, August 1-3, Nashville

  • Game Development for Fun (and not profit)Saturday, 5pm, Embassy East – An overview of “hobby” game development, including how to get started, the (free) tools available, and how to find support in user groups and game jams.
  • Board Gaming 201Saturday, 9pm, Embassy West – An overview of how to identify the types of board and card games you like, as well as board game recommendations.

Anime Weekend Atlanta, September 26-28

  • Otaku Board and Card GamingTBD – An overview of games by Japanese designers, as well as Japanese- and “otaku”-themed games. (This is sort of a specialized version of my general tabletop gaming panel.)

Blog re-purposing

There’s been a couple of gamedev-oriented blog posts I’ve been meaning to write for a while, so I figured it was time to take a look at the old blog again. I’ve pruned off all the random personal posts, leaving mostly the gaming and coding posts.

This isn’t one of those infamous “I really need to blog more” posts; it probably won’t be a regular thing. However, I find it’s helpful to create up specific outlets for specific types of posts, and I’ve sorely needed a space for this category of post.

I’ll also be using the blog to note upcoming panels I’m doing, since that’s becoming a regular thing for me these days.

Reactions to the D&D “5E” announcements/rumors

I’ve heard some rumblings about a new edition of D&D today, and finally caught a couple of links in my Twitter feed. (I could just Google this stuff, but I’m lazy and feel like I can trust re-tweeted links from known sources better.)

I’m having two reactions to these rumors, and I think these apply to not only gaming, but technology and programming and all sorts of other things. (Admittedly, they are gut reactions.)

Learn to recognize when you’re being sold the “next big thing” line, but don’t overreact. 4E’s marketing was all about how it makes the game more accessible and easier to play. And it did that, mainly by adopting some game mechanics from MMOs. Fundamentally, this isn’t a bad thing. Rumors pointing to a more old-school approach suggest either it didn’t work or it went too far.

This seems to be the fundamental problem with a lot of leaps in design/technology: to ease the uncertainty, it’s hailed as the “next big thing” (the implication usually being that those who don’t like it don’t “get it”). For other examples, look at WPF vs. WinForms and .NET vs. WinRT. Or look at any new programming methodology that gets some good buzz behind it. Maybe we’d do well to consciously remember almost every “next big thing” will somehow, someday be “old and busted,” if only because it loses its novelty, and that you can’t say with certainty what “the next big thing” will be until well after it actually becomes “the next big thing”.

But being a naysayer may be as bad as being sold on the party line. 4E was a different system than 3E. It did some things better and some things worse, but it wasn’t on the whole a huge step back–more like a lateral move. Ultimately, I hope the update will capitialize on the good things while dropping the things that didn’t work. But if you deny that an about-face means the whole thing wasn’t as successful as hoped, you might end up missing the “next small, iterative thing” because it’s not the much-heralded “next big thing.”

My point, I suppose, is that the best response is to realize it is a line and ignore it. And railing against it is not ignoring it–you’re still allowing the line to dictate the terms of the conversation.

As an aside, I think companies damage trust with their customers when they play a strong “next big thing” line and it fizzles. Of course, that’s just me–I’m overly literal and I have a strong reaction to trying to reframe reality in ways that turn out to be decidedly unrealistic. But I have a feeling the “reality-based community” is not a large portion of anyone’s target audience.

WotC is doing well to frame this announcement by focusing on the fact that game development is an iterative, sometimes opinionated process, rather than playing “the next big thing” card again. I don’t know if that will convince people to buy a new set of books.

There is no universal system for anything. I find the talk of a single system a bit disconcerting. 3E was a very tools-oriented system and 4E was a very game-experience-oriented system. Both of these are valid approaches for different types of people, the success of which depends upon whether a niche will buy enough to support the product line. And the quality of each approach depends on making design choices that support that approach–it’s nearly impossible to create a good restricted, simplified system and cater to people who want an open, free-form toolbox.

To put it another way, even if it’s community-driven, it will not necessarily be universal.

4E was divisive is because it told 3E D&D fans “this is what we’re about now.” That didn’t sit well with me, but I recognized 3E and 4E were the right tools for different types of campaigns (in terms of genre, feel, player types, and scheduling/effort). No matter what the company line was, I was free to choose which tools I would use.

The two approaches could almost be separate product lines, or maybe alternate rules sets of rules à la Unearthed Arcana. (And it appears this is not too far off.) But any attempt to say “this is the secret formula” will end up looking dated in a few years, even if it was borne out of community involvement and playtesting.

Of course, the rub in WotC’s case is that you have to have a business model to go along with whatever decision you make. Will subscriptions work as well as they hope? I’m not sure. I only recently decided to shell out for D&D Insider, but $9.95/month is painful for one semi-regular game. Is there a middle way between a subscription-based model and model based on endless splatbooks? I don’t know.

Anyway, that’s my two cents. I haven’t played a lot of 4E. For reasons I’m not entirely sure of (and which may have little to do with the game itself) I haven’t been all that excited about learning the rules in depth as I was with 3E. Will these updates fix that for me, or will it make me say “screw it, I’m sticking with 3E”?

(EDIT: I actually went back and read some of the original source articles and updated this post.)

Upcoming Road Trip

So I have an interesting road trip planned in a couple of weeks.

I say “interesting” because it’s been a while since I’ve done any serious travel on my own and I’m looking forward to it. But also because it’s just a crazy combination of destinations.

Geek Media Expo

October 21-23 I’ll be in Nashville for the Geek Media Expo. So far I’ve had three panels accepted (XNA Jam, Podcasting 101, Nonfiction for Geeks), but the schedule isn’t up yet.

GMX has been in the cards for months. I wasn’t really sure which days I’d be going or where we’d stay, but I knew I was going. (As it turns out, “all three days” and “in the con hotel.”)

The new thing, and the thing that turns this into an honest-to-goodness road trip, is that I’m also going to be in Memphis. I’ll be at St. Jude Children’s Research Hospital earlier that week to participate in a medical study.

St. Jude

When I was in high school, I was diagnosed with non-Hodgkins lymphoma and went through treatment at St. Jude. (Incidentally,
since I haven’t had a relapse after 14 years, the chance of recurrence is nil.) I’m taking part in a study on the long-term effects of treatment.

Essentially, it’s three days of medical tests. My After Completion of Therapy checkups stopped 10 years after treatment, so it’s more data to help future research, as well as some medical tests at no cost to me. Plus, there are no travel costs and they’re paying me for my time (for some reason, participating in a medical study just sounds cooler than merely a very thorough checkup). In short, it’s a good excuse to take some time off and travel.

I won’t lie, I’m a terrified of the whole thing. First, the idea of three days of procedures and tests isn’t pleasant. And while I see it as an opportunity to catch potential health problems early (whether side effects from treatment or not), there’s always the slight chance that a battery of medical tests will turn up something serious. The best I can hope for is getting griped at about my weight and general being out of shape (which, not surprisingly, doesn’t help the blood pressure reading).

The plan is to leave out that Sunday, drive to Nashville for a day, head on to Memphis on Monday night, and then come back to Nashville Thursday after my last appointment.

Since I have some extra time, I will try to see family when I’m out that way. I’ve talked to dad about nailing down some plans on that front–mom and dad will likely be going on Sunday and Monday. (I’m in Nashville every year for MTAC, but usually ride with friends and spend all my time at the con. I always feel a little guilty.)