227 lines
4.5 KiB
Markdown
227 lines
4.5 KiB
Markdown
---
|
|
title: Zones
|
|
type: docs
|
|
weight: 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:
|
|
|
|
```java
|
|
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
|
|
|
|
```yaml
|
|
# 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
|
|
|
|
```java
|
|
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
|
|
|
|
```java
|
|
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:
|
|
|
|
```java
|
|
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:
|
|
|
|
```yaml
|
|
# 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:
|
|
|
|
```java
|
|
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:
|
|
|
|
```java
|
|
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
|
|
|
|
```yaml
|
|
# 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 >}}
|