This commit is contained in:
2026-01-20 20:33:59 +01:00
commit b16a40e431
583 changed files with 87339 additions and 0 deletions

View File

@@ -0,0 +1,281 @@
---
title: Prop Placement
type: docs
weight: 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:
```java
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
```yaml
# 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:
```yaml
Type: RandomPosition
Density: 0.1
GridSize: 4 # One attempt per 4x4 area
```
### GridPositionProvider
Regular grid with jitter:
```yaml
Type: GridPosition
Spacing: 8
Jitter: 3
```
### NoisePositionProvider
Noise-based clustering:
```yaml
Type: NoisePosition
NoiseScale: 0.05
Threshold: 0.3
Density: 0.5
```
## Placement Rules
```java
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:
```yaml
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:
```yaml
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:
```yaml
Type: BushPlacer
Density: 0.1
Prefabs: [bush_small, bush_medium]
NearTreesOnly: true
TreeDistance: 5
```
## Object Props
### RockPlacer
Places rocks and boulders:
```yaml
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:
```yaml
Type: DebrisPlacer
Density: 0.03
Items:
- fallen_log
- branch
- leaf_pile
ForestOnly: true
```
## Biome Integration
```java
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
```yaml
# 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
```java
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 >}}