--- 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 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 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 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 >}}