274 lines
5.0 KiB
Markdown
274 lines
5.0 KiB
Markdown
---
|
|
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 >}}
|