Grammar Playground

An easy to use tool for hand-authoring procedural generators.

How to Use

The top pane contains the grammar. Grammars are made up of rules. Rules have a head and body.

GRAMMAR
1[head] -> body

Rules are always written inside square brackets [like this] and the simplest body is text in quotes "Some text". Rules have an arrow -> that links the head to the body, indicating the head side will be transformed into the body side. This might all sound abstract so here’s a simple example.

GRAMMAR
1[start] -> "Hello World"

If you paste that in to the grammar box and press the Generate button; it will put “Hello World” in the output. Not a super interesting grammar :D

Grammars can have choices.

GRAMMAR
1[start] -> "Hello World" | "Hello 世界"

In this case, if you press the Generate button a few times you’ll see one of these two “Hello World” texts appear. The pipe character | separates the two choices, so it’s saying “This choice” OR “This choice”. Can you guess how you might add a third Hello World? Maybe a Korean version “Hello 세계”.

That’s right, another |.

GRAMMAR
1[start] -> "Hello World" | "Hello 世界" | "Hello 세계"

Press Generate a few times and you’ll see each piece of text appear in the output. So this is interesting but not amazingly useful yet.

Rules can call other rules. Let’s add another rule [greeting] -> "Hi" | "Hello". Again, guess how you could extend the current grammar to introduce a rule like this.

GRAMMAR
1[greeting] -> "Hi" | "Hello"2[start] -> [greeting] " World" | [greeting] " 世界" | [greeting] " 세계"

The grammar calls the “[start]” rule to begin with. The parser evaluates this rule and sees that it has three possible choices separated by |. It selects one of these choices, then evaluates any rules referenced inside it. A single run results in a random output that could be any of:

Hi World
Hi 世界
Hi 세계
Hello World
Hello 世界
Hello 세계

Let’s make one last change to this grammar, just for fun.

GRAMMAR
1[greeting] -> "Hi" | "Hello"2[world] -> " World" | " 世界" | " 세계"3[start] -> [greeting] [world] | [greeting] [world] | [greeting] [world]

That’s basically it and it might look like a toy but you can make some interesting procedural generators from these simple grammar based rules. The language is kept purposefully restrained (if you want a full rules-based language, you end up with Prolog).

Sharing

You can share your grammar by pressing Copy Link and then sharing that link. The link encodes the grammar in the url and it’ll work for quite big grammars but it won’t work for extremely big grammars, like if you tried to encode a telephone book.

Here’s a link that has a terrible poem generator embedded in it.

Advanced Features

There are more advanced features but by now, you know enough to start playing around, so please do a bit of that first!

Grammars can have comments, use #.

GRAMMAR
1# Oh yeh, there's comment support too2[start] -> "The man stands before you. And makes a gesture; [gesture]"3[gesture] -> 4    "a hand raised high, with an open palm - a sign of peace." | 5    "a finger pointing to the ground, eyes closed - a sign of penitence." |6    "the horns - the sign of the beast" @0.1 7

Alternatives are picked at random and all are equally likely to be picked.

But you can tip the scale; a trailing @2 weights an alternative. @2 means a choice is twice as likely to be picked, and @0.5 means half as likely.

Escape Codes

There are also a few escape codes:

  • \" for a quote
  • \n for a newline
  • \\ escape the escape
  • \[ a left square bracket

Rules can Go Directly in Strings

Text goes in "quotes", and"""triple quotes""" are literal instead - quotes, brackets and line breaks all count as themselves with no escaping, and nothing inside is treated as a rule. Rules can also go inside normal strings and be expanded.

GRAMMAR
1[cool] -> "Cool"2[start] -> "You can embed rules directly in the quote. [cool]!"

Destructive Picking

You can also do a “destructive” pick, while the rule is being run, a pick from a sub-rule cannot be repeated. i.e.

GRAMMAR
1[fruit] -> "an apple" | "a banana" | "an orange"2[bowl-1] -> "A bowl with " [fruit!] " " [fruit!] " and " [fruit!]3[bowl-2] -> "A bowl with " [fruit!] " " [fruit!] " and " [fruit!]4[start] -> [bowl-1] "\n" [bowl-2]

This will give “A bowl with an apple, an orange and a banana” twice with the order of the fruits mixed up but each individual fruit only appearing once. This only applies to the top level choices of the sub-rule.

The grammar will error out if you keeping picking after all options are exhausted.

Example Grammars

Here are a few grammars as examples but this isn’t exhaustive, I’m sure if you’re reading you’ll be able to come up with something more creative than me.

Space Pirate Crew

Let’s start with the classic “Space Pirate”.

GRAMMAR
1[start] -> "Name: " [name] " | Role: " [role]" |  Species: " [species]2[role] -> "Captain" | "Gunner" | "Helmsman" | "Engineer" | "Brawler" | "Cook" | "Cabin Boy" | "First Mate"3[species] -> "Human" | "Robot" | "Mutant" | "Sentient " [animal] | [animal] "-Man"4[animal] -> "Dog" | "Cat" | "Parrot" | "Octopus"5[name] -> [pirate-pre] " " [pirate-noun] | [color] " " [pirate-noun]6[pirate-noun] -> "Beard" | "Hand" | "Tooth" | "Hat" | "Eye" | "Cow" | "Fox"7[pirate-pre] -> "Sea" | "Sky" | "Hook" | "Crust" | "Three" | "Slow" | "Fast" | "Long" | "Star" | "Space" | "Nova"8[color]-> "Red" | "Black" | "Silver" | "Grey" | "White"

Which gives us this motley, rather engineer-heavy, crew:

Name: Crust Eye | Role: Cabin Boy |  Species: Human
Name: Grey Tooth | Role: Engineer |  Species: Robot
Name: Grey Beard | Role: Engineer |  Species: Parrot-Man
Name: Sky Cow | Role: Brawler |  Species: Human
Name: Silver Eye | Role: Helmsman |  Species: Sentient Octopus
Name: Space Beard | Role: Gunner |  Species: Human
Name: Crust Fox | Role: Engineer |  Species: Sentient Octopus

What’s in the Chest?

Generators are great for filling things up.

GRAMMAR
1[start] -> "With both hands you push open the lid of the " [chest-descriptor] " chest and you find: " [item!] ", " [item!] " and " [item!] "."2[chest-descriptor] -> "old" | "grimy" | "weathered" | "ancient"3[some] ->  "2" | "3" | "4" | "5" | "6"4[gold-pieces] -> [some] " gold pieces" | "a handful of gold coins" | "a single dirty gold coin"@0.5 | "an ancient gold coin"@0.55[odds] -> "a blackened mummified hand" | "a basalt cobra statue" | "[some] human teeth" | "a palm-sized crystal pyramid" | "a tiny skeleton of an unknown creature" | "an old book, that feels cold to the touch" | "spectacles with emerald lenses" | "a bag of soot"6[weapon] -> "a shortsword" | "an emerald dagger" | "a halfsword, pitted with rust" | "a thin black-bladed dagger" | "a heavy looking mace" | "a wood club, decorated with red bands"7[gemstone] -> "ruby" | "emerald" | "pearl" | "diamond"8[gemstones] -> "rubies" | "emeralds" | "pearls" | "diamonds"9[treasure] -> "a single " [gemstone] | [some] " " [gemstones] | "a golden necklace" | "an amulet"1011[item] -> [odds] | [gold-pieces] | [weapon] | [treasure]

and that’ll give you some chest contents

With both hands you push open the lid of the grimy chest and you find: a heavy looking mace, 4 gold pieces and a palm-sized crystal pyramid.
With both hands you push open the lid of the old chest and you find: a tiny skeleton of an unknown creature, a handful of gold coins and a golden necklace.

Some ASCII Rugs of Unbounded Length

Tell me if you find a use for this one!

GRAMMAR
1[start] -> "[p1]\n[start]" @8 | "[p1]"2[p1] -> "██[p2]██" | "▓▓[p2]▓▓" | "░░[p2]░░"3[p2] -> "█[p3]█" | "▒[p3]▒" | [p3]·"4[p3] -> "█[p4]█" | "░[p4]░" | [p4]·"5[p4] -> "··█··" | "·▓▓▓·" | "██·██" | "·░·░·"

Gives these pretty “rugs”, here are two:

██·███·███·██
▓▓▒█··█··█▒▓▓
░░▒···█···▒░░
██▒░··█··░▒██
▓▓████·████▓▓
▓▓▒░··█··░▒▓▓
▓▓·█·░·░·█·▓▓
░░▒█·▓▓▓·█▒░░
▓▓█░██·██░█▓▓
██▒░·▓▓▓·░▒██
███··░·░··███
░░▒·██·██·▒░░
██▒░··█··░▒██
░░█░██·██░█░░

Random Grammar Inspiration

A fun one, might be to get the names from the Domesday Book, an English census from 1086, with 13,000 names and create a random generator for English names circa 1000 A.D. If you have a book or RPG setting and want medieval names; there you go - press Generate a few times until you find one you like. You could also split it by gender or region maybe even social class, if you could get the data.

You can also create a generator for every possible four letter word pretty easily. Though you might want to limit it to common vowel-consonant patterns or you’re going to get a lot of “words” that look like nhgy or jhyp.

If you collect a lot of names, you start to see little clusters of letters and they make good points to break-up the word. You can then turn these fragments into a grammar or even use as a basis for your own conlang. Let’s choose some names: Daniel, Nathaniel, Gabriel, Ariel, so there’s a split point [name-start] -> "Dan" | "Nathan" | "Gabr" | "Ar" are there some names that could be broken down in a similar way? Then what might happen if we mixed them up?

You can also play with structured output; like you can generate a random .obj or .xml or .html or the scene file for your favourite game engine. Anything plain text can now be randomised (that includes generate grammars).

Your imagination is the limit!

Secrets

Well done for reading to the end, as a reward here are some secret rules. There are a couple of additional built-in rules:

  • Simple dice rolls of the form [numDice]d[numFaces] like [1d6]
  • Ranges [2..22]
  • [a] will transform into a or an as appropriate

Go have fun, if you make an interesting grammar share it with me!


← All Sparks