Table “grid_layouts” contains grid parameters, like maximal X-, Y- and Z-coordinates, maybe a grid name and frequencies of different cells. This way we can have several grid templates. The columns are:

id

layout_name — a dozen of characters

max_x — number

max_y — number

max_z — number

description — many characters

what else?

Table “hex_layouts” contains all possible types of hexes that can be encountered on a grid, information on whether they are inhabitable, fertility, sunlight/temperature, and water/humidity:

id

inhabitable — boolean

fertility — percent from 0 to 100

humidity — percent from 0 to 100

sunlight — percent from 0 to 100

OK, that was it so far. What hex types do we need here?
Uninhabitable:

fertile-humid — 110:110:80 (or maybe I should make it even more imbalanced, comparing to the previous three)

fertile-sunny — 110:80:110

humid-sunny — 80:110:110

So, there are 10 types of hexes. I need to decide on the distribution (like a hex of basic type should have no more than two uninhabitable hexes adjacent to it) and frequencies of each type. Exact frequencies are not very-very important, but it would be interesting to make a mechanism to adjust frequencies after the distribution rules were met. Say, if while populating the grid (hex by hex, row by row, checking for rules in the previous row), uninhabitable hexes turned out to be too few, the probability of the next hex being uninhabitable should be larger than average. Mmm … that still does not guarantee that the number of outcomes is strictly equal to the probabilities/frequencies…