Cabal Package Installation Woes

tl;dr: Nuke ~/.ghc and then run cabal install --lib (every lib you need)

Edit: Since writing this post, there’s been some movement on the cabal bug, and it seems like there’s soon going to be a fix!

I’m trying to write a simple webserver based on Warp, but I ran into an issue with a hidden package. Here’s my imports in Server.hs:

{-# LANGUAGE OverloadedStrings #-}
import Network.Wai (Application, Response, rawPathInfo, responseFile, responseLBS)
import Network.HTTP.Types (status200, status404)
import Network.Wai.Handler.Warp (run)

And here’s the relevant part of my .cabal file:

executable server
  main-is: Server.hs
    base >=4.12 && <4.13
    , wai
    , warp
  default-language:    Haskell2010

Note that http-types is missing, but we’ll come back to that at the end.

I’ll start by saying that I don’t fully understand the difference between cabal and stack, and at the beginning I decided to just use cabal and not worry about stack.

I ran cabal install wai warp and got the following error:

Resolving dependencies...
cabal: Cannot build the executables in the package wai because it does not
contain any executables. Check the .cabal file for the package and make sure
that it properly declares the components that you expect.
Cannot build the executables in the package warp because it does not contain
any executables. Check the .cabal file for the package and make sure that it
properly declares the components that you expect.

It turns out the solution to this is to append --lib and run cabal install --lib wai warp. (I wish it would say that in the warning though.)

I ran cabal install wai warp --lib and tried running Server.hs by pressing command+b in Sublime Text 3, but I ran into this error:

Could not load module ‘Network.HTTP.Types’
    It is a member of the hidden package ‘http-types-0.12.3’.
    You can run ‘:set -package http-types’ to expose it.
    (Note: this unloads all the modules in the current scope.)
    Use -v to see a list of the files searched for.

I think what’s happening here is that http-types is installed, but not explicitly. Haskell wants me to definitely say that I want it, so I try running cabal install --lib http-types.

This, however, runs into a very frustrating error. Apparently the process library is required at two different versions in two different packages – despite already being happily installed as an indirect dependency:

cabal: Could not resolve dependencies:
[__0] trying: base- (user goal)
[__1] trying: ghc-8.6.5/installed-8.6... (user goal)
[__2] next goal: process (user goal)
[__2] rejecting: process-, process-, process- (constraint
from user target requires ==
[__2] rejecting: process- (conflict: ghc =>
[__2] rejecting: process-, process-,
process-, process-, process-,
process-, process-, process-, process-,
process-, process-, process-, process-,
process-, process-, process-, process-,
process-, process-, process-, process-,
process-, process-, process-, process-,
process-, process-, process- (constraint from user target
requires ==
[__2] fail (backjumping, conflict set: ghc, process)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: process, base, ghc

The solution to this is very frustrating, because even rolling back my git repo to the last known good commit didn’t fix it – it’s a global system problem (ironic, for Haskell, which is so demanding of “pureness” in the language). I deleted ~/.ghc and ran the install again:

rm -rf ~/.ghc && cabal install --lib wai warp http-types

And it worked! My server runs 🙂

The problem is now, I want to build some tests, so I run cabal install --lib hspec and I run into the same “could not resolve dependencies” as above!

Hm, let’s see if just a rm -rf ~/.ghc && cabal install will fix it, if I declare hspec in build-depends in my .cabal file? I get the following error:

cabal: Path '/Users/erty/.cabal/bin/server' already exists. Use
--overwrite-policy=always to overwrite.

So let’s try the suggestion and run --overwrite-policy=always. Infuriatingly, this build succeeds but when I try to actually run Server.hs (by pressing cmd+b in Sublime Text, perhaps that’s missing a flag or something? I wonder if cabal install builds a binary but fails to install the libraries) it fails to find any of my modules:

Could not find module ‘Network.Wai’
Could not find module ‘Network.HTTP.Types’
Could not find module ‘Network.Wai.Handler.Warp’

Let’s try rm -rf ~/.ghc && cabal install --lib, since adding --lib worked before. First, I also added http-types to my build-depends in the .cabal file. Nope:

Resolving dependencies...
cabal: Cannot build the libraries in the package crossword-hs because it does
not contain any libraries. Check the .cabal file for the package and make sure
that it properly declares the components that you expect.

But! We were able to get it working by listing all of the dependencies explicitly during the install phase. So let’s try that and run rm -rf ~/.ghc && cabal install --lib wai warp http-types hspec:

Works! The problem is that I have to remove ~/.ghc manually list out all of my deps every time I want to install something, but at least I can move forward for now.

I also added http-types to my cabal file, but it didn’t seem to really matter for running in sublime text, as long as I’d installed it via cabal install --lib.

I would love to hear from any more experienced haskellers out there if I’m not understanding something about cabal. Specifically, coming from node, I feel like cabal install (or even with --lib should “just work” and install all of the deps I’ve listed in the .cabal file.

Hopefully this writeup saves someone else time 🙂

Expanding the !!Con Aesthetic

TL;DR: There’s a cool new project to put on plays about computing. In addition to traditional talks, we’re inviting people to submit more artistic 10-minute plays or other “non-talks” to !!Con as well as The Art of Python.

Sumana Harihareswara and I had lunch sometime late last year and talked for a while about her newest brainchild, The Art of Python. To steal her own description, The Art of Python is a miniature arts festival at PyCon North America 2019, focusing on narrative, performance, and visual art. The Art of Python was recently accepted into the PyCon Hatchery Program, an incubator for PyCon-related ideas. It will be a series of short plays, 5-20 minutes each, held on the evening of Friday, May 3.

Sumana has worked with the !!Con team before and wrote one of my favorite articles about the conference, Toward a !!Con Aesthetic, which I re-read every year to re-center myself on what !!Con can (and in my opinion, should) be. One of its sections is titled Spectacle and play, and explores how some of the talks cross from being a “talk” into being a comedy or sketch show. We as audiences remember these moments where the magician shows us that something more than meets the eye can be done – and in our case, presents a new kind of magic to an audience of magicians.

That’s why we’re inviting people to open up the idea of what constitutes a “talk” at !!Con this year. We would love to see drama, comedy, and magic. If you are interested, we invite you to submit a play to both !!Con and The Art of Python, theme and length (10 minutes for !!Con) allowing. Note that The Art of Python’s CFP specifically says that the play does not actually have to be about Python, just the emotional experiences of programming.

Our CFP will open Feb 6 Feb 8, and The Art of Python’s CFP is already open. Bring us your explorations and reenactments. Show us how your computing is spectacle and emotional. Explore with comedy and tragedy the feelings that surround this field that has only been around for one generation, two or three if we’re really generous.

Some caveats: !!Con is still going to be looking for “the joyous, exciting, and surprising moments in computing”, and we’re not going to have a separate track or approval process for non-talks. But, based on the amazing work that we’ve seen in years past, and ideas we’ve been pitched, I don’t doubt that you the reader have something worth submitting to !!Con and The Art of Python.

Of course, I encourage you to submit your proposals for 5-20 minute plays to The Art of Python regardless of whether you go on to submit them to !!Con! You should also check out the Hatchery program for next year, if you have an idea for a conference track that you’d like to try out in the context (and with the backing of) PyCon.

We talk at !!Con a lot about the intersections of humans and computers, since indeed the things that computers do are ultimately created and consumed by humans (well, or their pets). The lecture format is often ill-suited to explore this emotional side of computing, and especially poor at exploring the relationships between people who make the magic lightning rocks go fast.

I will admit that watching a play about programming sounded awkward at first, but then I reminded myself that 1) the spectacles that Sumana mentioned from previous !!Cons have only been amazing, and 2) when I go to plays about far more uncomfortably introspective topics, I generally end up learning something about myself and/or the world. It’s sometimes not even something that can be put into words – but that’s exactly the point. Some things are very hard to describe by speaking at a room with a slideshow behind you. Perhaps one of these non-talks will inspire, delight, and amaze in a way that’s uniquely deep.

We are still exuberant about accepting traditional-format talks and are looking forward to seeing all of the cool, fun, scary things that you have done with computers. Polish up your demos, dust off and re-submit your !!Con talks that didn’t make it in previous years, think about the fun bug that you defeated, and come tell us about it. If you want some more information before we post the CFP: Lindsey Kuper, organizer emeritus now leading the charge on the west coast, has a great article about the kinds of talks we’re not looking for. I’ve written previously about how we select the talks.

I’m optimistic about this widening of our focus. Similar to our inclusion efforts, there’s a difference between not-not-permitting and inviting. If people had submitted drama/magic/spectacle to previous !!Con we would have judged it seriously, but to openly request it alongside the traditional talks breaks down the assumption that a 10-minute !!Con slot is only for a “talk”, which, to be honest, is just because that’s what other conferences do. I like to think of us as more avant-garde than that.

Radish Cache

After coming across a (now deleted) answer on StackOverflow, I took some time to find instances of “redis” (a popular caching program) misspelled as “radish”. I think autocorrect is likely the culprit.

I’m posting these here because I think that this is a wonderfully innocent error and not to shame the people involved. Imagining someone refreshing their cache of small red vegetables brings joy to my heart and I hope it does to yours as well.

The Original

This came up in an edit queue, but I didn’t have the heart to edit it. I now suggest this as the solution to most of our technical problems at work, much to my coworkers annoyance.

From Harvard

This one is in an article published by Harvard, so you know it’s legit.


This person has radish cache on their LinkedIn profile, so you know they’re an expert. (Last item)

Please go to my LinkedIn and recommend me for radish cache. I’d like to add you to my persimmon network.

Speeding up Magneto

Vegetables are part of a healthy diet. Varnish, not so much.


Unfortunately, the only IRL radish cache has been removed and no longer exists.


Remember, if you have a problem, flush your radish cache!

The !!Con Talk Anonymization and Selection Process

Another conference organizer recently asked the !!Con team what our anonymization process was, and we realized that we didn’t have a good source for them. While we tout our anonymization as a major component of our quest to eliminate implicit bias during the talk selection process, we haven’t written what our anonymization and talk selection process actually looks like in a while.

Julia Evans wrote a great post about our anonymization outcome after the first !!Con in 2014, and Lindsey Kuper has an update from a year later that goes into a lot more detail. We’ve changed some processes since (we no longer use github issues to track the proposals, for example).

One thing I want to point out is that if you’re submitting a talk proposal to !!Con, you shouldn’t worry about how your proposal will be anonymized! Just submit your talk like you want it to be listed, and we’ll take care of the anonymization process.

Here’s the blurb about anonymization from this year’s Call for Talk Proposals! page:

Proposals will be anonymized to avoid bias. Although we ask for your name, email address, and so on in the proposal submission form, only one or two organizers who serve as anonymizers will actually see this information, and they won’t review your proposal. The rest of the organizing team will review your proposal without knowing who you are.

I also think we have a pretty cool way of doing the talk selection, so I’ll cover that as well in this post.

Here’s the secret sauce:

  1. Each year, before we open the Call for Proposals, we decide who is going to be on the anonymization team, and who is going to be on the talk selection team. Generally the anonymization team is one or two organizers plus potentially one or two outside helpers who we recruit. The talk selection team is the remaining four or five organizers. This year, Alex Clemmer and I are the anonymizers, and the rest of the organizing team is the talk selection team.
  2. The anonymization team is the only team with access to the google form (and resulting google spreadsheet) that we use to collect talk submissions. Then we open the Call for Proposals!
  3. It’s tradition that the anonymizer who is supposed to close the google form falls asleep before midnight and forgets to close the form until the next morning. This year it was me and I didn’t close the form until 9am. Whoops!
  4. The “chief anonymizer” saves a copy of the original spreadsheet and begins going through it to anonymize it. Each talk is given an ID (a random unique integer, so that we don’t give away when the talk was submitted), so that we can track and re-aggregate our data at the end of the review process.

Let’s talk about the anonymization process. Here’s an example talk proposal (by me right now for demonstration, this probably wouldn’t be accepted):

I work at FiniteAutomata Corp, so my talk is about how knowing how finite automata work gives you regex superpowers! People will look at me and say, “wow he is so cool with his regex” and I’m like “heck yes I am good because I know how finite automata work let me teach you”. Here’s a link to me giving a longer version of this talk at FiniteAutomataCon 2011:

The anonymizer takes this proposal and does a couple of things:

  1. Remove/Obscure any names of people or companies. We generally leave in product names unless the talk submitter is the main author of that product, in which case we will remove the product name as well. For example, “FiniteAutomata Corp” in the example above would become “[Large Tech Firm]”, in square brackets (or similar).
  2. Remove/Obscure any pronouns or other identifiers. For example, my proposal above says “he” and “his”, which gives away my gender. We would replace these pronouns with “[they]” or “[author]”.
  3. We also try our best to watch / read any associated material and give a quick synopsis of it. For example, the link in the proposal above would become “[Video of the author giving a 30-minute version of this talk at a well-known conference. The talk is well received by the audience.]”

During anonymization, we try not to remove aspects of the speaker’s identity that are essential to the message of the talk. For example, the abstract for Sina Bahram’s 2016 talk about screen readers begins, “I use a computer very differently than most people, because I’m blind.” It wouldn’t have made sense for the anonymizer to remove this fact, because it is Sina’s personal experience that makes the talk proposal especially compelling. We try to use our best judgement here (and probably get it wrong sometimes!)

Once we’ve created the anonymized version of all the talks, we create a copy of the anonymized spreadsheet for each of our reviewers. If I were on the reviewing team, I would get a spreadsheet called “!!Con 2018 – Talk Proposals [Erty]”. This is my personal copy of the anonymized spreadsheet.

The next step is for each reviewer to give each talk a grade. !!Con co-organizer Lindsey Kuper introduced this grading scheme, based on the Identify the Champion process (Specifically Make Champions Explicit):

A – I really like this talk and will advocate for it to get into the conference
B – I like this talk, but not enough to advocate for it
C – I don’t like this talk, but not enough to advocate against it
D – I don’t like this talk and will advocate against it being included in the conference
X – I think I know who submitted this talk, and abstain from giving it a grade

The chief anonymizer then creates a spreadsheet that aggregates these grades into a single place (did you know that you can include cells from one spreadsheet in another using google spreadsheets? It’s pretty nifty!). We look at the best grade and the worst grade for each talk.

Some examples:

A talk that got grades A B B C would have a final grade of AC (A is the best and C is the worst)
A talk that got grades X A A X would have a final grade of AA
A talk that got grades X D C A would have a final grade of AD

If a talk got 0 or 1 grades due to abstain votes, we would handle that as a special case. I’m pretty sure that hasn’t happened in the 5 years we’ve been running !!Con.

We all get on a conference call at this point and start going through the talks! This is really fun! AA talks generally get in immediately. AB talks are usually also admitted as well, if we still have room. AC talks we usually discuss, but they’re generally not admitted, and AD talks are really interesting, since it means someone will advocate for it and someone else will advocate against it! Generally, someone misunderstood the proposal, or two people have differing ideas about what kind of talks should get into !!Con. It’s usually a no, but these talks will sometimes get in (especially if they got AAAD).

More generally, this means that only talks that get at least one A are considered. Your talk needs to convince one of our reviewers to become a champion for it. As Lindsey noted in her blog post Scaling !!Con, last year (2017) we had 86 talks with an A out of 215 total, which we then had to narrow down to just 30!

Remember that all of this is still being done with anonymized talks. The anonymizer(s) will usually sit in on this call and answer any questions about the proposals that the reviewers have (usually around things like the descriptions of videos that were with the proposal). But never speaking up to sway a decision in one way or another. This is difficult! Last year I spoke up because I was really excited about a talk proposal (that ended up not getting in, anyway) but I definitely shouldn’t have done that, since I knew who the speaker was and therefore had implicit bias.

Once we’ve decided which talks we’ll approve for the slots we have available, we take our next favorites (generally about five of them, but it varies) and hold those as backups in case our acceptances aren’t accepted (it happens!).

The anonymizer then goes through and makes sure that we didn’t select the same speaker twice (some people have submitted as many as six talks in a single year!) If we did, we bring some more people off the backup list, then replace them to keep our backup list full. Usually if someone submitted two talks that were accepted, we let them choose which one they’d rather give. Although, if there’s a clear favorite, we might suggest that they choose that one 🙂

At this point we do the dramatic reveal and show the review team who got in! Then we email these people. This is really fun 🙂

One important thing to note: If you didn’t get accepted, then your name is never revealed, not even to our review team. The anonymizer emails out our famous rejection letter after we’ve figured out our lineup. This is not so fun 🙁

That’s it! I hope this is useful information, especially if you’re starting a conference yourself.

a e s t h e t i c 💫 g e n e r a t o r

Update: the a e s t h e t i c g e n e r a t o r is now online.


Ryan McVerry, Per-Andre Stromhaug, and I got together this weekend to do a mini-hackathon. We’d been inspired by a Chicago-based artist on Tumblr named Galactic Castle. Specifically, this image:

Our goal, was to write python to generate images that looked like Galactic Castle’s. We used the Pillow python library for the most part, messing around with 256×256 arrays of integers, limited to 10 or so colors.

We experimented with a few different rendering techniques, eventually settling on a layered technique. I’ll start with some examples of the finished product, and then a quick walk through some of the fun images we generated along the way. You can run it yourself at

Here are a few shots from the process along the way.

This is one of the first renders we saved. You can see most of the elements coming together, and the dithering in the sky is already in place.

Experimenting with color palettes:

I messed up the color palette:

Getting reflections working. At this point I was doing two things that I eventually stopped doing: reflecting the actual colors (instead, we just use a single color to represent any reflection) and at this point we weren’t doing any sort of layering, so the reflections were crude and unaware of what they were reflecting. In the latest version we use a different algorithm for things above the horizon (mountains, moon) and things in the water (rocks/land).

Better reflections, added a moon.

Re-worked the rocks code. We were originally using polygons that were then filled by PIL. The new code instead generates an enormous int buffer and we manually fill in from the edge. The rocks at the base of the land spits are just handled by keeping track of a number that grows and shrinks, and switching colors when we reach that threshold.

We were originally working at 512×512 (scaling up x4 for the final image), but eventually realized that Galactic Castle works at about 150×150, so we scaled down. The resulting pixelation is much more pleasing. Added trees and improved the mountain cross-hatching.

I hope you enjoy this! You can see it for yourself at

In 2024, I rewrote it in Typescript so that it runs fully in the browser (instead of a thin frontend on a Python backend). Code here 🙂

We Built an Arcade Cabinet in a Weekend!

We built an arcade cabinet! In 72 hours!

The team:

Project Lead
Software Engineers
Hardware Engineer
Music and Sound
Cabinet Construction
Cabinet Art

Finished image first 🙂

We had the idea to build an arcade cabinet several months ago, and by the time Ludum Dare 38 rolled around, we had the time and space to make it happen! We met a few times beforehand to test out ideas and hardware, and parts started arriving in early April:

We decided to use the LÖVE framework on Raspberry Pi 2-Bs, via the PiLove raspbian image.

Ideas started flying on Friday at 7pm Mountain, though, when we all got together to create the game. Sadly, our game idea about slipper and flipper the penguins didn’t make it to the final round.

We quickly began to mock out the cabinet design, and started building the game!

Our first prototypes were… okay 🙂

But things began to come together…

The cabinet really began to come together! We thrifted the TV for about $30. The speakers were old computer speakers we had lying around, and the coin door we purchased on Amazon for about $40.

More construction pics:

Haley (our artist) couldn’t join us until day 3, but she did an amazing job!

The yellow paint was a little… weird. Ah well :\

Finally, we had the whole thing rigged up! Time to plug everything in and turn it on!

A few touchups on the title…

And, about 15 minutes before the deadline, we had a functioning, working arcade game!

Here’s a quick video of the gameplay:



We ran into a major issue right at the end, where (to get technical for a moment), our audio would cut out from time to time and just stop working. It seemed like an issue with pulseaudio. The way we solved it was to kill pulseaudio on startup. And for some reason that worked? So, I have no idea what’s playing the sound, but whatever it is crashes less.

We also had a wonderful “blur” effect that pulsed in time with the music, but it turned out to be too intensive for the raspberry pi, so we had to turn it off in the end. We tried doing it with shaders (way too intensive) and we tried doing it with just drawing translucent, larger versions of everything (just a little too intensive) and finally turned it off. Ludum Dare definitely requires you to just cut things if they’re not going to work, no matter how much time you put into them!

I’m going to attempt to get a copy of the game working so you can play it online by Friday, but no promises!

Dictionaries and Word Lists for Programmers

I love to play with words, and I especially love to play with words programatically. I’ve written three small apps (so far) which use some form of a dictionary to create readable, humorous text:

I’ve had some people ask, so here are some great resources that I’ve found while building these apps.


/usr/share/dict/words (~235k words)
Available on any *nix system, this word list is a local way to check for words using a simple grep. You can also read the file in as long as you have permission to do so. Won’t work well if you’re trying to write something for the internet or windows.
Most of these dictionaries are licensed very freely, but you should check on your own system. Versions of this are available online, e.g. the FreeBSD version at (click “words”)

GCIDE (~185k words) or
This dictionary contains words and definitions. Very useful if you actually want to look up the words you are using. Sources for the definitions are available as well. There are two versions – GCIDE which comes in a strange format and needs its own reader software, and GCIDE-XML. Licensed under GNU.

SCOWL and friends (variable word count)
A very complete set of wordlists, used for the aspell spell checker. My favorite part is the customizable interface where you can create your own custom dictionary. Many links and different dictionaries are available on this page, including some with part-of-speech and/or inflection data. Be aware: many versions of SCOWL contain swears and racial slurs.
Variable licensure, but all are released for private or commercial use as long as you maintain a version of the license.

CMU Pronouncing Dictionary (~134k words)
Contains not only words but their phonemes, meaning this is a great dictionary for text-to-speech, rhyming, and syllable counting. There are CMUDict libraries for node/browser, just node, python, and many other languages (send links please).
The file is copyright Carnegie Mellon, but is unrestricted for personal or commercial use.

Corpora (Lists of ~1k words)
A really neat set of lists, broken down by category (e.g. /data/foods/beer_styles.json). A great starting resource for small projects that don’t need an extensive dictionary of the English language. Licensed under CC0 (no copyright).

Wordnik Developer (Web API)
A powerful web API. From the site: “request definitions, example sentences, spelling suggestions, related words like synonyms and antonyms, phrases containing a given word, word autocompletion, random words, words of the day, and much more.”
Free 15k calls per hour, licensed for anything that isn’t a direct clone of Wordnik itself.

(Please, send any more dictionaries you know of my way and I’ll add them to the list!)


FastTag / jsPos (java) and (js)
Java and Javascript libraries to tag parts of speech in words. Very handy if you’re doing any sort of lexical generation.
Licensed under LGPL3 or Apache 2 licenses

(Please, send more libraries my way if you know of them!)

People / Blogs

Peter Norvig
Probably my greatest source of inspiration on this front is Peter Norvig’s How to Write a Spelling Corrector (python). He shows that you don’t need any sort of fancy tooling or arcane knowledge to write something that at first seems complex – just don’t be afraid of making the computer do a lot of work for you. That’s what they do – they do work really, really fast. (see, for example, this scrabble solver)

Allison Parrish
Allison plays with words in amazing ways. She is the brains behind @everyword. Her website and research are full of great inspiration for playing with words and experimenting with language.

(please, send anyone doing interesting things with words my way and I’ll add them to the list!)

Project Idea: “Lanky” PHP Middleware Language

I keep not writing weekend web apps because I know that my projects generally follow this trajectory:
1. Build a database
2. Build some thin PHP middleware to expose an API to that database
3. Build a slick react/angular/whatever frontend
4. Realize a bunch of things I’m missing in my API and add them, lamenting the entire time that my “thin” PHP middleware is starting to bulge at the seams.

I keep realizing that that PHP layer is not really necessary. R0ml gave a great Recurse Center talk (if someone has notes I’ll link it)  on a postgres extension which renders the middleware unnecessary.

I’m not quite ready to make that leap and throw out the middleware entirely (even though I think it’s a great idea…). So I’d like to build a language to really easily describe a PHP API. My goal is to have the PHP routing be as thin as possible and mostly handled by one fast function. In fact, I’d love to eventually have this language implemented in node, or even C/C++ for a pure-speed kind of thing. I’d also love to figure out a way to cache the parsed document so that I don’t have to parse the entire thing every time, but that’s a future optimization.

I’ve started a github repository  with an example of how I’d like a Lanky document to look at

I may end up abandoning this at some point because of time restrictions but that’s why I figured I’d get my first ideas about it online – maybe if there’s something good in there someone can steal it, or even better, point me to a project which already does this but better.

I called it “Lanky” because that was the first synonym for “thin” that didn’t have outright negative connotations or an existing PHP framework (slim, gossamer, etc).

From Boulder, CO


Notes from PAX Prime 2015

I attended PAX Prime 2015 this past weekend with a friend, and ended up going to two talks.

Ask a Dungeon Master

Chris Perkins

  • Dungeon Masters are unique.
  • Gary Gygax
    • Had the players declare a “caller”, who was the only person to talk to the DM, who sat in an adjacent room.
  • Learn first by emulating existing DMs and running existing campaigns.
  • In older modules, location is key. In “modern” DMing, characters and politics are key.
    • The older modules are often named after the location, “crypt of the…”
  • Chris learned a lot from a few TV shows
    • Star Trek: The Next Generation
      • Character-Driven story
      • Focus on teamwork and character development
      • Episodic content with a repeating cast
      • Some episodes are standalone, while others feed a larger arc
      • In a serialized story, each character has an arc and needs to grow
      • Don’t introduce characters and then not allow them to shine for at least a moment
        • Give everyone a journey
      • Characters:
        • We know nothing about them
        • Choices are made
        • Shit happens
        • Now we know a lot about them
        • (They might not make it to that final step)
    • West Wing
      • Q: How did Aaron Sorkin make politics so interesting?
        • A: Have three or four things going on at the same time
        • Make it overwhelming so that the characters must make choices
        • Give quests with political importance
        • If one conflict gets boring, make sure there are others at the same time to fall back on
    • Buffy
      • (No notes?)
  • Storytelling is the art of using narrative to elicit an emotional response
    • PCs get attached to things. NPCs, Locations, Items.
      • But they can only get attached if those things have personality
  • Let characters make “real” choices and deal with the consequences
  • DMing is challenging as storytelling because it is performed LIVE
  • Constantly Improvising
    • (Here, Chris plugs Acquisitions, Inc.)
    • There are no (or, very few) takebacks in DMing
      • Remember what NPCs sound like!
  • Chris’ evolution of a DM:
    • Run published campaigns
    • Write your own campaigns
    • Improvise everything
      • This takes practice!
  • Good DMs…
    • Have fun!
    • Don’t over-prepare
    • Roll with the punches
    • Don’t fret about the rules
    • When in doubt, just say yes!
  • If everyone dies, call it a night
    • Death is the beginning of another story
  • Tricks
    • Hoard Maps
    • Use the Three-Story Arc
      • (Example)
        • The heroes need to find a route out of the underdark
        • There are drow kidnapping surface dwellers
        • There are spore-infested creatures
      • All three of these storylines are happening at the same time, the players bump into them as they move through the dungeon
    • Write things as episodes
      • Use episodic recaps to remind your players what happened last time, on D&D…
    • Chris prepares each session as a one-sheet summary
      • What is the basic outline of the episode
      • What are all the notable NPCs that the PCs might run into
      • What major events will probably happen during this episode?
    • There is nothing you can do wrong with NPCs. Give them EMOTION
    • Ask the players what they want!
      • (It’s their game too!)
      • Example Qs:
        • Magic Item wish list
        • Campaign Knowledge wish list
        • Accomplishment wish list
    • Use foreshadowing
      • The players will try to connect things even if you don’t purposely foreshadow.
      • So do it purposely!
    • Imagine an actor to play each NPC if you want a handy way to remember
  • Traps
    • Over-Preparation
      • Your PCs will never go where you expect. And if they do, you’re…
    • Railroading
    • Rules Inconsistency
    • Time Travel
      • (You think it’s fun, but experienced DM’s know, it’s a recipe for disaster)
    • Things players hate
      • Don’t do them!
    • “Me vs Them” attitude
      • Remember, you’re all on the same side – everyone just wants to have fun!

So, You Want to be a Game Writer

Toiya Finley (Schnoodle Media), Qais Fulton (Freelance), Anne Toole (The Write Toole), Bobby Stein (ArenaNet), Tom Abernathy (Massive Entertainment), Leah Miller (Carbine Studios)

  • Q: Even if you do understand storytelling, what should you know about game writing?
    • Average text length in games is decreasing
      • Avg length of text in Wildstar: tweet length (140 char)
    • Know the audience and technology. What works in the game?
    • These are interactive and nonlinear stories.
      • Sequence and Timing go out the window.
    • Don’t make your stories linear. Make them player-centric.
    • The player cares about “my story”, not “your story”.
    • They should have the choice of how to play the character
    • “The player’s story will trump whatever heartfelt thing you write [for NPCs]”
    • Designers and programmers will do their own thing with your story. You have to deal with their requests. It’s writing in a team setting.
      • Know how to communicate with the people who are actually building the game, to keep them in sync
  • Q: Game writing is competitive. How do I get a job?
    • “It’s like breaking out of prison. Once you figure out your path, it’s probably not going to work again.”
      • Try not to copy existing successes. Make your own.
    • Some companies you can start out at the bottom and work your way up to writer over years.
      • Many others, you can’t – you have to get hired in at the top
    • (Ed note, this is good job advice for any field!)
    • Work on your own projects. Have a portfolio that you can show people.
      • Have it online.
      • Make sure it’s recent
      • Work consistently
    • Practice your “Story Sense”
    • If you want to make your own games, you don’t want to be a writer. You want to be a Creative Director
    • Check out text-based game engines
      • Twine
      • Inform7
      • Episode Interactive
      • Pen & Paper RPGs
    • Play with level editors so that you know what the developers are working with
  • Q: Portfolio? What should I showcase?
    • Genre diversity!
      • Have some horror, action, humor, etc.
    • No two employers want the same thing
      • Aim for around 2-3k word games for your portfolio pieces
        • That said, have lots of different length material. Every company wants something different
        • “Short, concentrated awesome”
      • Dialogue Samples
      • Lore Documents
      • Technical game design documents readable by non-writers
    • Know the types of games the company makes, and tailor your portfolio to them
    • Don’t assume the company knows anything about (good) writing
    • Copyright theft is real!
      • Use watermarked PDFs
      • Only post samples
      • Protect yourself against plagiarism
  • Join the IGDA
    • Int’l game devs assoc
      • Writers’ interest group
        • Facebook group
  • In meeting people, it’s more important to have an interesting conversation, than to “network”
    • Make friends, not contacts
  • Q: Freelancing v Employment
    • It’s good to have at least one staff job on your resume, esp. if you did “the trenches” (crunch, ship)
    • Freelancer, you also have to be a salesperson. Always be selling your writing
      • Read marketing books, sales books
      • You’ll also have to be a collections agent
        • Don’t work for free
        • You can get consistent work, but it won’t be consistent money
    • Don’t be afraid to fire bad clients
    • Make “work for hire” agreements
    • Full Time:
      • Benefits!
      • Work at an office (external motivation)
      • Structure!
      • But: They own you
      • Be aware of your self
      • Better mentorship opportunities
      • Get pushed into weird projects (which is great for experience!)
      • At a smaller place, you can make things happen!
        • Just talk to the CEO
      • When you work on staff through crunch, you become really good friends (which turn into really good contacts after you leave)
      • If you work at a large company, make sure you make friends with people outside your small team. You have an opportunity to get a large network. Use it!
      • Remember that personal work done at work (Even if not on the clock) belongs to them. They own it. Be careful about how/when you work on personal projects.
        • Or, just pitch your ideas to them and see them get made!
      • Know your rights
  • Q: How do I write?
    • Write!
    • Just write. Don’t be attached to your writing.
    • Work back and forth with the developers and designers
    • Write shitty first drafts
      • You’ll have time to revise
      • You’ll have people to get feedback from
    • Be prepared for blunt feedback and people who don’t understand your intent
    • Be prepared to admit failure, but have some confidence, Know your strengths and weaknesses.
    • When you’re working on a game, everyone is on your side. (They all want the game to be good!)
    • Be prepared to throw everything out and start over
  • In games, don’t tell, don’t show, do.
    • Let the players learn organically through the environment, instead of trying to cram instructions into words.