4.5 KiB
4.5 KiB
title, type, weight
| title | type | weight |
|---|---|---|
| Zones | docs | 6 |
Zones define distinct regions of the world with specific generation rules, biomes, and features.
Package: com.hypixel.hytale.server.worldgen.zone
Zone System
Zones partition the world into distinct areas:
public class ZoneManager {
// Get zone at position
public Zone getZone(int x, int z);
// Register zone
public void registerZone(Zone zone);
// Get all zones
public List<Zone> getZones();
}
Zone Definition
# zones/emerald_grove.yaml
Type: Zone
Id: emerald_grove
DisplayName: "Emerald Grove"
Shape: Circle
Center: [0, 0]
Radius: 1000
Biomes:
- forest
- dense_forest
Climate:
TemperatureOffset: 0.1
HumidityOffset: 0.2
Features:
- giant_trees
- fairy_circles
Prefabs:
- elf_village
- forest_shrine
MobSpawns:
- Type: deer
Weight: 20
- Type: forest_spirit
Weight: 5
Zone Class
public class Zone {
private String id;
private String displayName;
private ZoneShape shape;
private List<String> biomes;
private ClimateModifier climate;
private List<String> features;
private List<String> prefabs;
private List<MobSpawn> mobSpawns;
// Check if position is in zone
public boolean contains(int x, int z);
// Get zone-specific biome
public Biome getBiome(int x, int z);
// Modify generation
public void modifyGeneration(GenerationContainer container);
}
Zone Shapes
public interface ZoneShape {
boolean contains(int x, int z);
float getDistanceToEdge(int x, int z);
}
public class CircleZone implements ZoneShape {
private int centerX, centerZ;
private int radius;
public boolean contains(int x, int z) {
int dx = x - centerX;
int dz = z - centerZ;
return dx * dx + dz * dz <= radius * radius;
}
}
public class RectangleZone implements ZoneShape {
private int minX, minZ, maxX, maxZ;
public boolean contains(int x, int z) {
return x >= minX && x <= maxX && z >= minZ && z <= maxZ;
}
}
public class PolygonZone implements ZoneShape {
private List<Vector2i> vertices;
public boolean contains(int x, int z) {
// Point-in-polygon algorithm
return isPointInPolygon(x, z, vertices);
}
}
Zone Transitions
Smooth transitions between zones:
public class ZoneTransition {
private int transitionWidth;
public float getBlendFactor(Zone from, Zone to, int x, int z) {
float distFrom = from.getShape().getDistanceToEdge(x, z);
float distTo = to.getShape().getDistanceToEdge(x, z);
if (distFrom > transitionWidth) {
return 0.0f; // Fully in 'from' zone
}
if (distTo > transitionWidth) {
return 1.0f; // Fully in 'to' zone
}
return distFrom / (distFrom + distTo);
}
}
Zone Layers
Zones can have vertical layers:
# zones/underground_kingdom.yaml
Type: Zone
Id: underground_kingdom
Shape: Circle
Center: [5000, 5000]
Radius: 500
VerticalRange:
MinY: 0
MaxY: 40
Biomes:
- crystal_cave
- mushroom_forest
Features:
- glowing_crystals
- underground_lake
Zone Priority
When zones overlap, priority determines which applies:
public class ZonePriority {
public Zone getActiveZone(int x, int y, int z) {
List<Zone> containing = zones.stream()
.filter(z -> z.contains(x, z) && z.containsY(y))
.sorted(Comparator.comparing(Zone::getPriority).reversed())
.toList();
return containing.isEmpty() ? defaultZone : containing.get(0);
}
}
Dynamic Zones
Zones that can change at runtime:
public class DynamicZone extends Zone {
public void expand(int amount) {
if (shape instanceof CircleZone circle) {
circle.setRadius(circle.getRadius() + amount);
}
}
public void move(int dx, int dz) {
shape.translate(dx, dz);
}
}
Configuration
# worldgen/zone_config.yaml
Zones:
Default: wilderness
TransitionWidth: 32
List:
- Id: spawn_area
Priority: 100
Shape: Circle
Center: [0, 0]
Radius: 200
- Id: wilderness
Priority: 0
Shape: Infinite
Best Practices
{{< callout type="info" >}} Zone Guidelines:
- Use zones for distinct world regions
- Define smooth transitions between zones
- Consider zone priority for overlaps
- Use appropriate shapes for zone boundaries
- Test zone generation thoroughly {{< /callout >}}