Gamasutra is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Gamasutra: The Art & Business of Making Gamesspacer
Procedural Content Generation: Thinking With Modules
View All     RSS
June 20, 2019
arrowPress Releases
June 20, 2019
Games Press
View All     RSS
If you enjoy reading this site, you might also want to check out these UBM Tech sites:


 

Procedural Content Generation: Thinking With Modules

by  [Design, Indie]

July 18, 2012 Article Start Previous Page 3 of 5 Next
 

PCG is a Panacea That Will Cure Leprosy

Our next title, Ugly Baby, would play much like Aaaaa!, but we wanted it to generate all of its level structure algorithmically, at runtime, based on player-supplied media. This media could be anything from music, a la Audiosurf or Beat Hazard, to a video to a block of the Declaration of Independence. We describe the game like this:

"Battle your favorite drum 'n' bass track, or relax as you fly through that trance album. 'Ugly Baby' takes your MP3 music and creates floating worlds for you to fight through."

Our hopes were (and still are) that PCG would allow us to:

  • Generate (essentially) an infinite number of interesting levels that were more distinct than the hand-generated ones in Aaaaa!
  • Generate all level content at runtime based on the player's own media.
  • Allow players to participate in the world creation process by tweaking "level DNA" and "growing" their own levels.

We wanted to create scripts that read in the music and spat out Aaaaa!-like levels with enemies, figuring that our understanding of floating architecture and generative art would make it simple. As it happened, a nine-month project turned into 24 months before we even began to get our footing.

We ended up hitting four major problems:

1. Manual creation's strengths are PCG's weaknesses.

Algorithms and hand-created content often have complementary strengths. Algorithms can beat hand-tweaking if you have an enormous mountain and want to see what happens if it undergoes erosion. While you could easily spend an entire day sculpting it by hand, running it through an erosion tool will take moments, and allow you to try different things.

On the other hand, if you want to add a few trees around the entrance to a cave, it's usually easier to just plop a few down by hand and nudge them around than to script that. If you want to carve the world "HELP" in a beach, it's easier to just select a tool and draw the word. We learned this the hard way, through this process:

  • STEP 1: Create an algorithm that generates a level skeleton. (1 hour)
  • STEP 2: Test to determine that the buildings are too far apart; increase the density but finagle it so that they don't overlap. (15 minutes)
  • STEP 3: Test to determine that that didn't work at all; skew the path so that the buildings weaver a bit. (15 minutes)
  • STEPS 4-9: Rinse, repeat. (15 minutes apiece.)
  • STEP 10: Curse that the approach isn't working, when it would be so easy to tweak by hand. (5 minutes.)

So, we'd get into a mode where we created a promising script, tweaked endlessly, and hit a local maximum: the initial script would establish a certain type of level layout, and we'd spend hours exploring the best permutations of that rather than looking elsewhere. We'd later find that the distance between "not fun" and "fun" was small. But it can be time-consuming to experiment with an algorithm or to augment it to include interesting details.

Solution: experimentation is sometimes best done by hand; we can then learn from what we create, then have the algorithm mimic something that turns out looking good.

2. It's easy to create repetitive content.

We'll borrow a quote from Alex Norton's AltDevBlogADay post:

Why have world borders at all? Procedural generation code hasn’t changed much in the last 25 years. People are still stuck using fractals and diamonds and blobs to do everything, which becomes repetitive and quite simply looks like procedurally generated content. To any programmer looking at it, it virtually smells of procedural generation.

If we're not careful, we see the same stuff over and over again. For example, in Ugly Baby, either of the below levels is interesting for about 15 seconds, after which point they become tedious:

Since levels were each about 5 minutes long, that meant we'd want to switch things up a few dozen times over the course of a level. One common solution is to swap out different algorithms periodically, but that can be jarring -- imagine a PCG forest that ended sharply on a boundary. Another is to augment the algorithm with tidbits of new stuff along the way, and gradually morph between things, but we ran into problems with complexity, as we touch on in the next point.

3. As PCG algorithms become more expressive, they seem to become disproportionately more complex to design.

It's really easy to create an algorithm that generates a simple level -- but as we made things more complex, implementation became disproportionately more difficult. For example, in Ugly Baby, we had early success creating a script that scattered buildings around a map. However, augmenting that resulted in this internal conversation:

"That looks great; what happens if we group those in clusters?"

"Okay, but they're now too regular. Mix them up a bit."

"Let's add some scoring plates, tunnels, moving platforms, and fan blades."

"Oops, the scoring plates are intersecting the buildings. Move them apart. And center the fan blades in the tunnels except when preceded by a moving platform, but not if there were fan blades centered in tunnels before, because that gets boring."

"Well, now, nothing works."

In the same way that a neophyte game developer can see a 3D character walking around a grassy terrain will say, "Hey, I can make that MMORPG, easy!", we figured that if simple scripts created interesting results, we could simply extend them ad infinitum to create proportionally more awesome ones. Interesting structures start to require support mechanisms and carefully engineered exclusions.

4. Interesting PCG often creates either 1) stupid or 2) boring content.

The simplest random name generator we've seen looks like this:

# Generate random letters, yo:

for i in 1..random_number():

name += random_ character()

It's possible to generate every awesome fantasy, sci-fi or baby name you can possibly imagine -- given enough iterations, it'll come up with "Captain Rock McSpectacular," which is a great name. But it'll mostly generate junk like "ergihwe`=-ufaw38o72wenufse," which is completely useless to you. Probably.

In Ugly Baby, we did similar -- a relatively unconstrained algorithm that spat random pieces around a central axis created a simple, playable tunnel. The algorithm went something like this:

  1. Pick a random 3D model in our library (cubes, triangles, curves).
  2. Pick a number N and a number M.
  3. Create N evenly-space rings of the model, with M instances of the model in each ring.
  4. Go back to step 1.

On one run, that produced this:

Visually interesting, and actually useful to us -- it was a tunnel! Running the same script a second time generated an interesting sequence of hairy, finger-looking things, followed by another tunnel:

Also interesting and unexpected, and still useful. It was something the player could fly through. A third run:

This produced a completely impenetrable path comprising enough polygons to tank the framerate. It was pretty, and potentially useable elsewhere, but didn't compose a tunnel.

One solution to this problem is to start constraining parameters. In the earlier example of the name generator, perhaps we construct a grammar (consonant + vowel + consonant + vowel + consonant), or to keep a list of common first names and surnames, and simply string those together ("Billy Margaret Smith"). Similarly, in our tunnel example, perhaps we only construct tunnels out of pieces that are less than a certain volume, or limit the total number of high-poly base pieces.

The (sub-)problem with this is:

  • We end up clipping out some interesting branches that might surprise/delight us (goodbye, Captain Rock McSpectacular).
  • We quickly fill our algorithm with special cases, and it becomes impossible to manage.

Article Start Previous Page 3 of 5 Next

Related Jobs

Behaviour Interactive
Behaviour Interactive — Montreal, Quebec, Canada
[06.18.19]

Senior Game Designer
Ubisoft RedLynx
Ubisoft RedLynx — Helsinki, Finland
[06.18.19]

Senior Game Designer
New Moon Production
New Moon Production — Hamburg, Germany
[06.18.19]

User Interface Artist - New Moon Production (all genders)
Insomniac Games
Insomniac Games — Burbank, California, United States
[06.17.19]

Open-World Designer





Loading Comments

loader image