Avatar

Games with Tracery

Someone online asked if there was a guide to integrating Tracery with games, so I wrote one.

Tracery is named for the architectural term "tracery", the curly filigree part of gothic cathedrals. Tracery doesn't hold up the cathedrals: it's decorative not structural. If you find yourself trying to do very complex data storage and conditionals with Tracery, you might be trying to build a cathedral with filigree. It is best to use your game code (javascript or Unity, or whatever else you use) itself to perform complex tasks like these. Tracery is best for adding decoration afterwards. But there are some good techniques for adding Tracery to games that I've encountered.

Common uses of Tracery

Games often have abstract rule systems at their core (see Joris Dormans work on modelling games abstractly http://www.jorisdormans.nl/machinations/). But even for games with identical rule systems, content can create flavor and feelings that go far beyond the meaning of rule systems. Ladykiller in a Bind and Hatoful Boyfriend may have very similar mechanical systems driving them, but what wonderfully different experiences we get from their unique content! From flavortext on Magic: the Gathering cards to story arcs and dialogues of dating sims, or the sprawling poetry of Twine games, content can serve many purposes in a game.

Tracery, and other grammar-based templating languages, are already popular in games to create new content. Dietrich Squinkifer uses it in Interruption Junction for an endless stream of dialogue and in Mr. Darcy's Dance Challenge uses it for endless insults from Mr. Darcy. Pippin Barr uses it to generate thoughtful frowns and headscratches in It is as if you were playing chess.

Beyond Tracery, there are other templating languages, and many game developers have built their own. Zach Johnson, the creator of Kingdom of Loathing invented a templating language to create game content like combat text and hobo-names (https://youtu.e/X3sqkxedSHQ?t=4m6s). Even the original 1966 ELIZA chatbot used templating in its dialogue generator.

Basic Tracery content in a game

These basic content creation tasks are easy for Tracery! Create a grammar "rpgGrammar" (or several, like "weaponGrammar", "innNameGrammar" etc if you don't want to share content between grammars) with your writing. Then call

rpgGrammar.flatten("#innName#") or rpgGrammar.flatten("#NPCName#") or rpgGrammar.flatten("#armorDescription#") or rpgGrammar.flatten("#combatSound#")

to generate whatver content you've authored.

Generating parseable data

You may find that you want to generate more complex stuff with a single query, such as generating a sword name and a related description like "General Greenblat's Blade" "a sword found by General Greenblat while searching for her lost puppy". In that case, you might have a grammar like

"swordWord": ["blade", "edge", "sword"],

"bowWord": ["aim", "bow", "longbow"],

// This picks out whether we are generating a bow or a sword "setWeaponType": ["[weaponClass:sword][weaponNameType:#swordWord#]","[weaponClass:bow][weaponNameType:#bowWord#]"]

"generateWeaponData": "[character:#name#]#setWeaponType##weaponType# | #character#'s #weaponNameType#" | #character# found this #weaponType# when #doingSomeTask#"]

Expanding "#generateWeaponData#" would generate some data separated by "|" symbols, which you could then split apart with Javascript and use separately in your game.

Generating tagged data

I've been working on a hipster chef game, HipChef (for waaayyyy too long). It's been an exercise in figuring out good tagging practices for using Tracery text in a game while also getting meaning out of that text.

For example, here is a sample of my grammar for generating recipes:

largeFruit : ["kumquat<citrus>", "honeydew<melon>", "bittermelon<melon>", "cherimoya", "peach", "sugar apple", "persimmon", "green apple", "jackfruit", "damson plum", "kiwi", "lime<citrus>", "key lime<citrus>", "meyer lemon<citrus>", "pomegranate", "green apple", "pineapple", "mandarin orange<citrus>", "blood orange<citrus>", "plum", "bosque pear", "fig", "persimmon", "durian", "mango", "lychee"],

preparedMeat : ["duck fat<fowl><game>", "roast duck<fowl><game>", "crispy bacon<pork>", "pancetta<pork>", "salami<pork>", "prosciutto<pork>", "corned beef", "pastrami<beef>", "roast game hen<fowl>", "seared ahi<fish>"],

herb : ["fennel", "cilantro", "mint", "basil", "thyme", "Thai basil", "oregano", "peppermint", "spearmint", "rosemary"],

spice : ["vanilla", "nutmeg", "allspice", "turmeric", "cardamom", "saffron", "cinnamon", "chili powder", "cayenne", "coriander", "black pepper", "white pepper", "ginger", "za’atar"],

"artisanToast": "#bread# with #spice#-spiced #largeFruit# and #meat#"

This might generate some fancy toast descriptions, but in the game, I want to know the game-significant ingredients of this toast. If it has pork and fennel, which are trendy at the moment it scores higher, but if it has duck and melon, which are not, the score is lower. I can search for some ingredients, like "pineapple" by name, but others, like "mint" might be ambiguous. Other queries, like "fowl" or "herb" would need to match many rules.

The fastest way to do this, for me, is to hand-embed these tags inside the content, like kumquat<citrus>. For some content, like herbs and spices, I want to tag all the rules with a single tag. That sounded like work, so I wrote a bit of utility code function autotag(grammar, key, tags) which automatically appends the given tags to all the rules for that key.

Now when the toast generates, it outputs a string like "Ciabatta with turmeric-sprinkled honeydew and roast duck". I can strip these tags out with JavaScript, and get and array "spice,melon,fowl,game" (which the game's rules can use) and a string "Ciabatta with turmeric-sprinkled honeydew and rost duck" which I can display to the player.

You can generate any structure of data this way, even JSON (which you can then use JS's JSON parser to unpack automatically). In fact, the SVG graphics made with Tracery are an example of this: Tracery generates specially structured text, which a web-page can interpret as image-making commands. But SVG and JSON parsers are just two ways to computationally parse text, you can write your own, as I did with HipChef.

Using world state in Tracery

Your game almost certainly has some world state. For an RPG, this might include the player's occupation and race, their weapon, their health, a list of skills. Like many games, you might also have a custom name for the player. To use the name in Tracery, you can edit the raw grammar before you use it in Tracery or you can edit the grammar on the fly by pushing new rules to the grammar. This is what Tracery does when you use "[myName:#name#]" in a grammar, but now you're doing it whenever you want, with whatever data you want.

mygrammar.pushRules(playerName, ["Bobo the Love Clown"]);

mygrammar.pushRules(playerHometown, ["Scranton, NJ"]);

mygrammar.expand("#playerName# left #playerHometown# on an adventure");

A Note: the newest in-progress version of Tracery allows you to pass a world-object to Tracery along with a grammar, so you no longer have to manually update "playerMood", etc, each time the player's mood changes and you want to use it in a piece of generated text. But I don't have an ETA for that.

Seeds: turning commodities into individuals

You'd often want to generate the same content many times in a game. For example, in a text-version of a space game that can generate trillions of planets for you to visit (cough) you might not want to save all the generated tree descriptions, plant descriptions, alien city names, etc. But, if you use some fixed number to set the random seed, you can be certain that Tracery will make the same sequence of "random" choices when picking rules. This will generate the same content, as long as you ask for the content in the same order once you set the seed. For Javascript, I use David Bau's excellent fix. Conveniently, this requires no changes to Tracery, it just modifies JS's random number generator.

This is especially fun if you have some huge number represting an in-game commodity, like the population of your city. You can use the index as your seed: "look at citizen #31992" will set the seed to "31992" and each time, the citizen will be "Margarie Tomlinson, age 45, afraid of spiders".

Further

This may not be as much as your game needs. You may want internal conditionals controlling the grammar's expansion, or more direct tagging control, such as "give me a conversation tagged 'aggressive' and 'evasive'". James Ryan's Expressionist work can do tag-directed generation management to satisfy constraints, and I've heard Emily Short is working on something Tracery-like with tags.

I'm also working to include tags and conditionals in the new Tracery, but we'll see when that ships. Until then, you may get mileage out of the techniques above.

Avatar

10 Mostly Easy Steps To Become An Indie Dev

Of Game Dev and Ukuleles

I saw this post and as much as I disagree with it, I wanted to reflect on what I think would be the 'right' set of steps.

Like the author, I too am often "asked about starting to work on a indie game project by non game-devs"!

I would have very different advice from the author, whose advice seems to be predicated on the question-asker's desire to make the next high-end tactical combat game. That may be true of you (even if so, I think he’s setting you on a road of pain, but that’s another story)

So here are my proposed alternate Easy Steps for People Who Kinda Wanna Make a Game, Maybe?

  1. Accept that you probably won’t make money at this, and that’s ok! Indie development is a job where you work really hard and unpaid for years, then ship your game, and .... still don’t get paid. Yep, even if you buy a really really expensive setup. Indie game development is like going into music. You probably won’t make money with your band, but its a great way to have fun with your friends, and maybe some strangers online will dig your cool niche tracks ("zydeco-flavored jazz dubstep!") and tell you that you make good stuff that makes them happy. They might give you the occasional fiver, and that feels pretty good, too. The alternative is going to work for a "major label" like EA. You get a steady paycheck, but aren't working on your own stuff. Many pro developers still get together with their friends to jam on go-nowhere weekend projects, just like the indies!
  2. Equipment This isn't an "investment", kid. Buying a fancy rig is about as well correlated with success as buying the fanciest guitar in the shop. Much great music has been made on a toy piano or a beater ukelele from the dime store, and many a fine game was made on someone's cheapo ancient laptop.  On the other hand, this is your fun, so buy whatever you want.  If money's no object, drop a few grand on whatever the computational equivalent of Sir Paul's original Gibson is. ("My indie game was developed on Will Wright's original Amiga!")  Otherwise, borrow your Nan's old ThinkPad, and move on.  As my dad says, only upgrade once your equipment is the only thing holding you back.  Don't buy tutorials and assets yet, wait until you know what you want to know.
  3. Pick a starting song to learn: Never coded before? Coded, but never games? There are lots of great free tools.  Pick one that's good for simple games that you could imagine yourself having fun making.  Emphatically do not start with the tool you think you need to make your magnum opus.  We aren't at magnum opus territory yet.  Find the "Hot Cross Buns" or opening licks of Smoke on the Water, something you'd have fun making, but think might even be too easy for you (tip: it's not).   Don't make World of Warcraft, make the "click-to-fish" fishing minigame of World of Warcraft. You ain't gonna ship this to Steam, any more than you're gonna play Hot Cross Buns at Woodstock, so don't worry that your idea is tiny and silly. That's a good thing.
  4. Learn! Find a "Hello "World" tutorial for the platform you've chosen as your "first song". Is it more than a page long? No time for that, find a new one.  Smaaaaaalllest tutorial you can find. Really tiny and stupid.  Great. That one looks good, so read it. OK, STOP, LEARNING TIME IS OVER, NO MORE READING FOR NOW  This is not the time to read music theory, don't get lost in "hot tips for pros", this is the time to program.
  5. Make! Then discover failure! Then overcome failure! Follow the tutorial.  You goal here is to have something on screen that you can interact with.  Along the way, you'll discover all the things that the tutorial is missing, like installing the program or getting it to run on your machine, or which syntax errors will cause it to fail.  Practice having a problem, panicking, stopping panicking, trying out solutions, being patient and forgiving of yourself, and feeling successful when it works We're learning to get past these annoying technical issues when making a tiny stupid program, that way they won't get in your way when you make something bigger. You may find that you just need to pick a different tool for technical reasons.  I've discovered I can't get my hands to do an barred F-chord, now I sometimes use Irish guitar tuning because it's easier on my soft and stumpy fingers, but a ukulele is even easier for me so I've mostly switched to that.
  6. Customize and explore You have a small interactive thing, now, right?  Make it do something very slightly different.  Change the texture.  Put your name on the screen somehow.  Add some music (just some dreadful looping mp3).  Don't try to make any tiny feature very complex of very good, just get it working.  Get each small thing working before starting the next change.  It doesn't even really matter what you're changing, as long as you are practicing of wanting a feature and making that feature real. After a while of this, go back and redo the first few features you've implemented. Did you already forget how? Is it easier this time? Did you figure out a better way to do it?  You'll find yourself improving a little bit each time, getting more familiar with your platform and how it "thinks".
  7. First audience Pick an easy audience.  Your supportive grandpa, or your 3-year-old niece, or a cat.  Your goal is to make them delighted. Got it? They'll probably be happy if you just make some color and noise, but this is practice playing to an audience and getting feedback.  The best ever advice I got in the games industry is to make your small games "love letters" to a single person that you know and love. This gets you out of the feature-creep mode of trying to guess at the desires of the masses, and it helps you be specific.  Grandad likes fishing and WWII, but can't move fast and doesn't play games.  Make him something with very simple, very easy mechanics (maybe a tap on an ipad?) and positive feedback (you want him to feel like he's 'good at games'), and give it a theme that makes it clear that you respect his interests and were thinking fondly of him when making this game.  Your niece likes pink, and seeing her name on a screen, and is still learning cause-and-effect. Maybe make something that does something for everything she does, make it really customized for her with her name splashed over everything. You don't like pink, yourself, but can you make a pink game that you still feel good about it? This is a challenge, but remember that her smiles make you happy, and pink makes her smile.  I don't know what your cat wants. That's your problem, but if you can design for a cat, you're doin' pretty good.  Watch them happily interacting with it. You did this: you helped them be happy.  Feel good feelings.  If they give you feedback or don't like it, listen and be glad that you're learning more about them and what they like. You can make more games later.
  8. Get the band together, or go solo Do you need a team? From your previous game-making mini experiments, you've run into things that you aren't good at doing. For many of these, you've learned to work around them.  Maybe you all your 3D models look like badly-melted G.I.Joes, but you always find ones you like on the asset store, or in Creative Commons collections.  Maybe you have a grand vision that no one else shares ("a game of thousands of scientifically-accurate semi-pixellated mollusks and clams!"), and so you want to find someone else to help.  There are a few options: recruit a friend who has that skill, and hope that their affection for you will make them happy to share your goal ("pixel clams just make him so happy..."). They may have their own ideas they want to add, so you can't treat them as your underling, you may have to be flexible with your ideas, too.  You might also find an online collaborator who is excited about seeing their strange interest shared by someone else ("NautilusJane: just made these new pixelated geoducks gifs, someone anyone plz retweet").  Respect and celebrate their expertise, and use your work to showcase theirs, and they may return the favor.  You can also just go solo.  Make do with what you have, and learn to leverage what you can find.  There's no shame in being a collage artist or a remixer.
  9. Let's have a party Did you know that games can be a social activity? And that your friends support you and like to see what you've been making?  Invite a few of them over to play your game, and have some tacos and other activities for if they want a break from your game.  They may have all sorts of features that they think you should add, and changes you should make.  They might be quite bad at your game. They may say it sucks. They may PLAY IT WRONG. What is wrong with these stupid jerks?  Why did we ever give these losers our tacos and affection? Hold it.  Resist the urge to lecture them about their wrongness. Playtesting is hard, and one of the hardest parts of game development. Let's practice what we're going to say instead: "Thanks, that's very interesting". "Oh, that's very good information".  In a playtest, there is no right or wrong, only interesting.  You may totally disagree with what they say, but try believing that it's a real and true picture of how they feel.  You now have information that this piece of the game makes this person feel like this.  You don't have to change anything, it's just information to add to your information pile.  Maybe no-one ever notices that switch over there in the corner, but you think it looks cooler in the dark shadow.  You can keep it the way you want, but know that many users will still miss it.  You can't argue people into having a different experience.  Make choices accordingly, find your own balance between self-expression and user experience.  At this point, you can try shipping your game. This is "hard mode". Now you have no tacos or social bonds to tempt users to your game, and its even harder to argue them into having fun.  But you can choose where to release it, to find the people that your game will most delight ("Bivalve Retro Gamers Forum: the place for people who love pixels and pteriomorpha!") and who will make you happiest to have as users.  Maybe this is just your twitter followers, maybe you think the big crowds at Steam will like it.  It's just a bigger version of the game party you hosted, warts and complaints and all.
  10. Make yourself happy This is the big one.  There are no right answers here.  There is no official recipe for being an indie dev, any more than there is the right way to make music, no matter what any Gamasutra article or GDC talk will tell you.  If you've gone through these steps, you've discovered some parts that you love, and some parts that made you feel terrible.  Some people genuinely like doing playtesting (those are strange people).  Some like the nervous thrill of releasing to a giant crowd, others like the patient craft of slowly getting better and better at their skills.  Find the part that makes you happy and fulfilled, and build your practice around that. Game Dev Bob Ross has some great advice, but this is a good one: "Remember that with every game you make, you have the power to bring joy and positivity into the world. Let this be your guide."

Bring joy to yourself, maybe bring some joy to others, and jam out with your own beautiful and unique music.

-Kate

Avatar

So you want to build a generator...

This is a beginner-level advice essay for people just getting started with building generators. It's also for practiced experts who want a way to organize their knowledge. The advice is meant for any kind of generators: humorous twitterbots, fanciful art-making bots, level generators, planet builders, makers of music, architecture, poetry, and cocktails. (edit: it turned out to be 4000 words long, so enjoy the ride!)

With so many possible kinds of generators, what advice can I give? Any advice will depend on what kind of generator you want to build. I'll give you a list of questions to ask yourself, and advice to match the possible answers.

The first question is: What are you making?

Write down the thing that your generator will make. We'll refer to this as your "artifact" but it could be anything: procedural birds, generated stories, animated dance choreography, gazpacho recipes, RPG quests, chess variants.

Now the hard part. Inhale, exhale, and start writing down everything you know about what makes one of those successful. What qualities does a good one of those artifacts have? "Funny", "Harmonic", "Playable"? Now go deeper: the more specific the kind of thing you are making, the more specific and detailed you can get with these requirements. What does a "fun" level mean? "Fun" will mean very different things for Super Mario or Civilization or Bejeweled. I can come up with more properties of a good paranormal regency romance novel than I can come up with rules for a good novel. The easiest generators to make are the ones where you can describe "good" artifacts as sets concrete properties.

Now flip the question on its head: what makes a "bad" example of this artifact? List everything you can think of, including properties that are merely unfortunate, and properties that are total deal-breakers. Put a star next to anything that absolutely must not happen. These are your constraints. The most reliable generators are the ones where you can concretely describe constraints.

You now have a list of desirable properties and constraints that you want and don't want for your artifacts. We want a generator with a possibility space (all the kinds of artifacts it can generate) where most of the artifacts have the good properties, and few (or none) of the artifacts have bad properties. We'll also want a range of artifacts, not just the same perfect artifact over and over and over, though how wide a range that is is a choice for you, the designer (a problem identified by Gillian Smith and being explored by Michael Cook).

Now we have the guidance we need to start building methods that make artifacts.

An alternative approach: the previously described method is good for inflexible situations, where you know ahead of time what you want to build. For many situations, like game jams or prototypes or side projects, you can be more flexible and improvisational! You can start with a methods or some loose pieces to figure out what it 'wants' to generate (what properties is it best at generating?) and then revising what artifacts you are generating to better suit what the generator is good at making. I talk more about this approach in my 2015 Procjam talk.

Building Your Artist-in-a-Box

When the Spore editors were being designed, the engineers, designers worked closely with the art team to understand how an artist or an animator would go about sculpting and texturing a creature. If they could understand the process and design an algorithm that could follow that process on demand, they would have an "Artist-in-a-box" that could make procedurally generated creatures that would be nearly as good as the original animator would have made. Designer Chaim Gingold explained this process in his 2007 GDC talk audio slides and Art Director Ocean Quigley used a similar process to experiment with what kinds of building blocks he would want for building cities

It is helpful when making a generator to sit down with someone who makes the sort of artifacts you are building, and have them walk you through the process of making something. What questions do they ask themselves along the way? How do they make decisions? How do they describe the tradeoffs between choices? How do they describe the different problems that they have to keep in mind? How do they name all the parts of what they are working on, and all the relationships between them? (the academic term for this is an "ontology")

Some fields have expert practitioners who have written frameworks, often controversial, to describe what they do. Music theory has proposed plenty of rule systems, for example, for jazz improvisation or Bach-style harmonies or pop songs. Story generation has narratological theories like The Hero's Journey, but also informal frameworks like TV Tropes. Art theory has the Golden Ratio and color harmonies and composition rules (I haven't found those visual aesthetic rules to be productive in my own work, though you may feel differently). No framework is complete, or makes provable good artifacts, but they can help give you guidance and inspiration.

So now, ask yourself: How would a human solve this problem?

From rules to generative methods

Unfortunately, knowing how a human would make something isn't the same as being able to teach a computer how to do it. Humans are good at estimation, and making guesses, and synthesizing a lot of knowledge about past situations. Computers know only what you tell them, and many problems require way more implicit knowledge than we think, but they are good at performing lots of calculations and trying out lots of possibilities. So the methods we want to use will need to provide a way for the computer to solve problems like a human, or at least with a way to mirror some of the skills of a human. Methods that are particularly good for building generators (generative methods) will give the computer some of the following skills:

  • Encapsulate knowledge of options (skill A)
  • Create some structure (skill B)
  • Encode conditional rules for options (A2)
  • Create variability in structure (B2)
  • Be able to ask itself questions about its constraints (have I solved this?) (skill C)

Distribution

This is the easiest kind of generative method. You have a bag of stuff and an area of space or time that you can spread them out across. Distribution methods usually don't have much overall structure (B), but they are often very sophisticated with the odds of picking each option (A). Some use weighted randomness to change the distribution percentages, or 'deck shuffling' (putting all the options in a stack and discarding when they are used), which prevents accidentally picking the same option twice. The conditional rules (A2) can get quite complex as well, but specifying arbitrary conditions is difficult to implement in practice. Most systems have carefully chosen parameters that can be set for each option and the conditional functions can just look compare the fixed parameters to make choices.

For an RPG example, wandering monsters are distributed around the environment (A). Higher monsters are found in higher level areas, water monsters in water, etc (A2). There may be a little structure to how they are distributed, like several 'baby' versions of a monster leading up to the 'boss' version. Loot is also distributed: you may be more likely to get high level loot in high level situations (A2) but there's still some randomly selected stuff chosen from a big list of possible loots (A).

Distribution in music and language doesn't work well. Randomly selected strings of words or musical notes don't have enough structure to make interesting meaning. For structure-heavy artifacts, you might want tile-based or grammar-based methods instead, or for something with very fixed structure and not much variability you could try the Parametric approach.

Parametric methods

You have a pretty well-built artifact already, and you know that you can tweak it a little. You have music, and you can transpose it up or down, make it louder or softer. You have a teapot, and you can make the spout curve out farther, you can make the body tall or short, thin or fat, and you can make the base wide or narrow. You have a set of hand-made alien creatures, and you can tweak their legs to be long, fat, curved, or flat-footed, and their bellies to be slender or barrel-shaped, and this changes their voice as well. This is how creatures in "No Man's Sky" are varied. This is a very reliable and controllable technology! For 3D models, can often be encoded as a Maya animation channel, allowing it to blend with other animations (a Spore trick used in the rig-block animations). But your variability (A) is only along fixed one-dimensional numerical paths, there is no structure variability at all (B2). You can see something "new", but never something surprising.

A more sophisticated form of parametric methods uses other forms of input, and can generate new artifacts based not only numerical, but also point-based, path-based and graph-based input. When you draw a line in Photoshop with a tablet pen, your path becomes the input to an algorithm that renders a brushstroke, taking into account pressure, speed, and tilt as parameters at each point. The Spore creatures, likewise, used Metaballs, a geometry creation algorithm that could create smooth tubes along paths in 3D space. Other algorithms for filling spaces and paths are Voronoi patterns, Perlin/Simplex noise, triangulation algorithms, 3D extrusion or rotation, and the Diamond-square algorithm for fractal terrain. These algorithms are particularly well-suited for interactive generators, because the user can provide the input parameters for the generator.

Want more? Inconvergent.net has more intriguing specimens of these than you could possibly ever need, with open-source implementations.

However, though these algorithms are delightfully surprising, they can often be too uncontrollable to provide the constraint-satisfaction needed for gameplay or other highly-constrained artifacts.

Tile-based

Chop the problem up into modular, identically-sized slots. Have a number of different hand-made solutions that can fill in these slots. The artifacts being created are just differently-selected-or-ordered sets of pre-authored solutions. A familiar example of this is the board layout for games like Settlers of Catan and Betrayal at the House on the Hill (or Civilization for a digital example). The island, and the mansion, are constructed from the same tiles each time, but laid out differently, which changes the gameplay. Some of the earliest forms of generative content I've found are the Musikalisches Würfelspiel from 1750s and earlier, with which pianists could put together "tiles" (in this case: measures) of music to produce a playable waltz.

Tile-based methods are great for small-scale structure (B) because the insides of the tile are pre-authored, but they have no flexibility (B2) for small-scale structure for the same reason. Large scale structure is harder to control: it can be totally random. There can be more advanced constraints about which tiles can go next to other tiles but then you may need a complex algorithm to solve for compatible layouts of highly-constrained tiles ("The beach tile can go next to a jungle tile, but cannot be within two tiles of a river tile and....."). Individual tiles have a very rigid encapsulation of possible options (A), because each possible tile has to be authored by a human. These systems don't have enough knowledge to come up with good new tiles by themselves. Tile-based methods work for problems that can be broken-up into small chunks where internal structure matters, but that can still create interesting (but not constraint-breaking) behavior when combined in different orders.

Interested in more analog content generation? Additional forms of boardgame and role-playing-game content generation can be found in this paper by Gillian Smith, and this exploration of comics by Chris Martens

Grammars

Grammars are one of my favorite generative methods, because I find that they give me a great way to make very deep and complicated structures while still also having a lot of control over my options. Grammars are a computer-sciency way of saying that big complex things are made out of other things, and those other things may themselves be made out of even smaller simpler things. Orteil's Nested is a lovely example of this. The universe is made of galaxies made of planets made of continents full of people who are full of thoughts and dreams and memories and atoms. Each symbol (that is, a type of thing) has a distribution of sub-symbols that it might be composed of. When it "unpacks" it has to pick one of those options (and any subsymbols then unpack recursively). Grammars make it easy to encode knowledge about a particular artifact and its structure and its options all in one piece of data. I like them so much I made a library to help people work with them, Tracery. This has been used to make a twitterbot hosting service and lots of great weird creative twitterbots including some of my own.

The downside of grammars is that they do not have a way to handle constraints, unless the constraints are implicitly encoded in the grammars themselves (if a bed can only be in a house, than only the house can have a bed as a sub-child, for example). It's harder for grammars to encode high level relationships between different things generated at different points in the grammar. If you wanted to have foreshadowing of the villain's death at the very beginning of the grammar, that might be difficult to do, and you might want to use the 'big hammer' of a constraint-solver.

Constraint solvers

Constraint solvers are very powerful, very recent tools in our generative arsenal. They are what you use when you have a lot of hard constraints, a lot of flexible and complex structure, but you don't know how to build out the structure in a way that will be sure to solve your constraints.

The oldest simplest version of this is brute force solving. Make every possible variant of content, toggle every switch, make an alternative universe where you have made each different decision, and test your constraints until you find one that works. This is a viable solution for some problems! But as any mathematician will tell you, too many choices will create a number of possible artifacts to search that is greater than the number of atoms in the universe. And that's going to be slow.

There are often shortcuts you can take, depending on how your constraints are structured (I don't have to choose an ice-cream flavor in possible futures where I did not go out for ice cream). But this takes a long time to author by hand (just ask the Storyteller developer).

Fortunately, many mathematicians and logicians find it amusing to try to solve this problem, and they have come up with general purpose solvers. Plug in your constraints and structure and options (in a language that it can understand) and it will find all the cheap shortcuts to cut the aeons of brute-force solver time down to something slow but accomplishable within normal gameplay time.

Because these tools are big and bulky and new, they are still hard to plug into many game engines, and there aren't many tutorials. Adam Smith has been doing good educational outreach for Answer Set Solving, a particularly powerful one. Another one with some support is Craft by Ian Horswill, a constrained random number generator, that has been recently ported to javascript. Look for these rare but powerful methods to be more common in the future!

Agents and Simulations

This is where it gets weird. Remember how I said that we could look at how humans solve problems to provide inspiration for our generators?

Guess what: humans aren't the only ones who solve problems

There are algorithms that solve problems based on the colonial behaviors of ants, or the social communications of fireflies. Many other agents and simulations take inspiration from other parts of nature, like flocks of birds, evolution, bacteria, neurons and cities. Here are a few of my favorites, but there are many more.

Steering behaviors (these deserve their own long post some day) can create remarkably complex crowd motion. Braitenberg vehicles were originally a thought experiment about simple machines with two photosensitive eyes and two wheels that could 'steer' themselves just by activating one wheel more than the other, applying an asymmetrical force that changes their direction. Despite their total brainlessness, they can show 'fear' and 'adventure' and have been ported to many languages and physical robots.

Boids took the steering approach of the Braitenberg vehicles and applied it to flocks of birds and fish (and the wildebeest in the Lion King animated movie). Each bird helps keeps its flock in shape by calculating applying its own forces for cohesion, alignment and separation. Small variations in the each birds's tuning values can generate new behavior for the flock.

I've also used steering forces to generate procedural dance: you just replace the flocking forces with rhythmic forces in time to the music paper. Steering forces can do a lot more than pathfinding, but I don't think they haven't yet been explored to their full potential.

Genetic algorithms, as can be seen in my flower-evolving app aren't methods to generate content, you still need a generator (a flower generator in this case). But they are a way to guide that generator towards more constraint-fulfilling and desirable-property-producing content. A genetic algorithm (which, yes, needs its own post), needs three things:

  • A thing you can modify (a 'genotype')
  • A thing you can judge (a 'phenotype')
  • A way to turn the first into the second

For the flowers, the genotype is an array of floats. That array gets fed into a parametric generator to create a pretty animated flower (turning genotype to phenotype). The user can see which flowers they like (a judgable phenotype). They pick their favorite, it's original genotype is cloned and mutated (a thing you can modify, remember?) and the next generation is born from its mutant babies, and overtime, evolution happens. Sexual reproduction is common in GAs, but so are many other interesting kinds of reproductions and metaheuristics. There's a lot of neat research in this area!

Cellular automata rely on many very simple agents, all working in parallel. The canonical example of this is Conway's Game of Life, in which many tiny automata in a grid, each with a very simple behavior, can give rise to so many strange behaviors and phenomena that many mathematicians make a hobby of discovering and cataloging them.

Cellular automata with more complex rules are used to create Dwarf Fortress, the classic Powder game, and with the advent of voxel-based simulation, are taking on a new life as the engine behind Minecraft

After you generate...

You've browsed this list of generative methods, you've got your list of constraints and properties in hand, and you've built your generator!

Now what?

Ways that generators fail

Something has gone horribly wrong. The content looks ugly. The content all looks the same. The content looks like genitalia. The content is broken. Some of these problems are easier to solve than others. Here are a few kinds of difficult problems you will encounter.

One will be the kind where you can computationally identify when something is going wrong. The solution to this one is to generate some new content until this constraint is no longer violated. Perhaps you want a generated chair to have its center of gravity over its support points (like legs), so it won't fall over. This is possible to calculate with a physics simulation, so if the generated chair fails, generate a new one until it passes. This approach is called "generate and test".

What can go wrong with "generate and test": what if every chair you generate fails this test? Perhaps content that passes the test is very rare. Or there are too many constraints, if you have constraints for material thickness and cost and symmetry and comfort and more? Each chair might satisfy most constraints, but with enough constraints, most chairs will still fail one or two. Maybe you need a constraint solver. Or maybe you need to restrict your generator so that it is more conservative with its choices, though that may lose interesting possibility space.

Another difficult constraint is when you cannot adequately describe your constraints. This is a remarkably common situation, because there are so many things that we don't want but can't write rules that "I know it when I see it" can be used as a serious legal argument.

Is this an offensive adjective to use to describe this character? Does this color palette look too much like a corporate logo? Does this look like genitalia? Is this just... ugly? This is a hard and unsolved problem, I'm afraid. If you can't define "bad" content, it becomes impossible to filter, especially when your human users are trying to get around the detection algorithm. In this case, the best path is to construct an generator such that it is harder or less-likely to make offensive content. This also restricts your possibility space, like removing words that are harmless and useful unless combined in a particular way.

Aesthetics: the toughest challenge

The most common way that generators fail is that they produce content that fails to be interesting. What is "interesting"? That depends on the situation. Very few generators produce only one of a thing. Most generate multiples, but a twitterbot posting every hour will generate more content than a novel-generator outputing one novel every NaNoGenMo. So achieving novelty with the first Twitterbot will be more difficult because there are so many artifacts being produced that any given one of them will probably start seeming less special.

So your algorithm may generate 18,446,744,073,709,551,616 planets. They may each be subtly different, but as they player is exploring them rapidly, will they be perceived as different? I like to call this problem the 10,000 Bowls of Oatmeal problem. I can easily generate 10,000 bowls of plain oatmeal, with each oat being in a different position and different orientation, and mathematically speaking they will all be completely unique. But the user will likely just see a lot of oatmeal. Perceptual uniqueness is the real metric, and it's darn tough.

In some situations, just perceptual differentiation is enough, and an easier bar to clear. Perceptual differentiation is the feeling that this piece of content is not identical to the last. A user glancing at a line of trees can tell if they are identical, or if they are less-varied-than-expected suggesting unnaturalness. This fulfills an aesthetic need even if no tree is particularly memorable.

Perceptual uniqueness is much more difficult. It is the difference between being an actor being a face in a crowd scene and a character that is memorable. Does each artifact have a distinct personality? That may be too much to ask, and too many for any user to remember distinctly. Not everyone can be a main character. Instead many artifacts can drab background noise, highlighting the few characterful artifacts.

Characterful artifacts is another blog post for another time, but certain aesthetic principles create objects with readable meanings for human perception. Humans seem to like perceiving evidence of process and forces, like the pushed up soil at the base of a tree, or the grass growing in the shelter of a gravestone. These structurally-generated subtleties suggest to us that there is an alive world behind this object. Kevin Lynch's influential "Image of the City" demonstrates that there are factors that make cities memorable and describable. Perhaps there are other aesthetic rules that we can discover, too.

Conclusions:

Oh, my, this turned into a monster of a blog post. It's probably full of errors and omissions, but I hope it will be of use to you.

If you want to begin playing with generativity right away, here are some great tools to get your feet wet:

Want to learn more? Or meet like-minded people?

I'll be on Twitter, @galaxykate, to answer further questions, hear about typos, and take feedback

Avatar

Casual Creators: a roadmap

Welcome to my dissertation blog! It’s gonna be a thrilling couple of months as this comes together.

What are Casual Creators, and why am I studying them? They're a genre of software (well, usually software) that is designed to make casual users feel creative. Apps like Let's Create Pottery, or in-game editors like the Spore Creature Creator help everyday novice users make great stuff that otherwise would take a lot of training and skill to make. I'm also interested in how these apps also help users share what they've made, and how users use their creations to communicate with others. The diagram above shows some of the many different ways these systems can work. They often have a generator as central part, like many computational creativity systems. A well-built generator can enable all kinds of other interaction, between art-generating bots, humans, and communities, which is why I'm starting my blog with this image. It shows Casual Creators as an ecosystem of interconnected parts, not just a monolithic content generator.

I hope you will find this area of study useful to you!

To conclude this first post, here's my official academic definition of casual creators:

A Casual Creator is an interactive system that encourages the fast, confident, and pleasurable exploration of a possibility space, resulting in the creation or discovery of surprising new artifacts that bring feelings pride, ownership, and creativity to the users that make them.

Sponsored

You are using an unsupported browser and things might not work as intended. Please make sure you're using the latest version of Chrome, Firefox, Safari, or Edge.