In most cases procedural content generation for games means building with bricks, where each brick is a hand crafted asset module designed to fit together with any other module in the same set, just like Lego bricks. Level generation is then simply selecting and placing instances of these pre-made bricks according to some logic, often simply using rand().
Building with Bricks
Modular bricks have some very nice properties, by design they lend themselves to instancing and can be very friendly to your frame rate even in large numbers. They are also fairly quick and easy to make, and the placement logic used can be as simple or as complex as needs be. The problem with building bricks however, is repetition. Sooner or later a player will have seen every brick in your set enough times to recognise the individual pieces, spoiling immersion in the game world and making levels boring and predictable. While modules can make generating levels of various sizes quick and easy, the problems of repetition obviously increase with the size of the level created.
Personally I think of procedurally placed modules as a sort of PCG lite, a fairly simple thing to create that offers a level of artistic control at the cost of some variety and more manual work building the modules. Ultimately I hope to move on from this and add much more procedural variety into the mix, possibly by generating modules to mix in with the hand authored assets, but for now PCG lite is a good start.
Dealing with Repetition
One of the best ways I have found to break up repetition caused by tiling bricks is to actually introduce more levels of repetition. This may seem counterintuitive but if the additional levels of repetition are out of sync with the first (and with each other) the combined result is vastly more interesting and reduces the appearance of tiling. Like two waveforms that are out of phase with each other, the period of repetition when taking both into account is larger than that of either wave on its own. This idea works very nicely with materials (think detail maps) and I hope to write more about that in the next update.
For now let’s look at implementing the idea with geometry. This can be achieved by adding visual features that span multiple tiles. This effectively ties several tiles together into one larger tile that is out of phase with those around it. By mixing in randomness in the choice of elements picked (another set of bricks to chose from) and in the length of tiles spanned, we can add in a decent amount of variety without too much extra work.
So let’s try building some new wall tiles and some decorations to tie them together. In these examples we are using pipes and cables to tie industrial themed wall sections together.
Adding a few more tweaks and some door frames for good measure we get something that’s starting to look fairly decent, all conjured up procedurally.
As mentioned earlier, the next update will take this idea further and add specially crafted materials to break up repetition even more.