5.1 KiB
5.1 KiB
title, type, weight
| title | type | weight |
|---|---|---|
| Prop Placement | docs | 10 |
Prop placement handles the generation of vegetation, decorations, and small objects on terrain surfaces.
Package: com.hypixel.hytale.builtin.hytalegenerator.props
Prop System
Props are small features placed after terrain generation:
public interface PropPlacer {
// Place props in chunk
void place(GenerationContainer container, int chunkX, int chunkZ);
}
public class PropContext {
private int x, y, z;
private Biome biome;
private BlockType surfaceBlock;
private float slope;
private boolean nearWater;
}
Prop Definition
# props/oak_tree.yaml
Type: Prop
Id: oak_tree
Prefab: prefabs/trees/oak_medium
Density: 0.02
Placement:
SurfaceTypes: [grass_block, dirt]
MinSlope: 0
MaxSlope: 30
MinSpacing: 3
Requirements:
ClearanceAbove: 10
ClearanceRadius: 2
Variants:
- prefabs/trees/oak_small
- prefabs/trees/oak_medium
- prefabs/trees/oak_large
VariantWeights: [0.3, 0.5, 0.2]
Position Providers
Determine where props can be placed:
RandomPositionProvider
Random surface positions:
Type: RandomPosition
Density: 0.1
GridSize: 4 # One attempt per 4x4 area
GridPositionProvider
Regular grid with jitter:
Type: GridPosition
Spacing: 8
Jitter: 3
NoisePositionProvider
Noise-based clustering:
Type: NoisePosition
NoiseScale: 0.05
Threshold: 0.3
Density: 0.5
Placement Rules
public class PlacementRules {
private Set<BlockType> validSurfaces;
private float minSlope;
private float maxSlope;
private int minSpacing;
private int clearanceAbove;
public boolean canPlace(PropContext ctx) {
// Check surface type
if (!validSurfaces.contains(ctx.surfaceBlock)) {
return false;
}
// Check slope
if (ctx.slope < minSlope || ctx.slope > maxSlope) {
return false;
}
// Check spacing from other props
if (!hasMinSpacing(ctx)) {
return false;
}
// Check clearance
if (!hasClearance(ctx)) {
return false;
}
return true;
}
}
Vegetation Props
TreePlacer
Places trees with biome variation:
Type: TreePlacer
Biomes:
forest:
Density: 0.3
Types: [oak, birch, maple]
plains:
Density: 0.02
Types: [oak]
jungle:
Density: 0.5
Types: [jungle_tree, palm]
GrassPlacer
Places grass and flowers:
Type: GrassPlacer
Density: 0.8
Variants:
- Block: tall_grass
Weight: 0.7
- Block: fern
Weight: 0.2
- Block: flower_red
Weight: 0.05
- Block: flower_yellow
Weight: 0.05
BushPlacer
Places bushes and shrubs:
Type: BushPlacer
Density: 0.1
Prefabs: [bush_small, bush_medium]
NearTreesOnly: true
TreeDistance: 5
Object Props
RockPlacer
Places rocks and boulders:
Type: RockPlacer
Density: 0.05
Sizes:
- Prefab: rock_small
Weight: 0.6
- Prefab: rock_medium
Weight: 0.3
- Prefab: rock_large
Weight: 0.1
BiomeModifiers:
mountains: 2.0
plains: 0.5
DebrisPlacer
Places fallen logs, branches:
Type: DebrisPlacer
Density: 0.03
Items:
- fallen_log
- branch
- leaf_pile
ForestOnly: true
Biome Integration
public class BiomePropPlacer implements PropPlacer {
private Map<String, List<PropConfig>> biomeProps;
public void place(GenerationContainer container, int chunkX, int chunkZ) {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
int worldX = chunkX * 16 + x;
int worldZ = chunkZ * 16 + z;
Biome biome = container.getBiome(worldX, worldZ);
List<PropConfig> props = biomeProps.get(biome.getId());
for (PropConfig prop : props) {
if (shouldPlace(prop, worldX, worldZ)) {
placeProp(container, prop, worldX, worldZ);
}
}
}
}
}
}
Configuration
# props/config.yaml
PropPlacement:
Enabled: true
DensityMultiplier: 1.0
Props:
- Type: TreePlacer
Priority: 1
- Type: BushPlacer
Priority: 2
- Type: GrassPlacer
Priority: 3
- Type: RockPlacer
Priority: 4
Custom Prop Placer
public class MyPropPlacer implements PropPlacer {
@Override
public void place(GenerationContainer container, int chunkX, int chunkZ) {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
if (random.nextFloat() < 0.1f) {
int surfaceY = container.getHeight(x, z);
// Place custom prop
placeMyProp(container, x, surfaceY + 1, z);
}
}
}
}
}
Best Practices
{{< callout type="info" >}} Prop Placement Guidelines:
- Use appropriate density for biome feel
- Ensure props don't overlap
- Add variety with multiple variants
- Consider performance with high density
- Test visual distribution across terrain {{< /callout >}}