4
\$\begingroup\$

The aesthetics I am going for is demonstrated by many simulation games such as Simcity. But I am looking at this particular example: Polygonal Planet Project by Oskar Stålberg.

planet project

I understand the concept: when the player places or upgrades a tile, the game looks at adjacent tiles to figure out which tile should be used. And in most cases, a tile would be self-contained, so I just need to design all possible variant of such tile.

And I have some experience on procedural generation in 3D, so coding isn't the main problem for me.

What I am wondering, are:

  • Does this type of continuous 3D tilesets have a name? I tried to google some examples/tutorials but failed to find the appropriate keyword.
  • Are there tools to make the process of creating tile variants easier?
  • Is there a preferable process to create such tileset? Do I start by creating structures then divide them into repeatable patterns, or should I start with basic tiles and find way to create smooth transition between them?

That's probably too much to answer in detail, but I would like some pointers on this topic (more about asset design than programming I suppose). Thx!

\$\endgroup\$
4
\$\begingroup\$

This can be done with a generalization of Wang Tiles or Corner Tiles. These associate labels with the boundaries of a tile, and enforce the constraint that two tiles that meet along a particular boundary must have matching labels. This lets us create tiles tagged with these labels and ensure that there will be no visible seams, because the label constraint controls which tiles can abut one another.

  • Wang Tiles associate a label with each (oriented) edge in the grid.

    (If your data is stored at the vertices, you can create an edge label from an ordered pair of vertex labels - eg. "this vertical edge goes from [water] at the bottom to [mountain] at the top, so it's a water-mountain edge")

  • Corner Tiles associate a label with each vertex in the grid. This is sometimes more natural for tile-based level authoring, and can result in smaller tilesets or more pleasing tiling properties, as described in the linked paper.

When deciding what tile to draw at each location, you form a tile ID from the labels of its bounding vertices/edges (eg. water, mountain, forest, town...), and use that information to look up or generate an appropriate tile to fill the space inside.

For example, here's the complete set of square corner tiles needed to handle all possible combinations of three corner types:

Set of all 3^4 = 81 square corner tiles with 3 distinct labels The ID in the center of each tile is formed this way:

ID = 0
For each cornerIndex, from 0 (top-left) clockwise to 3 (bottom-left)
    cornerLabel = GetCornerLabel(cornerIndex); //red: 0, yellow: 1, green: 2
    ID += cornerLabel * pow(3, cornerIndex)

To generate such a tileset directly, you'd enumerate each feature label you need (eg. water, sand, grass, forest, mountain, town) then build a tile for each possible permutation of these features around the border of your tile shape.

Note that the complete set of tiles needed grows very quickly as we increase complexity. Specifically:

SizeOfCOmpleteTileset(numLabels, numFeaturesPerTile) = pow(numLabels, numFeaturesPerTile)

Things you can do to address this:

  • Break your tiles into smaller pieces. A square tile depends on four edge/corner labels, but a triangular tile depends on only three, reducing the complexity by an order of magnitude.

    I'd be willing to bet that Oskar Stålberg's planetary example above models its border/tile transition logic on triangles, breaking each hexagon/pentagon of the Goldberg polyhedron into a fan of 6/5 triangles. This both reduces the number of distinct tile types and allows handling the 5- and 6-sided tiles more uniformly, rather than creating a unique tileset for each tile shape.

  • Forbid certain permutations of features from meeting at a single tile.

    Eg. maybe "jungle" never appears adjacent to "desert" - there must be a patch of another terrain like "grassland" or "mountain" separating them. This reduces the number of combinations you need to support, but restricts your level creation flexibility (and slightly complicates your tile indexing, since a naive index will contain gaps representing forbidden tiles that are never used).

  • Automatically flip/rotate tiles to handle duplicate tiles that differ only by orientation. This means you can't have oriented features in your tiles, or rely on identical orientation along edges.

  • Generate tiles on demand, by layering or parametrizing features, rather than storing every combination explicitly.

    It looks like the planetary example in the question may use this strategy, having rules to build things like "junction between town wall and higher town wall" so it can generate needed permutations of this pattern on the fly. There also seems to be some procedural logic in the placement of buildings to fill the towns - the cluster of buildings in the center of each hex/penta fan stays the same, but the buildings along the edges change as their surroundings are modified.

There are tools to help generate these types of tiles from 2D textures (though usually for texture synthesis and not directly suitable to typical tile-based game uses where we want more structure) - see the references in the Corner Tile paper linked above - but I'm not aware of any for working in 3D.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.