PolyhedralDev / Terra

Voxel world generation modding platform
MIT License
673 stars 89 forks source link

[Feature] Layered Generator #340

Open astrsh opened 2 years ago

astrsh commented 2 years ago

Pre-Request Checklist

Feature Description

A generator that generalizes terrain, carving, and ocean, referred to as 'layers'. These layers and their generation behaviour would be config defined rather than hardcoded by the generator.

What Problem Does This Solve?

Adding new aspects of generation to a pack such as aquifers is difficult to do properly without code changes to facilitate it. Data driven generation layers should provide the functionality required for such aspects, and is also in line with the Terra design philosophy, such that concepts like 'ocean' and 'carving' are not hard coded in.

A Solution You'd Like

Alternative Solutions

The best alternative available right now would be using features to generate things like aquifers, and underground lava oceans, however doing it that way lacks advantages of this generator such as control over interpolation and sampling, more control over initial chunk generation, etc..

dfsek commented 2 years ago

This would probably be implemented in a new chunk generator addon, that way we can keep the noise 3d generator addon around for beginners/simple packs.

astrsh commented 2 years ago

Mockup config for how the layered generator could work

# Layer predicates define a predicate that takes world coordinates
# Not sure how exactly these should be defined
# The functionality of terrain.sampler, terrain.sampler-2d, carving.sampler, and ocean.level would be utilized here
layer-predicates:
  is-terrain:
  is-carving:
  is-aquifer-border:
  is-aquifer-water:
  is-aquifer-lava:
  is-under-lava-level:
  is-under-ocean-level:

# Layer palettes define sets of block placements
layer-palettes:
  terrain:
    type: BIOME_DEFINED # Allows biomes to specify a palette, this would be dynamically registered as a config key
    default: # What the default palette is if a biome doesn't specify a palette
      type: BLOCK # A single block palette
      block: minecraft:stone
  air:
    type: BLOCK
    block: minecraft:air
  ocean:
    type: BIOME_DEFINED
    default:
      type: BLOCK
      block: minecraft:water
  underground-lava:
    type: BLOCK
    block: minecraft:lava
  aquifer-water:
    type: BIOME_DEFINED
    default:
      type: BLOCK
      block: minecraft:water
  aquifer-lava:
    type: BLOCK
    block: minecraft:lava

# Converts to a binary decision diagram
# The 'if' key specifies a layer predicate
# The 'place' key specifies a layer palette
layer-placement: 
  if: is-terrain
  then:
    if: is-carving
    then:
      if: is-aquifer-border
      then:
        place: terrain
      else:
        if: is-aquifer-water
        then:
          place: aquifer-water
        else:
          if: is-aquifer-lava
          then:
            place: aquifer-lava
          else:
            if: is-under-lava-level
            then:
              place: underground-lava
            else:
              place: air
    else:
      place: terrain
  else:
    if: is-under-ocean-level
    then:
      place: ocean
    else:
      place: air
astrsh commented 2 years ago

The following layer predicates could share the same sampler:

layer-predicates:
  is-aquifer-border:
  is-aquifer-water:
  is-aquifer-lava:

So perhaps there would be another component that is used to construct the predicates, i.e a layer distributor.

Layer distributors should supersede the capabilities of the biome keys terrain, carving, and ocean.level, such that you can do things like specify interpolation, combining 2D & 3D samplers, etc