The incredible power of procedural content generation

Its quite a while since my last post, and lots of stuff happened inbetween. Founded an indie-game studio together with a friend. We produced and published our first game and are now working on the second.

While the first game was more a proof to ourselves that we are able to do a complete development cycle, beginning from scratch up to finalizing and publishing it – the second one is now getting into more interesting realms.
I was always quite fascinated from procedural content generation (PCG) in general, and some of the fruits of my early experiments are shown in some older posts here.

The new project is making heavy use of some PCG techniques. Namely map generation and word/sentence generators. While both are often used and well known, i wanted to go a bit further and test out some ideas.
The main issue during out last game was that our Designer created game-content like texts and stats/balance – i had to hardcode them into the scripts. This was a bad aproach cause it basicly doubled the time needed for it.
Now i tried to develop some tools to outsource this data from the game. This not only allows for a quicked development but also makes the game moddable. I chose XML for this, cause its rather easy to use complex data-structures with it, without the need to re-invent the wheel with developing our own data-formats (and scripting exporter/importer algorithms).

Now, you may wonder what this have to do with PCG.
Well, lets take as example the word/sentence Generator:

Word / Sentence Generator

Generators like that work quite simple. Lets say we want to come up with a bunch of names that all sound nordic. An easy way to do this is to analyze nordic names and get a list of syllables that make up those names.
A simple formula would be: Beginning syllable + middle syllable + ending syllable = name

Depending on the data for those syllables you can produce a large amount of names that all sound quite believable.

Alffdanr Jakobhjalsen, Aris Rasberg, Fenrir Sorenhauser, Svadildorr Leonbak, Gudnarr Leonhaugen, Sleipbrandr Herhjallum, Fentoppr Hagerickbak, Hallki Skjeggeardgen

A more complex example would be descriptions for items, or book-descriptions. Basicly you try to make up rules that tell how the sentence is made up of different pieces. In general its the same concept like with the names, just more complex.
After developing the base concepts of this generator i tested it with setting up a simple sentence for a book-review. The output is something like the following:

This roll published by Alfris Hauthonvik  is muddled mostly due to uninspiring features.
This writing is totally senseless mostly due to the totally lack of content.
This writing from the known writer Eijotr Lundgen  is very easy to understand despite the really great crafted content.
This atlas is reasonable clear thanks to the very great done organization.
This book is totally senseless.
This work written by the well known writer Hallfrodr Harbak  is interesting.
This text from the writer Ganfari Sorenrickvik  is hard to understand thanks to the totally uninspiring diagrams.
This book published by the unknown writer Favnir Anter  is quite clear.

The quality of the sentences differs, sometimes its coming up with strange or amuzing curiositys, but in most cases it already giving pretty good results.

Now the great part about this is that both examples are done with the same generator. To be able to allow this i came up with a simply ruleset wich you describe in XMLs.

An example XML dataset looks like this:

<TextGen description=”Dwarven Name”>
<iD>#DWARVNAME#</iD>
<rule>       <string>A,Ba,Bi,Bo,Bom,Da,Do,Du,Dwa,Fa,Fi,Fre,Fun,Ki,Lo,Na,O,Tel,Tho,Thra,:100</string> <string>za,:10</string>
<string>bur,char,fur,ghal,in,li,lin,mil,ni,ri,rin,un,vi,:100</string>
</rule>
</TextGen>

This ruleset have an ID wich is used to reference this specific rule (#DWARVNAME#), and it have a list of rules wich are basicly strings that hold a number of elements, each seperated by a commata.
Those strings get parsed by the engine to “deconstruct” the rules and get the seperated elements. I mainly did this to avoid unneccesary complex XML structures. The number at the end of each rule is describing the chance that this rule gets applied at all.
This simple trick already allows for quite some variations.

Instead of all the time having 3 syllables added together, its easy to describe a ruleset here wich often only uses 2 syllables, but sometimes uses 3.
The above ruleset could output names like:

Bomli, Thrazamil, Aghal etc…

Another quite important thing is the option to reference other rules in those elements. To seperate normal content and rule-references correctly i suspect that each rule-ID is beginning with a # sign.
The process of generating the final words/sentences is recursiv. It would be of course quite easy now to “script” infinite loops”. To avoid this i count the number of recursion steps the algorithm takes, and just break out if i get over a hardcoded limit.

The last thing i implemented for now is the option to save the output of a generator in a variable and be able to use that variable in the rules.

With this simple setup we are already able to make up quite some complex generators for different use. Again some example:

<TextGen description=”Dwarv pseudo text”>
<iD>#TEST1#</iD>
<rule>
<string>#DWARVNAME_FULL#,:100</string>
<string>!1,:100</string>
<string>#DWARVNAME_FULL#,:100</string>
<string>!2,:100</string>
<string>A ,:100</string>                <!– here we begin actually building the text –>
<string>small ,ugly ,tiny ,crude ,greedy ,funny ,:50</string>
<string>dwarf ,guy ,person ,:100</string>
<string>called ,named ,known as ,with the name ,:100</string>
<string>?1,:100</string>
<string> met a , was a friend of , travelled together with ,:100</string>
<string>a person , someone ,a guy ,:100</string>
<string>called ,named ,known as ,with the name ,:100</string>
<string>?2,:100</string>
<string>. ,:100</string>;
</rule>
</TextGen>

The special new functionality here is the command !1 and ?1, wich basicly saves and loads into the variable slot 1. Currently i am providing 20 slots wich should be more than enough for quite some complex setups. They can be also used to pass things from within the game, so it would be quite easy to construct sentences that mention the name of the player for example.
The above example isnt the complete ruleset, i am calling the ruleset #DWARVNAME_FULL#, saving the output in slot1, calling it again (and getting another result), saving that in slot2, after this basic setup i begin to construct the simple sentence. This is just an example i wrote for our game-designer to show off how all elements are working together – its not used in the actual game.
With this simple tool, the players could mod their own name-variants, item-descriptions and so on. At the moment its more a proof of concept and still in early experimentation phase, so we havent decided how its actually linked to the game and how much freedom we give to players in respect to modding.

Well, enough text for today, stay tuned for more insights into our use of PCG techniques for our new game.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s