---
title: Material Providers
type: docs
weight: 9
---

Material providers determine which blocks are placed at each position during terrain generation.

**Package:** `com.hypixel.hytale.builtin.hytalegenerator.materialproviders`

## Material Provider Concept

Material providers select blocks based on context:

```java
public interface MaterialProvider {
    // Get block for position
    BlockType getBlock(int x, int y, int z, MaterialContext context);
}

public class MaterialContext {
    private Biome biome;
    private float density;
    private int surfaceHeight;
    private int depth;  // Depth below surface
    private boolean underwater;
}
```

## Basic Providers

### SingleMaterialProvider

Returns a single block type:

```yaml
Type: SingleMaterial
Block: stone
```

### DepthMaterialProvider

Changes blocks based on depth:

```yaml
Type: DepthMaterial
Layers:
  - Depth: 0
    Block: grass_block
  - Depth: 1
    Block: dirt
  - Depth: 4
    Block: stone
```

```java
public class DepthMaterialProvider implements MaterialProvider {
    private List<DepthLayer> layers;

    public BlockType getBlock(int x, int y, int z, MaterialContext ctx) {
        for (DepthLayer layer : layers) {
            if (ctx.depth >= layer.minDepth) {
                return layer.block;
            }
        }
        return defaultBlock;
    }
}
```

## Biome-Based Providers

### BiomeMaterialProvider

Selects materials based on biome:

```yaml
Type: BiomeMaterial
Biomes:
  forest:
    Surface: grass_block
    Subsurface: dirt
    Stone: stone
  desert:
    Surface: sand
    Subsurface: sandstone
    Stone: sandstone
  tundra:
    Surface: snow_block
    Subsurface: permafrost
    Stone: stone
```

### BiomeSurfaceProvider

Surface-specific provider:

```java
public class BiomeSurfaceProvider implements MaterialProvider {
    private Map<String, SurfaceMaterials> biomeMaterials;

    public BlockType getBlock(int x, int y, int z, MaterialContext ctx) {
        SurfaceMaterials materials = biomeMaterials.get(ctx.biome.getId());
        if (materials == null) {
            materials = defaultMaterials;
        }

        if (ctx.depth == 0) {
            return materials.surface;
        } else if (ctx.depth < 4) {
            return materials.subsurface;
        } else {
            return materials.stone;
        }
    }
}
```

## Noise-Based Providers

### NoiseMaterialProvider

Uses noise for variation:

```yaml
Type: NoiseMaterial
Noise:
  Scale: 0.1
  Threshold: 0.5
Materials:
  Above: stone
  Below: granite
```

### GradientMaterialProvider

Blends materials based on value:

```java
public class GradientMaterialProvider implements MaterialProvider {
    private SimplexNoise noise;
    private List<MaterialStop> stops;

    public BlockType getBlock(int x, int y, int z, MaterialContext ctx) {
        float value = noise.noise3D(x * 0.05f, y * 0.05f, z * 0.05f);

        for (int i = stops.size() - 1; i >= 0; i--) {
            if (value >= stops.get(i).threshold) {
                return stops.get(i).block;
            }
        }
        return defaultBlock;
    }
}
```

## Composite Providers

### LayeredMaterialProvider

Stacks multiple providers:

```yaml
Type: LayeredMaterial
Layers:
  - Provider: bedrock_layer
    MaxY: 5
  - Provider: stone_layer
    MaxY: 60
  - Provider: surface_layer
    MaxY: 256
```

### ConditionalMaterialProvider

Conditional block selection:

```yaml
Type: ConditionalMaterial
Conditions:
  - Condition:
      Type: Underwater
    Provider: sand_material
  - Condition:
      Type: NearCave
      Distance: 2
    Provider: cave_stone
  - Default: default_material
```

## Special Providers

### OreMaterialProvider

Places ore veins:

```yaml
Type: OreMaterial
Ores:
  - Type: iron_ore
    MinY: 0
    MaxY: 64
    Frequency: 0.02
    Size: 9
  - Type: diamond_ore
    MinY: 0
    MaxY: 16
    Frequency: 0.001
    Size: 4
```

### CaveMaterialProvider

Materials for cave surfaces:

```yaml
Type: CaveMaterial
Floor: gravel
Ceiling: stone
Walls: mossy_stone
WaterLevel: 10
WaterBlock: water
```

## Configuration

```yaml
# materialproviders/config.yaml
MaterialProviders:
  default:
    Type: BiomeMaterial
    Biomes:
      forest:
        Surface: grass_block
        Subsurface: dirt
        Stone: stone
  cave:
    Type: CaveMaterial
    Floor: gravel
    Walls: stone
```

## Custom Provider

```java
public class MyMaterialProvider implements MaterialProvider {
    @Override
    public BlockType getBlock(int x, int y, int z, MaterialContext ctx) {
        // Custom material logic
        if (ctx.underwater) {
            return BlockTypes.SAND;
        }
        if (ctx.depth == 0) {
            return BlockTypes.GRASS_BLOCK;
        }
        return BlockTypes.STONE;
    }
}

// Register
materialRegistry.register("my_materials", new MyMaterialProvider());
```

## Best Practices

{{< callout type="info" >}}
**Material Provider Guidelines:**
- Use biome-aware providers for variety
- Layer providers for complex surfaces
- Add noise for natural variation
- Consider special cases (underwater, caves)
- Test material transitions between biomes
{{< /callout >}}
