Chunky procedural generation

When making a procedural generator, instead of letting a parameter vary across the entire range of possible values, considering breaking that range into sectors.

EDIT: I used to call these limited ranges “chunks” instead of “sectors” but procedural generation in chunks makes people think of Minecraft, so I changed the name to avoid ambiguity.

Sectors

Not overlapping isn’t enough. Sectors should have space between them. This reduces the total number of possibilities, which seems bad, but each value will have greater meaning.

A number line from 0-4, labeled "height (meters)" Four ranges are marked. tiny: 0 to 0.5 meters. small: 0.75 to 1.25 meters. medium: 1.5 to 2 meters. Large: 2.5 to 4 meters.
Figure 1. Height parameter separated into four chunks

If the Small and Medium height sectors met at 1.5m, artifacts could be generated whose height is ambiguous. I can’t tell the difference between 148cm and 151cm at a glance, so if I see creatures with those heights, I won’t know if they are Small creatures or Medium creatures. Stopping Small at 1.25m means there’s 25cm between the tallest Small Creature and the shortest Medium creature, enough to remove ambiguity.

A number line from 0 to 12, labeled number of legs. four chunks are marked. Orb: 0 legs. Biped 2 legs. Beast 4 to 6 legs. Bug: 8 to 12 legs.
Figure 2. Number of legs parameter separated into 4 chunks.

Sectors don’t have to be the same size. They need to be different enough that observers can tell them apart. Counting 10 or 12 legs will take a while, but I immediately know they are both “a lot” and thus bug-like. The range for biped has no variation at all, but that’s valid too.

Limited sectors promote identity

For example, Hunter clothes come in desaturated earth tones to help Hunters blend in with natural surroundings.  If all clothing was available in all colors, Hunters would have less of an identity. Choice of clothing tells viewers something about the person wearing the clothing.

A grid of 21 stars on a black background. The stars vary widely in size, color, thickness, and number of points.
Figure 3. Stars generated with maximum randomness
A grid of 21 stars on a black background. The stars are roughly the same size, with 5 to 7 points, and red to yellow coloration.
Figure 4. Stars generated from sectors of parameter ranges.

Figure 3 the output of a star generator with the ranges on size, color, spikiness, and number of points opened up. It’s easy to associate to the two green spiky stars at top right as being kind of the same thing, but why would I think the red diamond on the left edge is the same kind of thing as those other two? The class of “stars” is so diverse that it loses cohesion.

In Figure 4, I tightened the colors to warm, autumnal colors, and reduced the amount of variance in size, number of points, and spikiness. These stars seem more related to each other. It’s easy to mentally group them as the same kind of thing, but there’s still quite a bit of variance between each star.

Perceptual differentiation

A grid of 21 stars on a black background. Half the stars are grey, very spiky, with many points. The other half look like the stars in Figure 4: red to yellow, 5 to 7 points.
Figure 5. Autumnal stars and grey spiky stars

Perceptual differentiation is the ability to tell two things apart.

In Figure 5, I’ve mixed the autumn stars with spiky grey stars. Even though each star is different from all the others, it’s easy to see that there are two different kinds of stars, and to sort each particular star into one of those two groups.

Individually unique objects that are easily sorted into groups are a nice way to ensure perceptual differentiation. If the two classes uses disjoint chucks of the parameter spaces, two objects from different classes are sure to look different from each other.

Even if you end up with 10,000 bowls of oatmeal, if you also offer 10,000 slices of toast, 10,000 waffles, and 10,000 cups of yogurt, you have a better breakfast buffet.

“Perceptual differentiation” and “10,000 bowls of oatmeal” are both terms from Kate Compton’s excellent blog post So you want to build a generator…

The sector becomes information

If a certain feature of an object is not completely random, it can tell us something about that object. In ARPGs like Diablo, a potion with blue liquid will restore my energy, no matter the size or shape of the bottle.  blue potion = mana. if a tree has a conical crown and needles instead of leaves, I know those leaves won’t fall off in winter, because conifers are evergreen. Live oaks are also evergreen, but their leaves and crown are shaped closer to deciduous trees than conifers, so it’s easy to mistake them for deciduous trees.

The next section shows how one class of object can have multiple parameters that each have some meaning, so an observer can quickly recognize many features of

Layers of differentiation

Every object will have multiple parameters, and each parameter can be divided into multiple sectors. By giving different objects the same or different sectors, you can create a hierarchy of relationships between objects. I’ll use Starcraft as an example.

Races:

  • Protoss:
    • colors: pale yellow, glowing blue
    • shapes: smooth curves
  • Terran:
    • colors: shades of grey
    • shapes: rectangles & circles
  • Zerg:
    • colors: reddish to purple
    • shapes: tubes, sacs, claws, and teeth

Unit types:

  • Buildings
    • size: huge
    • number: solitary
    • features: immobile, grounded
  • basic units
    • size: small
    • number: large groups
    • features: mobile
  • elite units
    • size: large
    • number: small groups
    • features: mobile

Terran Infantry:

  • All infantry:
    • small
    • humanoid
  • Marine
    • big shoulders
    • long gun
  • Firebat
    • backpack
    • twin weapons
  • Medic
    • white armor
    • shield

Seeing these patterns helps me recognize objects quickly, and make good guesses about new objects I haven’t seen before.

If I see a mass of Terran Infantry (small, humanoid, grey, large numbers) I can pick the Firebats out from the Marines by looking for the backpacks, because that’s the feature they DON’T share.

If I see a weird purple creature with big teeth, I know it’s Zerg, because that’s what Zerg look like. Protoss and Terrans don’t make things like that.

If I see a huge, immobile, radially symmetrical object, it’s probably a key building, like a Town Hall, because that’s what all the other Town Hall buildings look like.

Notice that the relationships can be hierarchical (Terran Infantry is a subset of Terran) or cut across groups (buildings share characteristics across races)

Use an interlocking system of similarities (objects that share the same parameter sector) and differences (objects use disjoint sectors of a parameter) to create objects that are all unique, but are easily sorted by an observer into multiple overlapping groups.

Summary

  • Consider if you really need the full range of a certain parameter for a class of artifacts
  • Divide a parameter range into sectors that:
    • are thematically appropriate for the artifacts that use them
    • are disjoint from other sectors of the same parameter range
    • allow enough variation between artifacts that use the sector
  • Use those sectors to:
    • allow observers to remember features of the artifacts
    • relate artifacts to artifacts that share that sector
    • separate artifacts from artifacts that use different sectors