Init
This commit is contained in:
115
content/world/worldgen/_index.en.md
Normal file
115
content/world/worldgen/_index.en.md
Normal file
@@ -0,0 +1,115 @@
|
||||
---
|
||||
title: World Generation
|
||||
type: docs
|
||||
weight: 10
|
||||
---
|
||||
|
||||
The World Generation system creates procedural terrain, caves, biomes, and structures for Hytale worlds.
|
||||
|
||||
**Packages:**
|
||||
- `com.hypixel.hytale.server.worldgen`
|
||||
- `com.hypixel.hytale.builtin.hytalegenerator`
|
||||
|
||||
{{< cards >}}
|
||||
{{< card link="world-loader" title="World Loader" subtitle="Chunk loading and generation pipeline" >}}
|
||||
{{< card link="chunk-generation" title="Chunk Generation" subtitle="Block placement and terrain" >}}
|
||||
{{< card link="cave-generation" title="Cave Generation" subtitle="Underground cave systems" >}}
|
||||
{{< card link="climate-biomes" title="Climate & Biomes" subtitle="Biome distribution and climate" >}}
|
||||
{{< card link="prefabs" title="Prefabs" subtitle="Structure and building placement" >}}
|
||||
{{< card link="zones" title="Zones" subtitle="Zone definitions and regions" >}}
|
||||
{{< card link="hytale-generator" title="Hytale Generator" subtitle="Default procedural generator" >}}
|
||||
{{< card link="density-functions" title="Density Functions" subtitle="Terrain shape definition" >}}
|
||||
{{< card link="material-providers" title="Material Providers" subtitle="Block selection logic" >}}
|
||||
{{< card link="prop-placement" title="Prop Placement" subtitle="Vegetation and object placement" >}}
|
||||
{{< card link="generation-patterns" title="Generation Patterns" subtitle="Patterns and fields" >}}
|
||||
{{< /cards >}}
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
The world generation system operates in several phases:
|
||||
|
||||
```
|
||||
World Generation Pipeline
|
||||
├── Climate Generation
|
||||
│ └── Biome Assignment
|
||||
├── Terrain Generation
|
||||
│ ├── Density Functions (shape)
|
||||
│ ├── Material Providers (blocks)
|
||||
│ └── Surface Decoration
|
||||
├── Cave Generation
|
||||
│ ├── Cave Carving
|
||||
│ └── Cave Features
|
||||
├── Structure Placement
|
||||
│ ├── Prefab Selection
|
||||
│ └── Prefab Positioning
|
||||
└── Prop Placement
|
||||
├── Vegetation
|
||||
└── Objects
|
||||
```
|
||||
|
||||
## Packages Overview
|
||||
|
||||
| Package | Files | Description |
|
||||
|---------|-------|-------------|
|
||||
| `loader/` | 75 | World loading system |
|
||||
| `util/` | 35 | Generation utilities |
|
||||
| `cave/` | 32 | Cave generation |
|
||||
| `climate/` | 12 | Climate and biomes |
|
||||
| `chunk/` | 12 | Chunk generation |
|
||||
| `prefab/` | 8 | Structure placement |
|
||||
| `zone/` | 7 | Zone definitions |
|
||||
| `cache/` | 7 | Generation caching |
|
||||
|
||||
## Hytale Generator
|
||||
|
||||
The built-in Hytale generator provides the default world generation:
|
||||
|
||||
| Package | Files | Description |
|
||||
|---------|-------|-------------|
|
||||
| `assets/` | 232 | Generator asset definitions |
|
||||
| `density/` | 76 | Density functions |
|
||||
| `materialproviders/` | 29 | Block selection |
|
||||
| `props/` | 24 | Prop placement |
|
||||
| `patterns/` | 13 | Generation patterns |
|
||||
| `fields/` | 8 | Field generation |
|
||||
|
||||
## Quick Example
|
||||
|
||||
```java
|
||||
// Get world generator
|
||||
WorldGenerator generator = world.getGenerator();
|
||||
|
||||
// Generate chunk
|
||||
generator.generateChunk(chunkX, chunkZ);
|
||||
|
||||
// Get biome at position
|
||||
Biome biome = generator.getBiome(position);
|
||||
|
||||
// Check if structure can generate
|
||||
boolean canPlace = generator.canPlacePrefab(prefab, position);
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
World generation is configured through YAML assets:
|
||||
|
||||
```yaml
|
||||
# worldgen/my_generator.yaml
|
||||
Type: WorldGenerator
|
||||
Id: my_generator
|
||||
Seed: 12345
|
||||
Climate:
|
||||
Type: StandardClimate
|
||||
Biomes:
|
||||
- forest
|
||||
- plains
|
||||
- mountains
|
||||
Density:
|
||||
Type: MultipleDensity
|
||||
Functions:
|
||||
- terrain_base
|
||||
- terrain_hills
|
||||
Prefabs:
|
||||
- Type: Village
|
||||
Frequency: 0.01
|
||||
```
|
||||
115
content/world/worldgen/_index.fr.md
Normal file
115
content/world/worldgen/_index.fr.md
Normal file
@@ -0,0 +1,115 @@
|
||||
---
|
||||
title: Génération de Monde
|
||||
type: docs
|
||||
weight: 10
|
||||
---
|
||||
|
||||
Le système de génération de monde crée du terrain procédural, des grottes, des biomes et des structures pour les mondes Hytale.
|
||||
|
||||
**Packages:**
|
||||
- `com.hypixel.hytale.server.worldgen`
|
||||
- `com.hypixel.hytale.builtin.hytalegenerator`
|
||||
|
||||
{{< cards >}}
|
||||
{{< card link="world-loader" title="World Loader" subtitle="Chargement de chunks et pipeline de génération" >}}
|
||||
{{< card link="chunk-generation" title="Génération de Chunks" subtitle="Placement de blocs et terrain" >}}
|
||||
{{< card link="cave-generation" title="Génération de Grottes" subtitle="Systèmes de grottes souterraines" >}}
|
||||
{{< card link="climate-biomes" title="Climat & Biomes" subtitle="Distribution des biomes et climat" >}}
|
||||
{{< card link="prefabs" title="Prefabs" subtitle="Placement de structures et bâtiments" >}}
|
||||
{{< card link="zones" title="Zones" subtitle="Définitions de zones et régions" >}}
|
||||
{{< card link="hytale-generator" title="Hytale Generator" subtitle="Générateur procédural par défaut" >}}
|
||||
{{< card link="density-functions" title="Fonctions de Densité" subtitle="Définition de forme du terrain" >}}
|
||||
{{< card link="material-providers" title="Material Providers" subtitle="Logique de sélection de blocs" >}}
|
||||
{{< card link="prop-placement" title="Placement de Props" subtitle="Placement de végétation et objets" >}}
|
||||
{{< card link="generation-patterns" title="Patterns de Génération" subtitle="Patterns et champs" >}}
|
||||
{{< /cards >}}
|
||||
|
||||
## Vue d'Ensemble de l'Architecture
|
||||
|
||||
Le système de génération de monde opère en plusieurs phases :
|
||||
|
||||
```
|
||||
Pipeline de Génération de Monde
|
||||
├── Génération du Climat
|
||||
│ └── Attribution des Biomes
|
||||
├── Génération du Terrain
|
||||
│ ├── Fonctions de Densité (forme)
|
||||
│ ├── Material Providers (blocs)
|
||||
│ └── Décoration de Surface
|
||||
├── Génération des Grottes
|
||||
│ ├── Creusement des Grottes
|
||||
│ └── Caractéristiques des Grottes
|
||||
├── Placement des Structures
|
||||
│ ├── Sélection des Prefabs
|
||||
│ └── Positionnement des Prefabs
|
||||
└── Placement des Props
|
||||
├── Végétation
|
||||
└── Objets
|
||||
```
|
||||
|
||||
## Vue d'Ensemble des Packages
|
||||
|
||||
| Package | Fichiers | Description |
|
||||
|---------|----------|-------------|
|
||||
| `loader/` | 75 | Système de chargement de monde |
|
||||
| `util/` | 35 | Utilitaires de génération |
|
||||
| `cave/` | 32 | Génération de grottes |
|
||||
| `climate/` | 12 | Climat et biomes |
|
||||
| `chunk/` | 12 | Génération de chunks |
|
||||
| `prefab/` | 8 | Placement de structures |
|
||||
| `zone/` | 7 | Définitions de zones |
|
||||
| `cache/` | 7 | Cache de génération |
|
||||
|
||||
## Hytale Generator
|
||||
|
||||
Le générateur Hytale intégré fournit la génération de monde par défaut :
|
||||
|
||||
| Package | Fichiers | Description |
|
||||
|---------|----------|-------------|
|
||||
| `assets/` | 232 | Définitions d'assets générateur |
|
||||
| `density/` | 76 | Fonctions de densité |
|
||||
| `materialproviders/` | 29 | Sélection de blocs |
|
||||
| `props/` | 24 | Placement de props |
|
||||
| `patterns/` | 13 | Patterns de génération |
|
||||
| `fields/` | 8 | Génération par champs |
|
||||
|
||||
## Exemple Rapide
|
||||
|
||||
```java
|
||||
// Obtenir le générateur de monde
|
||||
WorldGenerator generator = world.getGenerator();
|
||||
|
||||
// Générer un chunk
|
||||
generator.generateChunk(chunkX, chunkZ);
|
||||
|
||||
// Obtenir le biome à une position
|
||||
Biome biome = generator.getBiome(position);
|
||||
|
||||
// Vérifier si une structure peut être générée
|
||||
boolean canPlace = generator.canPlacePrefab(prefab, position);
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
La génération de monde est configurée via des assets YAML :
|
||||
|
||||
```yaml
|
||||
# worldgen/my_generator.yaml
|
||||
Type: WorldGenerator
|
||||
Id: my_generator
|
||||
Seed: 12345
|
||||
Climate:
|
||||
Type: StandardClimate
|
||||
Biomes:
|
||||
- forest
|
||||
- plains
|
||||
- mountains
|
||||
Density:
|
||||
Type: MultipleDensity
|
||||
Functions:
|
||||
- terrain_base
|
||||
- terrain_hills
|
||||
Prefabs:
|
||||
- Type: Village
|
||||
Frequency: 0.01
|
||||
```
|
||||
252
content/world/worldgen/cave-generation.en.md
Normal file
252
content/world/worldgen/cave-generation.en.md
Normal file
@@ -0,0 +1,252 @@
|
||||
---
|
||||
title: Cave Generation
|
||||
type: docs
|
||||
weight: 2
|
||||
---
|
||||
|
||||
The cave generation system creates underground cave networks, caverns, and subterranean features.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.worldgen.cave`
|
||||
|
||||
## Cave Generator
|
||||
|
||||
The `CaveGenerator` carves out underground spaces:
|
||||
|
||||
```java
|
||||
public class CaveGenerator {
|
||||
// Generate caves for chunk
|
||||
public void generateCaves(GenerationContainer container, int chunkX, int chunkZ);
|
||||
|
||||
// Check if position is in cave
|
||||
public boolean isInCave(int x, int y, int z);
|
||||
|
||||
// Get cave density at position
|
||||
public float getCaveDensity(int x, int y, int z);
|
||||
}
|
||||
```
|
||||
|
||||
## Cave Types
|
||||
|
||||
### Tunnel Caves
|
||||
|
||||
Winding tunnels through terrain:
|
||||
|
||||
```yaml
|
||||
CaveType: Tunnel
|
||||
Width: 3.0
|
||||
Height: 4.0
|
||||
Length: 50-200
|
||||
Frequency: 0.02
|
||||
MinY: 10
|
||||
MaxY: 60
|
||||
```
|
||||
|
||||
### Cavern Caves
|
||||
|
||||
Large open underground spaces:
|
||||
|
||||
```yaml
|
||||
CaveType: Cavern
|
||||
MinRadius: 10
|
||||
MaxRadius: 30
|
||||
MinHeight: 8
|
||||
MaxHeight: 20
|
||||
Frequency: 0.005
|
||||
MinY: 5
|
||||
MaxY: 40
|
||||
```
|
||||
|
||||
### Ravine Caves
|
||||
|
||||
Vertical crack formations:
|
||||
|
||||
```yaml
|
||||
CaveType: Ravine
|
||||
Width: 5-15
|
||||
Depth: 30-60
|
||||
Length: 100-300
|
||||
Frequency: 0.001
|
||||
```
|
||||
|
||||
## Noise-Based Generation
|
||||
|
||||
Caves use 3D noise for natural shapes:
|
||||
|
||||
```java
|
||||
public class CaveNoiseGenerator {
|
||||
private SimplexNoise primaryNoise;
|
||||
private SimplexNoise secondaryNoise;
|
||||
private float threshold;
|
||||
|
||||
public boolean shouldCarve(int x, int y, int z) {
|
||||
float noise1 = primaryNoise.noise3D(x * 0.05f, y * 0.1f, z * 0.05f);
|
||||
float noise2 = secondaryNoise.noise3D(x * 0.02f, y * 0.05f, z * 0.02f);
|
||||
|
||||
float combined = (noise1 + noise2) / 2.0f;
|
||||
return combined > threshold;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Cave Carving
|
||||
|
||||
```java
|
||||
public class CaveCarver {
|
||||
// Carve sphere at position
|
||||
public void carveSphere(GenerationContainer container, Vector3d center, float radius);
|
||||
|
||||
// Carve tunnel between points
|
||||
public void carveTunnel(
|
||||
GenerationContainer container,
|
||||
Vector3d start,
|
||||
Vector3d end,
|
||||
float radius
|
||||
);
|
||||
|
||||
// Carve with noise
|
||||
public void carveWithNoise(
|
||||
GenerationContainer container,
|
||||
Vector3d position,
|
||||
NoiseGenerator noise,
|
||||
float threshold
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Cave Decoration
|
||||
|
||||
After carving, caves are decorated:
|
||||
|
||||
```java
|
||||
public class CaveDecorator {
|
||||
// Add stalactites/stalagmites
|
||||
public void addStalactites(GenerationContainer container, int x, int y, int z);
|
||||
|
||||
// Add crystal formations
|
||||
public void addCrystals(GenerationContainer container, int x, int y, int z);
|
||||
|
||||
// Add water/lava pools
|
||||
public void addPool(GenerationContainer container, int x, int y, int z, FluidType type);
|
||||
|
||||
// Add cave vegetation
|
||||
public void addMushrooms(GenerationContainer container, int x, int y, int z);
|
||||
}
|
||||
```
|
||||
|
||||
## Cave Biomes
|
||||
|
||||
Different cave biomes with unique features:
|
||||
|
||||
```yaml
|
||||
# cave_biomes/crystal_cave.yaml
|
||||
Type: CaveBiome
|
||||
Id: crystal_cave
|
||||
Features:
|
||||
- Type: CrystalCluster
|
||||
Frequency: 0.1
|
||||
MinSize: 2
|
||||
MaxSize: 8
|
||||
- Type: GlowingMushroom
|
||||
Frequency: 0.05
|
||||
AmbientLight: 0.2
|
||||
Blocks:
|
||||
Floor: crystal_stone
|
||||
Ceiling: crystal_stone
|
||||
Walls: smooth_stone
|
||||
```
|
||||
|
||||
## Cave Configuration
|
||||
|
||||
```yaml
|
||||
# worldgen/cave_config.yaml
|
||||
CaveGeneration:
|
||||
Enabled: true
|
||||
Types:
|
||||
- Type: Tunnel
|
||||
Weight: 0.6
|
||||
MinY: 10
|
||||
MaxY: 60
|
||||
- Type: Cavern
|
||||
Weight: 0.3
|
||||
MinY: 5
|
||||
MaxY: 40
|
||||
- Type: Ravine
|
||||
Weight: 0.1
|
||||
MinY: 0
|
||||
MaxY: 64
|
||||
Decoration:
|
||||
Stalactites: true
|
||||
Pools: true
|
||||
Vegetation: true
|
||||
NoiseSettings:
|
||||
Octaves: 4
|
||||
Persistence: 0.5
|
||||
Scale: 0.05
|
||||
```
|
||||
|
||||
## Cave Systems
|
||||
|
||||
Connected cave networks:
|
||||
|
||||
```java
|
||||
public class CaveSystem {
|
||||
private List<CaveNode> nodes;
|
||||
private List<CaveConnection> connections;
|
||||
|
||||
// Generate connected system
|
||||
public void generate(GenerationContainer container) {
|
||||
// Create nodes
|
||||
for (int i = 0; i < nodeCount; i++) {
|
||||
nodes.add(createCaveNode());
|
||||
}
|
||||
|
||||
// Connect nodes
|
||||
for (CaveNode node : nodes) {
|
||||
CaveNode nearest = findNearest(node);
|
||||
connections.add(new CaveConnection(node, nearest));
|
||||
}
|
||||
|
||||
// Carve caves
|
||||
for (CaveNode node : nodes) {
|
||||
carver.carveCavern(container, node.position, node.radius);
|
||||
}
|
||||
|
||||
// Carve tunnels
|
||||
for (CaveConnection conn : connections) {
|
||||
carver.carveTunnel(container, conn.start, conn.end, conn.radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Integration with Terrain
|
||||
|
||||
```java
|
||||
public class TerrainCaveIntegration {
|
||||
// Prevent caves from breaking surface
|
||||
public boolean shouldCarve(int x, int y, int z, int surfaceY) {
|
||||
// Don't carve within 5 blocks of surface
|
||||
if (y > surfaceY - 5) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't carve below bedrock level
|
||||
if (y < 5) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return caveNoise.shouldCarve(x, y, z);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Cave Guidelines:**
|
||||
- Balance cave frequency with world density
|
||||
- Use noise for natural-looking shapes
|
||||
- Connect cave systems for exploration
|
||||
- Add decoration for visual interest
|
||||
- Consider performance with large caverns
|
||||
{{< /callout >}}
|
||||
252
content/world/worldgen/cave-generation.fr.md
Normal file
252
content/world/worldgen/cave-generation.fr.md
Normal file
@@ -0,0 +1,252 @@
|
||||
---
|
||||
title: Génération de Grottes
|
||||
type: docs
|
||||
weight: 2
|
||||
---
|
||||
|
||||
Le système de génération de grottes crée des réseaux de grottes souterraines, des cavernes et des caractéristiques souterraines.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.worldgen.cave`
|
||||
|
||||
## Cave Generator
|
||||
|
||||
Le `CaveGenerator` creuse les espaces souterrains :
|
||||
|
||||
```java
|
||||
public class CaveGenerator {
|
||||
// Générer des grottes pour un chunk
|
||||
public void generateCaves(GenerationContainer container, int chunkX, int chunkZ);
|
||||
|
||||
// Vérifier si une position est dans une grotte
|
||||
public boolean isInCave(int x, int y, int z);
|
||||
|
||||
// Obtenir la densité de grotte à une position
|
||||
public float getCaveDensity(int x, int y, int z);
|
||||
}
|
||||
```
|
||||
|
||||
## Types de Grottes
|
||||
|
||||
### Grottes Tunnel
|
||||
|
||||
Tunnels sinueux à travers le terrain :
|
||||
|
||||
```yaml
|
||||
CaveType: Tunnel
|
||||
Width: 3.0
|
||||
Height: 4.0
|
||||
Length: 50-200
|
||||
Frequency: 0.02
|
||||
MinY: 10
|
||||
MaxY: 60
|
||||
```
|
||||
|
||||
### Grottes Caverne
|
||||
|
||||
Grands espaces souterrains ouverts :
|
||||
|
||||
```yaml
|
||||
CaveType: Cavern
|
||||
MinRadius: 10
|
||||
MaxRadius: 30
|
||||
MinHeight: 8
|
||||
MaxHeight: 20
|
||||
Frequency: 0.005
|
||||
MinY: 5
|
||||
MaxY: 40
|
||||
```
|
||||
|
||||
### Grottes Ravine
|
||||
|
||||
Formations de fissures verticales :
|
||||
|
||||
```yaml
|
||||
CaveType: Ravine
|
||||
Width: 5-15
|
||||
Depth: 30-60
|
||||
Length: 100-300
|
||||
Frequency: 0.001
|
||||
```
|
||||
|
||||
## Génération Basée sur le Bruit
|
||||
|
||||
Les grottes utilisent du bruit 3D pour des formes naturelles :
|
||||
|
||||
```java
|
||||
public class CaveNoiseGenerator {
|
||||
private SimplexNoise primaryNoise;
|
||||
private SimplexNoise secondaryNoise;
|
||||
private float threshold;
|
||||
|
||||
public boolean shouldCarve(int x, int y, int z) {
|
||||
float noise1 = primaryNoise.noise3D(x * 0.05f, y * 0.1f, z * 0.05f);
|
||||
float noise2 = secondaryNoise.noise3D(x * 0.02f, y * 0.05f, z * 0.02f);
|
||||
|
||||
float combined = (noise1 + noise2) / 2.0f;
|
||||
return combined > threshold;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Creusement de Grottes
|
||||
|
||||
```java
|
||||
public class CaveCarver {
|
||||
// Creuser une sphère à une position
|
||||
public void carveSphere(GenerationContainer container, Vector3d center, float radius);
|
||||
|
||||
// Creuser un tunnel entre deux points
|
||||
public void carveTunnel(
|
||||
GenerationContainer container,
|
||||
Vector3d start,
|
||||
Vector3d end,
|
||||
float radius
|
||||
);
|
||||
|
||||
// Creuser avec du bruit
|
||||
public void carveWithNoise(
|
||||
GenerationContainer container,
|
||||
Vector3d position,
|
||||
NoiseGenerator noise,
|
||||
float threshold
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Décoration de Grottes
|
||||
|
||||
Après le creusement, les grottes sont décorées :
|
||||
|
||||
```java
|
||||
public class CaveDecorator {
|
||||
// Ajouter stalactites/stalagmites
|
||||
public void addStalactites(GenerationContainer container, int x, int y, int z);
|
||||
|
||||
// Ajouter des formations de cristaux
|
||||
public void addCrystals(GenerationContainer container, int x, int y, int z);
|
||||
|
||||
// Ajouter des bassins d'eau/lave
|
||||
public void addPool(GenerationContainer container, int x, int y, int z, FluidType type);
|
||||
|
||||
// Ajouter de la végétation de grotte
|
||||
public void addMushrooms(GenerationContainer container, int x, int y, int z);
|
||||
}
|
||||
```
|
||||
|
||||
## Biomes de Grottes
|
||||
|
||||
Différents biomes de grottes avec des caractéristiques uniques :
|
||||
|
||||
```yaml
|
||||
# cave_biomes/crystal_cave.yaml
|
||||
Type: CaveBiome
|
||||
Id: crystal_cave
|
||||
Features:
|
||||
- Type: CrystalCluster
|
||||
Frequency: 0.1
|
||||
MinSize: 2
|
||||
MaxSize: 8
|
||||
- Type: GlowingMushroom
|
||||
Frequency: 0.05
|
||||
AmbientLight: 0.2
|
||||
Blocks:
|
||||
Floor: crystal_stone
|
||||
Ceiling: crystal_stone
|
||||
Walls: smooth_stone
|
||||
```
|
||||
|
||||
## Configuration des Grottes
|
||||
|
||||
```yaml
|
||||
# worldgen/cave_config.yaml
|
||||
CaveGeneration:
|
||||
Enabled: true
|
||||
Types:
|
||||
- Type: Tunnel
|
||||
Weight: 0.6
|
||||
MinY: 10
|
||||
MaxY: 60
|
||||
- Type: Cavern
|
||||
Weight: 0.3
|
||||
MinY: 5
|
||||
MaxY: 40
|
||||
- Type: Ravine
|
||||
Weight: 0.1
|
||||
MinY: 0
|
||||
MaxY: 64
|
||||
Decoration:
|
||||
Stalactites: true
|
||||
Pools: true
|
||||
Vegetation: true
|
||||
NoiseSettings:
|
||||
Octaves: 4
|
||||
Persistence: 0.5
|
||||
Scale: 0.05
|
||||
```
|
||||
|
||||
## Systèmes de Grottes
|
||||
|
||||
Réseaux de grottes connectées :
|
||||
|
||||
```java
|
||||
public class CaveSystem {
|
||||
private List<CaveNode> nodes;
|
||||
private List<CaveConnection> connections;
|
||||
|
||||
// Générer un système connecté
|
||||
public void generate(GenerationContainer container) {
|
||||
// Créer les nœuds
|
||||
for (int i = 0; i < nodeCount; i++) {
|
||||
nodes.add(createCaveNode());
|
||||
}
|
||||
|
||||
// Connecter les nœuds
|
||||
for (CaveNode node : nodes) {
|
||||
CaveNode nearest = findNearest(node);
|
||||
connections.add(new CaveConnection(node, nearest));
|
||||
}
|
||||
|
||||
// Creuser les cavernes
|
||||
for (CaveNode node : nodes) {
|
||||
carver.carveCavern(container, node.position, node.radius);
|
||||
}
|
||||
|
||||
// Creuser les tunnels
|
||||
for (CaveConnection conn : connections) {
|
||||
carver.carveTunnel(container, conn.start, conn.end, conn.radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Intégration avec le Terrain
|
||||
|
||||
```java
|
||||
public class TerrainCaveIntegration {
|
||||
// Empêcher les grottes de percer la surface
|
||||
public boolean shouldCarve(int x, int y, int z, int surfaceY) {
|
||||
// Ne pas creuser à moins de 5 blocs de la surface
|
||||
if (y > surfaceY - 5) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ne pas creuser sous le niveau de bedrock
|
||||
if (y < 5) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return caveNoise.shouldCarve(x, y, z);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives des Grottes :**
|
||||
- Équilibrez la fréquence des grottes avec la densité du monde
|
||||
- Utilisez le bruit pour des formes naturelles
|
||||
- Connectez les systèmes de grottes pour l'exploration
|
||||
- Ajoutez de la décoration pour l'intérêt visuel
|
||||
- Considérez les performances avec les grandes cavernes
|
||||
{{< /callout >}}
|
||||
222
content/world/worldgen/chunk-generation.en.md
Normal file
222
content/world/worldgen/chunk-generation.en.md
Normal file
@@ -0,0 +1,222 @@
|
||||
---
|
||||
title: Chunk Generation
|
||||
type: docs
|
||||
weight: 4
|
||||
---
|
||||
|
||||
Chunk generation handles the block-by-block creation of terrain within each 16x16 chunk.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.worldgen.chunk`
|
||||
|
||||
## ChunkGenerator
|
||||
|
||||
The `ChunkGenerator` creates terrain blocks:
|
||||
|
||||
```java
|
||||
public class ChunkGenerator {
|
||||
// Generate terrain for chunk
|
||||
public void generate(GenerationContainer container, int chunkX, int chunkZ);
|
||||
|
||||
// Get height at position
|
||||
public int getHeight(int x, int z);
|
||||
|
||||
// Get block at position
|
||||
public BlockType getBlock(int x, int y, int z);
|
||||
}
|
||||
```
|
||||
|
||||
## Generation Stages
|
||||
|
||||
Chunk generation occurs in stages:
|
||||
|
||||
```
|
||||
Generation Stages
|
||||
├── 1. Height Map
|
||||
│ └── Calculate surface heights
|
||||
├── 2. Base Terrain
|
||||
│ └── Fill solid blocks
|
||||
├── 3. Surface Layer
|
||||
│ └── Apply biome surface blocks
|
||||
├── 4. Carving
|
||||
│ └── Remove blocks for caves/features
|
||||
└── 5. Decoration
|
||||
└── Add vegetation, ores, etc.
|
||||
```
|
||||
|
||||
## Height Map Generation
|
||||
|
||||
```java
|
||||
public class HeightMapGenerator {
|
||||
private NoiseGenerator baseNoise;
|
||||
private NoiseGenerator detailNoise;
|
||||
|
||||
public int getHeight(int x, int z) {
|
||||
// Base terrain height
|
||||
float base = baseNoise.noise2D(x * 0.01f, z * 0.01f);
|
||||
|
||||
// Detail variation
|
||||
float detail = detailNoise.noise2D(x * 0.1f, z * 0.1f) * 0.3f;
|
||||
|
||||
// Convert to block height
|
||||
int height = (int) ((base + detail + 1.0f) * 32.0f) + 64;
|
||||
return Math.clamp(height, 1, 255);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Terrain Fill
|
||||
|
||||
```java
|
||||
public class TerrainFiller {
|
||||
public void fill(GenerationContainer container, int x, int z, int height) {
|
||||
Biome biome = container.getBiome(x, z);
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
BlockType block;
|
||||
|
||||
if (y == 0) {
|
||||
block = BlockTypes.BEDROCK;
|
||||
} else if (y < height - 4) {
|
||||
block = biome.getStoneBlock();
|
||||
} else if (y < height - 1) {
|
||||
block = biome.getSubsurfaceBlock();
|
||||
} else {
|
||||
block = biome.getSurfaceBlock();
|
||||
}
|
||||
|
||||
container.setBlock(x, y, z, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Surface Decoration
|
||||
|
||||
```java
|
||||
public class SurfaceDecorator {
|
||||
public void decorate(GenerationContainer container, int x, int z) {
|
||||
int surfaceY = container.getHeight(x, z);
|
||||
Biome biome = container.getBiome(x, z);
|
||||
|
||||
// Add surface features based on biome
|
||||
for (SurfaceFeature feature : biome.getSurfaceFeatures()) {
|
||||
if (random.nextFloat() < feature.getDensity()) {
|
||||
feature.place(container, x, surfaceY + 1, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Block Palette
|
||||
|
||||
Chunks use a block palette for efficient storage:
|
||||
|
||||
```java
|
||||
public class BlockPalette {
|
||||
private List<BlockType> palette;
|
||||
private short[] blockData;
|
||||
|
||||
// Get block at local position
|
||||
public BlockType getBlock(int localX, int localY, int localZ) {
|
||||
int index = localX + localZ * 16 + localY * 256;
|
||||
short paletteIndex = blockData[index];
|
||||
return palette.get(paletteIndex);
|
||||
}
|
||||
|
||||
// Set block at local position
|
||||
public void setBlock(int localX, int localY, int localZ, BlockType type) {
|
||||
int index = localX + localZ * 16 + localY * 256;
|
||||
int paletteIndex = palette.indexOf(type);
|
||||
if (paletteIndex == -1) {
|
||||
paletteIndex = palette.size();
|
||||
palette.add(type);
|
||||
}
|
||||
blockData[index] = (short) paletteIndex;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Section-Based Generation
|
||||
|
||||
Chunks are divided into 16-block tall sections:
|
||||
|
||||
```java
|
||||
public class ChunkSection {
|
||||
private static final int SIZE = 16 * 16 * 16;
|
||||
private BlockPalette palette;
|
||||
private byte[] lightData;
|
||||
|
||||
public boolean isEmpty() {
|
||||
return palette.size() == 1 && palette.get(0) == BlockTypes.AIR;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Ore Generation
|
||||
|
||||
```java
|
||||
public class OreGenerator {
|
||||
public void generateOres(GenerationContainer container, int chunkX, int chunkZ) {
|
||||
for (OreConfig ore : oreConfigs) {
|
||||
int count = random.nextInt(ore.maxVeins - ore.minVeins) + ore.minVeins;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
int x = chunkX * 16 + random.nextInt(16);
|
||||
int y = random.nextInt(ore.maxY - ore.minY) + ore.minY;
|
||||
int z = chunkZ * 16 + random.nextInt(16);
|
||||
|
||||
generateOreVein(container, x, y, z, ore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateOreVein(GenerationContainer container, int x, int y, int z, OreConfig ore) {
|
||||
int size = random.nextInt(ore.maxSize - ore.minSize) + ore.minSize;
|
||||
// Generate blob of ore blocks
|
||||
for (int i = 0; i < size; i++) {
|
||||
int dx = random.nextInt(3) - 1;
|
||||
int dy = random.nextInt(3) - 1;
|
||||
int dz = random.nextInt(3) - 1;
|
||||
if (container.getBlock(x + dx, y + dy, z + dz) == ore.replaceBlock) {
|
||||
container.setBlock(x + dx, y + dy, z + dz, ore.oreBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# worldgen/chunk_config.yaml
|
||||
ChunkGeneration:
|
||||
HeightNoise:
|
||||
Octaves: 6
|
||||
Persistence: 0.5
|
||||
Scale: 0.01
|
||||
SeaLevel: 64
|
||||
BedrockLayers: 5
|
||||
Ores:
|
||||
- Type: iron_ore
|
||||
MinY: 0
|
||||
MaxY: 64
|
||||
VeinsPerChunk: 20
|
||||
VeinSize: 9
|
||||
- Type: diamond_ore
|
||||
MinY: 0
|
||||
MaxY: 16
|
||||
VeinsPerChunk: 1
|
||||
VeinSize: 8
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Chunk Guidelines:**
|
||||
- Use noise for natural terrain variation
|
||||
- Apply biome-specific blocks to surfaces
|
||||
- Generate features after base terrain
|
||||
- Use palettes for memory efficiency
|
||||
- Consider section-based optimizations
|
||||
{{< /callout >}}
|
||||
222
content/world/worldgen/chunk-generation.fr.md
Normal file
222
content/world/worldgen/chunk-generation.fr.md
Normal file
@@ -0,0 +1,222 @@
|
||||
---
|
||||
title: Génération de Chunks
|
||||
type: docs
|
||||
weight: 4
|
||||
---
|
||||
|
||||
La génération de chunks gère la création bloc par bloc du terrain dans chaque chunk 16x16.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.worldgen.chunk`
|
||||
|
||||
## ChunkGenerator
|
||||
|
||||
Le `ChunkGenerator` crée les blocs de terrain :
|
||||
|
||||
```java
|
||||
public class ChunkGenerator {
|
||||
// Générer le terrain pour un chunk
|
||||
public void generate(GenerationContainer container, int chunkX, int chunkZ);
|
||||
|
||||
// Obtenir la hauteur à une position
|
||||
public int getHeight(int x, int z);
|
||||
|
||||
// Obtenir le bloc à une position
|
||||
public BlockType getBlock(int x, int y, int z);
|
||||
}
|
||||
```
|
||||
|
||||
## Étapes de Génération
|
||||
|
||||
La génération de chunk se fait par étapes :
|
||||
|
||||
```
|
||||
Étapes de Génération
|
||||
├── 1. Carte de Hauteur
|
||||
│ └── Calculer les hauteurs de surface
|
||||
├── 2. Terrain de Base
|
||||
│ └── Remplir les blocs solides
|
||||
├── 3. Couche de Surface
|
||||
│ └── Appliquer les blocs de surface du biome
|
||||
├── 4. Creusement
|
||||
│ └── Supprimer les blocs pour grottes/features
|
||||
└── 5. Décoration
|
||||
└── Ajouter végétation, minerais, etc.
|
||||
```
|
||||
|
||||
## Génération de Carte de Hauteur
|
||||
|
||||
```java
|
||||
public class HeightMapGenerator {
|
||||
private NoiseGenerator baseNoise;
|
||||
private NoiseGenerator detailNoise;
|
||||
|
||||
public int getHeight(int x, int z) {
|
||||
// Hauteur de terrain de base
|
||||
float base = baseNoise.noise2D(x * 0.01f, z * 0.01f);
|
||||
|
||||
// Variation de détail
|
||||
float detail = detailNoise.noise2D(x * 0.1f, z * 0.1f) * 0.3f;
|
||||
|
||||
// Convertir en hauteur de bloc
|
||||
int height = (int) ((base + detail + 1.0f) * 32.0f) + 64;
|
||||
return Math.clamp(height, 1, 255);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Remplissage du Terrain
|
||||
|
||||
```java
|
||||
public class TerrainFiller {
|
||||
public void fill(GenerationContainer container, int x, int z, int height) {
|
||||
Biome biome = container.getBiome(x, z);
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
BlockType block;
|
||||
|
||||
if (y == 0) {
|
||||
block = BlockTypes.BEDROCK;
|
||||
} else if (y < height - 4) {
|
||||
block = biome.getStoneBlock();
|
||||
} else if (y < height - 1) {
|
||||
block = biome.getSubsurfaceBlock();
|
||||
} else {
|
||||
block = biome.getSurfaceBlock();
|
||||
}
|
||||
|
||||
container.setBlock(x, y, z, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Décoration de Surface
|
||||
|
||||
```java
|
||||
public class SurfaceDecorator {
|
||||
public void decorate(GenerationContainer container, int x, int z) {
|
||||
int surfaceY = container.getHeight(x, z);
|
||||
Biome biome = container.getBiome(x, z);
|
||||
|
||||
// Ajouter des features de surface selon le biome
|
||||
for (SurfaceFeature feature : biome.getSurfaceFeatures()) {
|
||||
if (random.nextFloat() < feature.getDensity()) {
|
||||
feature.place(container, x, surfaceY + 1, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Palette de Blocs
|
||||
|
||||
Les chunks utilisent une palette de blocs pour un stockage efficace :
|
||||
|
||||
```java
|
||||
public class BlockPalette {
|
||||
private List<BlockType> palette;
|
||||
private short[] blockData;
|
||||
|
||||
// Obtenir le bloc à une position locale
|
||||
public BlockType getBlock(int localX, int localY, int localZ) {
|
||||
int index = localX + localZ * 16 + localY * 256;
|
||||
short paletteIndex = blockData[index];
|
||||
return palette.get(paletteIndex);
|
||||
}
|
||||
|
||||
// Définir le bloc à une position locale
|
||||
public void setBlock(int localX, int localY, int localZ, BlockType type) {
|
||||
int index = localX + localZ * 16 + localY * 256;
|
||||
int paletteIndex = palette.indexOf(type);
|
||||
if (paletteIndex == -1) {
|
||||
paletteIndex = palette.size();
|
||||
palette.add(type);
|
||||
}
|
||||
blockData[index] = (short) paletteIndex;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Génération par Sections
|
||||
|
||||
Les chunks sont divisés en sections de 16 blocs de haut :
|
||||
|
||||
```java
|
||||
public class ChunkSection {
|
||||
private static final int SIZE = 16 * 16 * 16;
|
||||
private BlockPalette palette;
|
||||
private byte[] lightData;
|
||||
|
||||
public boolean isEmpty() {
|
||||
return palette.size() == 1 && palette.get(0) == BlockTypes.AIR;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Génération de Minerais
|
||||
|
||||
```java
|
||||
public class OreGenerator {
|
||||
public void generateOres(GenerationContainer container, int chunkX, int chunkZ) {
|
||||
for (OreConfig ore : oreConfigs) {
|
||||
int count = random.nextInt(ore.maxVeins - ore.minVeins) + ore.minVeins;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
int x = chunkX * 16 + random.nextInt(16);
|
||||
int y = random.nextInt(ore.maxY - ore.minY) + ore.minY;
|
||||
int z = chunkZ * 16 + random.nextInt(16);
|
||||
|
||||
generateOreVein(container, x, y, z, ore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateOreVein(GenerationContainer container, int x, int y, int z, OreConfig ore) {
|
||||
int size = random.nextInt(ore.maxSize - ore.minSize) + ore.minSize;
|
||||
// Générer une grappe de blocs de minerai
|
||||
for (int i = 0; i < size; i++) {
|
||||
int dx = random.nextInt(3) - 1;
|
||||
int dy = random.nextInt(3) - 1;
|
||||
int dz = random.nextInt(3) - 1;
|
||||
if (container.getBlock(x + dx, y + dy, z + dz) == ore.replaceBlock) {
|
||||
container.setBlock(x + dx, y + dy, z + dz, ore.oreBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# worldgen/chunk_config.yaml
|
||||
ChunkGeneration:
|
||||
HeightNoise:
|
||||
Octaves: 6
|
||||
Persistence: 0.5
|
||||
Scale: 0.01
|
||||
SeaLevel: 64
|
||||
BedrockLayers: 5
|
||||
Ores:
|
||||
- Type: iron_ore
|
||||
MinY: 0
|
||||
MaxY: 64
|
||||
VeinsPerChunk: 20
|
||||
VeinSize: 9
|
||||
- Type: diamond_ore
|
||||
MinY: 0
|
||||
MaxY: 16
|
||||
VeinsPerChunk: 1
|
||||
VeinSize: 8
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives des Chunks :**
|
||||
- Utilisez le bruit pour une variation de terrain naturelle
|
||||
- Appliquez des blocs spécifiques au biome sur les surfaces
|
||||
- Générez les features après le terrain de base
|
||||
- Utilisez des palettes pour l'efficacité mémoire
|
||||
- Considérez les optimisations basées sur les sections
|
||||
{{< /callout >}}
|
||||
238
content/world/worldgen/climate-biomes.en.md
Normal file
238
content/world/worldgen/climate-biomes.en.md
Normal file
@@ -0,0 +1,238 @@
|
||||
---
|
||||
title: Climate & Biomes
|
||||
type: docs
|
||||
weight: 3
|
||||
---
|
||||
|
||||
The climate and biome system determines biome distribution across the world based on temperature, humidity, and other factors.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.worldgen.climate`
|
||||
|
||||
## Climate System
|
||||
|
||||
The `ClimateGenerator` creates climate maps:
|
||||
|
||||
```java
|
||||
public class ClimateGenerator {
|
||||
// Get temperature at position
|
||||
public float getTemperature(int x, int z);
|
||||
|
||||
// Get humidity at position
|
||||
public float getHumidity(int x, int z);
|
||||
|
||||
// Get altitude factor
|
||||
public float getAltitude(int x, int y, int z);
|
||||
|
||||
// Get climate data
|
||||
public ClimateData getClimate(int x, int z);
|
||||
}
|
||||
```
|
||||
|
||||
## ClimateData
|
||||
|
||||
```java
|
||||
public class ClimateData {
|
||||
private float temperature; // -1.0 (cold) to 1.0 (hot)
|
||||
private float humidity; // 0.0 (dry) to 1.0 (wet)
|
||||
private float altitude; // Normalized height
|
||||
private float continentality; // Distance from ocean
|
||||
|
||||
public Biome getBiome();
|
||||
}
|
||||
```
|
||||
|
||||
## Biome Selection
|
||||
|
||||
Biomes are selected based on climate parameters:
|
||||
|
||||
```java
|
||||
public class BiomeSelector {
|
||||
private Map<BiomeCondition, Biome> biomeMap;
|
||||
|
||||
public Biome selectBiome(ClimateData climate) {
|
||||
for (Map.Entry<BiomeCondition, Biome> entry : biomeMap.entrySet()) {
|
||||
if (entry.getKey().matches(climate)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return defaultBiome;
|
||||
}
|
||||
}
|
||||
|
||||
public class BiomeCondition {
|
||||
private Range temperatureRange;
|
||||
private Range humidityRange;
|
||||
private Range altitudeRange;
|
||||
|
||||
public boolean matches(ClimateData climate) {
|
||||
return temperatureRange.contains(climate.temperature)
|
||||
&& humidityRange.contains(climate.humidity)
|
||||
&& altitudeRange.contains(climate.altitude);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Biome Definition
|
||||
|
||||
```yaml
|
||||
# biomes/forest.yaml
|
||||
Type: Biome
|
||||
Id: forest
|
||||
DisplayName: "Forest"
|
||||
Climate:
|
||||
Temperature: [0.3, 0.7]
|
||||
Humidity: [0.4, 0.8]
|
||||
Terrain:
|
||||
SurfaceBlock: grass
|
||||
SubsurfaceBlock: dirt
|
||||
StoneBlock: stone
|
||||
Features:
|
||||
- Type: Tree
|
||||
Density: 0.3
|
||||
Variants: [oak, birch]
|
||||
- Type: Grass
|
||||
Density: 0.8
|
||||
- Type: Flower
|
||||
Density: 0.1
|
||||
Mobs:
|
||||
- Type: deer
|
||||
SpawnWeight: 10
|
||||
- Type: rabbit
|
||||
SpawnWeight: 20
|
||||
AmbientSounds:
|
||||
- birds
|
||||
- wind_leaves
|
||||
```
|
||||
|
||||
## Temperature Zones
|
||||
|
||||
```java
|
||||
public enum TemperatureZone {
|
||||
FROZEN(-1.0f, -0.5f), // Ice, snow
|
||||
COLD(-0.5f, 0.0f), // Taiga, tundra
|
||||
TEMPERATE(0.0f, 0.5f), // Forest, plains
|
||||
WARM(0.5f, 0.8f), // Savanna, jungle
|
||||
HOT(0.8f, 1.0f); // Desert, volcanic
|
||||
|
||||
private float min;
|
||||
private float max;
|
||||
}
|
||||
```
|
||||
|
||||
## Humidity Zones
|
||||
|
||||
```java
|
||||
public enum HumidityZone {
|
||||
ARID(0.0f, 0.2f), // Desert
|
||||
DRY(0.2f, 0.4f), // Savanna, steppe
|
||||
MODERATE(0.4f, 0.6f), // Plains, forest
|
||||
HUMID(0.6f, 0.8f), // Jungle, swamp
|
||||
WET(0.8f, 1.0f); // Rainforest, marsh
|
||||
}
|
||||
```
|
||||
|
||||
## Biome Blending
|
||||
|
||||
Smooth transitions between biomes:
|
||||
|
||||
```java
|
||||
public class BiomeBlender {
|
||||
private int blendRadius;
|
||||
|
||||
public BiomeBlendData blend(int x, int z) {
|
||||
Map<Biome, Float> weights = new HashMap<>();
|
||||
|
||||
// Sample surrounding biomes
|
||||
for (int dx = -blendRadius; dx <= blendRadius; dx++) {
|
||||
for (int dz = -blendRadius; dz <= blendRadius; dz++) {
|
||||
Biome biome = getBiome(x + dx, z + dz);
|
||||
float distance = (float) Math.sqrt(dx * dx + dz * dz);
|
||||
float weight = 1.0f / (1.0f + distance);
|
||||
weights.merge(biome, weight, Float::sum);
|
||||
}
|
||||
}
|
||||
|
||||
return new BiomeBlendData(weights);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Climate Noise
|
||||
|
||||
```java
|
||||
public class ClimateNoiseGenerator {
|
||||
private SimplexNoise temperatureNoise;
|
||||
private SimplexNoise humidityNoise;
|
||||
|
||||
public ClimateNoiseGenerator(long seed) {
|
||||
temperatureNoise = new SimplexNoise(seed);
|
||||
humidityNoise = new SimplexNoise(seed + 1);
|
||||
}
|
||||
|
||||
public float getTemperature(int x, int z) {
|
||||
// Large scale temperature variation
|
||||
float base = temperatureNoise.noise2D(x * 0.001f, z * 0.001f);
|
||||
// Small scale variation
|
||||
float detail = temperatureNoise.noise2D(x * 0.01f, z * 0.01f) * 0.2f;
|
||||
return base + detail;
|
||||
}
|
||||
|
||||
public float getHumidity(int x, int z) {
|
||||
return humidityNoise.noise2D(x * 0.002f, z * 0.002f);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Altitude Effects
|
||||
|
||||
```java
|
||||
public class AltitudeClimateModifier {
|
||||
// Temperature decreases with altitude
|
||||
public float modifyTemperature(float baseTemp, int altitude) {
|
||||
float altitudeFactor = altitude / 256.0f;
|
||||
return baseTemp - (altitudeFactor * 0.5f);
|
||||
}
|
||||
|
||||
// Humidity varies with altitude
|
||||
public float modifyHumidity(float baseHumidity, int altitude) {
|
||||
if (altitude < 64) {
|
||||
return baseHumidity * 1.2f; // More humid at low altitudes
|
||||
} else if (altitude > 128) {
|
||||
return baseHumidity * 0.6f; // Drier at high altitudes
|
||||
}
|
||||
return baseHumidity;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# worldgen/climate_config.yaml
|
||||
Climate:
|
||||
NoiseScale: 0.001
|
||||
TemperatureRange: [-1.0, 1.0]
|
||||
HumidityRange: [0.0, 1.0]
|
||||
BlendRadius: 8
|
||||
AltitudeEffect: true
|
||||
Biomes:
|
||||
- Id: forest
|
||||
Temperature: [0.3, 0.7]
|
||||
Humidity: [0.4, 0.8]
|
||||
- Id: desert
|
||||
Temperature: [0.7, 1.0]
|
||||
Humidity: [0.0, 0.3]
|
||||
- Id: tundra
|
||||
Temperature: [-1.0, -0.3]
|
||||
Humidity: [0.2, 0.6]
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Climate Guidelines:**
|
||||
- Use smooth noise for natural climate transitions
|
||||
- Consider altitude when determining biomes
|
||||
- Blend biomes for seamless transitions
|
||||
- Test biome distribution across large areas
|
||||
{{< /callout >}}
|
||||
238
content/world/worldgen/climate-biomes.fr.md
Normal file
238
content/world/worldgen/climate-biomes.fr.md
Normal file
@@ -0,0 +1,238 @@
|
||||
---
|
||||
title: Climat & Biomes
|
||||
type: docs
|
||||
weight: 3
|
||||
---
|
||||
|
||||
Le système de climat et de biomes détermine la distribution des biomes à travers le monde basée sur la température, l'humidité et d'autres facteurs.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.worldgen.climate`
|
||||
|
||||
## Système de Climat
|
||||
|
||||
Le `ClimateGenerator` crée des cartes de climat :
|
||||
|
||||
```java
|
||||
public class ClimateGenerator {
|
||||
// Obtenir la température à une position
|
||||
public float getTemperature(int x, int z);
|
||||
|
||||
// Obtenir l'humidité à une position
|
||||
public float getHumidity(int x, int z);
|
||||
|
||||
// Obtenir le facteur d'altitude
|
||||
public float getAltitude(int x, int y, int z);
|
||||
|
||||
// Obtenir les données climatiques
|
||||
public ClimateData getClimate(int x, int z);
|
||||
}
|
||||
```
|
||||
|
||||
## ClimateData
|
||||
|
||||
```java
|
||||
public class ClimateData {
|
||||
private float temperature; // -1.0 (froid) à 1.0 (chaud)
|
||||
private float humidity; // 0.0 (sec) à 1.0 (humide)
|
||||
private float altitude; // Hauteur normalisée
|
||||
private float continentality; // Distance de l'océan
|
||||
|
||||
public Biome getBiome();
|
||||
}
|
||||
```
|
||||
|
||||
## Sélection de Biome
|
||||
|
||||
Les biomes sont sélectionnés selon les paramètres climatiques :
|
||||
|
||||
```java
|
||||
public class BiomeSelector {
|
||||
private Map<BiomeCondition, Biome> biomeMap;
|
||||
|
||||
public Biome selectBiome(ClimateData climate) {
|
||||
for (Map.Entry<BiomeCondition, Biome> entry : biomeMap.entrySet()) {
|
||||
if (entry.getKey().matches(climate)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return defaultBiome;
|
||||
}
|
||||
}
|
||||
|
||||
public class BiomeCondition {
|
||||
private Range temperatureRange;
|
||||
private Range humidityRange;
|
||||
private Range altitudeRange;
|
||||
|
||||
public boolean matches(ClimateData climate) {
|
||||
return temperatureRange.contains(climate.temperature)
|
||||
&& humidityRange.contains(climate.humidity)
|
||||
&& altitudeRange.contains(climate.altitude);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Définition de Biome
|
||||
|
||||
```yaml
|
||||
# biomes/forest.yaml
|
||||
Type: Biome
|
||||
Id: forest
|
||||
DisplayName: "Forêt"
|
||||
Climate:
|
||||
Temperature: [0.3, 0.7]
|
||||
Humidity: [0.4, 0.8]
|
||||
Terrain:
|
||||
SurfaceBlock: grass
|
||||
SubsurfaceBlock: dirt
|
||||
StoneBlock: stone
|
||||
Features:
|
||||
- Type: Tree
|
||||
Density: 0.3
|
||||
Variants: [oak, birch]
|
||||
- Type: Grass
|
||||
Density: 0.8
|
||||
- Type: Flower
|
||||
Density: 0.1
|
||||
Mobs:
|
||||
- Type: deer
|
||||
SpawnWeight: 10
|
||||
- Type: rabbit
|
||||
SpawnWeight: 20
|
||||
AmbientSounds:
|
||||
- birds
|
||||
- wind_leaves
|
||||
```
|
||||
|
||||
## Zones de Température
|
||||
|
||||
```java
|
||||
public enum TemperatureZone {
|
||||
FROZEN(-1.0f, -0.5f), // Glace, neige
|
||||
COLD(-0.5f, 0.0f), // Taïga, toundra
|
||||
TEMPERATE(0.0f, 0.5f), // Forêt, plaines
|
||||
WARM(0.5f, 0.8f), // Savane, jungle
|
||||
HOT(0.8f, 1.0f); // Désert, volcanique
|
||||
|
||||
private float min;
|
||||
private float max;
|
||||
}
|
||||
```
|
||||
|
||||
## Zones d'Humidité
|
||||
|
||||
```java
|
||||
public enum HumidityZone {
|
||||
ARID(0.0f, 0.2f), // Désert
|
||||
DRY(0.2f, 0.4f), // Savane, steppe
|
||||
MODERATE(0.4f, 0.6f), // Plaines, forêt
|
||||
HUMID(0.6f, 0.8f), // Jungle, marais
|
||||
WET(0.8f, 1.0f); // Forêt tropicale, marécage
|
||||
}
|
||||
```
|
||||
|
||||
## Mélange de Biomes
|
||||
|
||||
Transitions douces entre biomes :
|
||||
|
||||
```java
|
||||
public class BiomeBlender {
|
||||
private int blendRadius;
|
||||
|
||||
public BiomeBlendData blend(int x, int z) {
|
||||
Map<Biome, Float> weights = new HashMap<>();
|
||||
|
||||
// Échantillonner les biomes environnants
|
||||
for (int dx = -blendRadius; dx <= blendRadius; dx++) {
|
||||
for (int dz = -blendRadius; dz <= blendRadius; dz++) {
|
||||
Biome biome = getBiome(x + dx, z + dz);
|
||||
float distance = (float) Math.sqrt(dx * dx + dz * dz);
|
||||
float weight = 1.0f / (1.0f + distance);
|
||||
weights.merge(biome, weight, Float::sum);
|
||||
}
|
||||
}
|
||||
|
||||
return new BiomeBlendData(weights);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Bruit Climatique
|
||||
|
||||
```java
|
||||
public class ClimateNoiseGenerator {
|
||||
private SimplexNoise temperatureNoise;
|
||||
private SimplexNoise humidityNoise;
|
||||
|
||||
public ClimateNoiseGenerator(long seed) {
|
||||
temperatureNoise = new SimplexNoise(seed);
|
||||
humidityNoise = new SimplexNoise(seed + 1);
|
||||
}
|
||||
|
||||
public float getTemperature(int x, int z) {
|
||||
// Variation de température à grande échelle
|
||||
float base = temperatureNoise.noise2D(x * 0.001f, z * 0.001f);
|
||||
// Variation à petite échelle
|
||||
float detail = temperatureNoise.noise2D(x * 0.01f, z * 0.01f) * 0.2f;
|
||||
return base + detail;
|
||||
}
|
||||
|
||||
public float getHumidity(int x, int z) {
|
||||
return humidityNoise.noise2D(x * 0.002f, z * 0.002f);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Effets d'Altitude
|
||||
|
||||
```java
|
||||
public class AltitudeClimateModifier {
|
||||
// La température diminue avec l'altitude
|
||||
public float modifyTemperature(float baseTemp, int altitude) {
|
||||
float altitudeFactor = altitude / 256.0f;
|
||||
return baseTemp - (altitudeFactor * 0.5f);
|
||||
}
|
||||
|
||||
// L'humidité varie avec l'altitude
|
||||
public float modifyHumidity(float baseHumidity, int altitude) {
|
||||
if (altitude < 64) {
|
||||
return baseHumidity * 1.2f; // Plus humide en basse altitude
|
||||
} else if (altitude > 128) {
|
||||
return baseHumidity * 0.6f; // Plus sec en haute altitude
|
||||
}
|
||||
return baseHumidity;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# worldgen/climate_config.yaml
|
||||
Climate:
|
||||
NoiseScale: 0.001
|
||||
TemperatureRange: [-1.0, 1.0]
|
||||
HumidityRange: [0.0, 1.0]
|
||||
BlendRadius: 8
|
||||
AltitudeEffect: true
|
||||
Biomes:
|
||||
- Id: forest
|
||||
Temperature: [0.3, 0.7]
|
||||
Humidity: [0.4, 0.8]
|
||||
- Id: desert
|
||||
Temperature: [0.7, 1.0]
|
||||
Humidity: [0.0, 0.3]
|
||||
- Id: tundra
|
||||
Temperature: [-1.0, -0.3]
|
||||
Humidity: [0.2, 0.6]
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives Climatiques :**
|
||||
- Utilisez un bruit lisse pour des transitions climatiques naturelles
|
||||
- Considérez l'altitude lors de la détermination des biomes
|
||||
- Mélangez les biomes pour des transitions fluides
|
||||
- Testez la distribution des biomes sur de grandes zones
|
||||
{{< /callout >}}
|
||||
270
content/world/worldgen/density-functions.en.md
Normal file
270
content/world/worldgen/density-functions.en.md
Normal file
@@ -0,0 +1,270 @@
|
||||
---
|
||||
title: Density Functions
|
||||
type: docs
|
||||
weight: 8
|
||||
---
|
||||
|
||||
Density functions define terrain shape by calculating density values at each point in 3D space.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.hytalegenerator.density`
|
||||
|
||||
## Density Function Concept
|
||||
|
||||
Density functions return values that determine solid vs air:
|
||||
- Positive values = solid terrain
|
||||
- Negative values = air
|
||||
- Zero = surface boundary
|
||||
|
||||
```java
|
||||
public interface DensityFunction {
|
||||
// Calculate density at position
|
||||
float calculate(int x, int y, int z, GenerationContext context);
|
||||
}
|
||||
```
|
||||
|
||||
## Basic Density Functions
|
||||
|
||||
### ConstantDensity
|
||||
|
||||
Returns a constant value:
|
||||
|
||||
```yaml
|
||||
Type: ConstantDensity
|
||||
Value: 1.0
|
||||
```
|
||||
|
||||
### NoiseDensity
|
||||
|
||||
Uses noise for terrain variation:
|
||||
|
||||
```yaml
|
||||
Type: NoiseDensity
|
||||
NoiseType: Simplex
|
||||
Scale: 0.01
|
||||
Amplitude: 1.0
|
||||
Octaves: 4
|
||||
Persistence: 0.5
|
||||
```
|
||||
|
||||
### HeightGradient
|
||||
|
||||
Creates flat terrain at a specific height:
|
||||
|
||||
```yaml
|
||||
Type: HeightGradient
|
||||
BaseHeight: 64
|
||||
Falloff: 32
|
||||
```
|
||||
|
||||
```java
|
||||
public class HeightGradient implements DensityFunction {
|
||||
private int baseHeight;
|
||||
private float falloff;
|
||||
|
||||
public float calculate(int x, int y, int z, GenerationContext ctx) {
|
||||
return (baseHeight - y) / falloff;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Composite Functions
|
||||
|
||||
### AddDensity
|
||||
|
||||
Combines multiple functions by addition:
|
||||
|
||||
```yaml
|
||||
Type: AddDensity
|
||||
Functions:
|
||||
- terrain_base
|
||||
- terrain_hills
|
||||
- terrain_mountains
|
||||
```
|
||||
|
||||
### MultiplyDensity
|
||||
|
||||
Multiplies function values:
|
||||
|
||||
```yaml
|
||||
Type: MultiplyDensity
|
||||
Functions:
|
||||
- terrain_base
|
||||
- mask_function
|
||||
```
|
||||
|
||||
### BlendDensity
|
||||
|
||||
Blends between functions:
|
||||
|
||||
```yaml
|
||||
Type: BlendDensity
|
||||
FunctionA: plains_terrain
|
||||
FunctionB: mountain_terrain
|
||||
Blender: biome_blend
|
||||
```
|
||||
|
||||
## Noise Functions
|
||||
|
||||
### SimplexNoise
|
||||
|
||||
Smooth, natural noise:
|
||||
|
||||
```java
|
||||
public class SimplexNoiseDensity implements DensityFunction {
|
||||
private SimplexNoise noise;
|
||||
private float scale;
|
||||
private int octaves;
|
||||
private float persistence;
|
||||
|
||||
public float calculate(int x, int y, int z, GenerationContext ctx) {
|
||||
float value = 0;
|
||||
float amplitude = 1;
|
||||
float frequency = scale;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
value += noise.noise3D(x * frequency, y * frequency, z * frequency) * amplitude;
|
||||
amplitude *= persistence;
|
||||
frequency *= 2;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### PerlinNoise
|
||||
|
||||
Classic Perlin noise:
|
||||
|
||||
```yaml
|
||||
Type: PerlinNoiseDensity
|
||||
Scale: 0.02
|
||||
Octaves: 6
|
||||
Persistence: 0.5
|
||||
Lacunarity: 2.0
|
||||
```
|
||||
|
||||
### VoronoiNoise
|
||||
|
||||
Cell-based noise:
|
||||
|
||||
```yaml
|
||||
Type: VoronoiDensity
|
||||
Scale: 0.005
|
||||
Type: Distance # or Edge, Cell
|
||||
```
|
||||
|
||||
## Terrain Shaping
|
||||
|
||||
### CliffFunction
|
||||
|
||||
Creates cliff formations:
|
||||
|
||||
```java
|
||||
public class CliffFunction implements DensityFunction {
|
||||
private float cliffHeight;
|
||||
private float steepness;
|
||||
|
||||
public float calculate(int x, int y, int z, GenerationContext ctx) {
|
||||
float baseNoise = ctx.noise2D(x, z, 0.01f);
|
||||
float cliffFactor = Math.abs(baseNoise) > 0.3f ? steepness : 1.0f;
|
||||
return (64 - y) * cliffFactor;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### TerraceFunction
|
||||
|
||||
Creates terraced terrain:
|
||||
|
||||
```yaml
|
||||
Type: TerraceDensity
|
||||
TerraceHeight: 8
|
||||
Smoothing: 0.5
|
||||
```
|
||||
|
||||
### OverhangFunction
|
||||
|
||||
Creates overhangs and arches:
|
||||
|
||||
```yaml
|
||||
Type: OverhangDensity
|
||||
BaseFunction: terrain_base
|
||||
OverhangNoise: overhang_noise
|
||||
Threshold: 0.3
|
||||
```
|
||||
|
||||
## Biome-Specific Functions
|
||||
|
||||
```yaml
|
||||
# density/forest_terrain.yaml
|
||||
Type: BiomeDensity
|
||||
Biome: forest
|
||||
Function:
|
||||
Type: AddDensity
|
||||
Functions:
|
||||
- Type: HeightGradient
|
||||
BaseHeight: 68
|
||||
Falloff: 24
|
||||
- Type: NoiseDensity
|
||||
Scale: 0.02
|
||||
Amplitude: 0.3
|
||||
```
|
||||
|
||||
## Mask Functions
|
||||
|
||||
Control where density applies:
|
||||
|
||||
```yaml
|
||||
Type: MaskedDensity
|
||||
Function: mountain_terrain
|
||||
Mask:
|
||||
Type: NoiseMask
|
||||
Scale: 0.001
|
||||
Threshold: 0.5
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# density/terrain_config.yaml
|
||||
DensityFunctions:
|
||||
terrain_base:
|
||||
Type: HeightGradient
|
||||
BaseHeight: 64
|
||||
Falloff: 32
|
||||
terrain_hills:
|
||||
Type: NoiseDensity
|
||||
Scale: 0.01
|
||||
Amplitude: 16
|
||||
terrain_combined:
|
||||
Type: AddDensity
|
||||
Functions: [terrain_base, terrain_hills]
|
||||
```
|
||||
|
||||
## Custom Density Function
|
||||
|
||||
```java
|
||||
public class MyDensityFunction implements DensityFunction {
|
||||
@Override
|
||||
public float calculate(int x, int y, int z, GenerationContext ctx) {
|
||||
// Custom terrain logic
|
||||
float baseHeight = 64 + ctx.noise2D(x, z, 0.01f) * 20;
|
||||
return baseHeight - y;
|
||||
}
|
||||
}
|
||||
|
||||
// Register in plugin setup
|
||||
densityRegistry.register("my_terrain", new MyDensityFunction());
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Density Function Guidelines:**
|
||||
- Use composite functions for complex terrain
|
||||
- Balance noise scales for natural appearance
|
||||
- Test with visualization tools
|
||||
- Consider performance with complex functions
|
||||
- Use caching for expensive calculations
|
||||
{{< /callout >}}
|
||||
270
content/world/worldgen/density-functions.fr.md
Normal file
270
content/world/worldgen/density-functions.fr.md
Normal file
@@ -0,0 +1,270 @@
|
||||
---
|
||||
title: Fonctions de Densité
|
||||
type: docs
|
||||
weight: 8
|
||||
---
|
||||
|
||||
Les fonctions de densité définissent la forme du terrain en calculant des valeurs de densité à chaque point dans l'espace 3D.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.hytalegenerator.density`
|
||||
|
||||
## Concept de Fonction de Densité
|
||||
|
||||
Les fonctions de densité retournent des valeurs qui déterminent solide vs air :
|
||||
- Valeurs positives = terrain solide
|
||||
- Valeurs négatives = air
|
||||
- Zéro = limite de surface
|
||||
|
||||
```java
|
||||
public interface DensityFunction {
|
||||
// Calculer la densité à une position
|
||||
float calculate(int x, int y, int z, GenerationContext context);
|
||||
}
|
||||
```
|
||||
|
||||
## Fonctions de Densité de Base
|
||||
|
||||
### ConstantDensity
|
||||
|
||||
Retourne une valeur constante :
|
||||
|
||||
```yaml
|
||||
Type: ConstantDensity
|
||||
Value: 1.0
|
||||
```
|
||||
|
||||
### NoiseDensity
|
||||
|
||||
Utilise le bruit pour la variation du terrain :
|
||||
|
||||
```yaml
|
||||
Type: NoiseDensity
|
||||
NoiseType: Simplex
|
||||
Scale: 0.01
|
||||
Amplitude: 1.0
|
||||
Octaves: 4
|
||||
Persistence: 0.5
|
||||
```
|
||||
|
||||
### HeightGradient
|
||||
|
||||
Crée un terrain plat à une hauteur spécifique :
|
||||
|
||||
```yaml
|
||||
Type: HeightGradient
|
||||
BaseHeight: 64
|
||||
Falloff: 32
|
||||
```
|
||||
|
||||
```java
|
||||
public class HeightGradient implements DensityFunction {
|
||||
private int baseHeight;
|
||||
private float falloff;
|
||||
|
||||
public float calculate(int x, int y, int z, GenerationContext ctx) {
|
||||
return (baseHeight - y) / falloff;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Fonctions Composites
|
||||
|
||||
### AddDensity
|
||||
|
||||
Combine plusieurs fonctions par addition :
|
||||
|
||||
```yaml
|
||||
Type: AddDensity
|
||||
Functions:
|
||||
- terrain_base
|
||||
- terrain_hills
|
||||
- terrain_mountains
|
||||
```
|
||||
|
||||
### MultiplyDensity
|
||||
|
||||
Multiplie les valeurs des fonctions :
|
||||
|
||||
```yaml
|
||||
Type: MultiplyDensity
|
||||
Functions:
|
||||
- terrain_base
|
||||
- mask_function
|
||||
```
|
||||
|
||||
### BlendDensity
|
||||
|
||||
Mélange entre fonctions :
|
||||
|
||||
```yaml
|
||||
Type: BlendDensity
|
||||
FunctionA: plains_terrain
|
||||
FunctionB: mountain_terrain
|
||||
Blender: biome_blend
|
||||
```
|
||||
|
||||
## Fonctions de Bruit
|
||||
|
||||
### SimplexNoise
|
||||
|
||||
Bruit lisse et naturel :
|
||||
|
||||
```java
|
||||
public class SimplexNoiseDensity implements DensityFunction {
|
||||
private SimplexNoise noise;
|
||||
private float scale;
|
||||
private int octaves;
|
||||
private float persistence;
|
||||
|
||||
public float calculate(int x, int y, int z, GenerationContext ctx) {
|
||||
float value = 0;
|
||||
float amplitude = 1;
|
||||
float frequency = scale;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
value += noise.noise3D(x * frequency, y * frequency, z * frequency) * amplitude;
|
||||
amplitude *= persistence;
|
||||
frequency *= 2;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### PerlinNoise
|
||||
|
||||
Bruit Perlin classique :
|
||||
|
||||
```yaml
|
||||
Type: PerlinNoiseDensity
|
||||
Scale: 0.02
|
||||
Octaves: 6
|
||||
Persistence: 0.5
|
||||
Lacunarity: 2.0
|
||||
```
|
||||
|
||||
### VoronoiNoise
|
||||
|
||||
Bruit basé sur les cellules :
|
||||
|
||||
```yaml
|
||||
Type: VoronoiDensity
|
||||
Scale: 0.005
|
||||
Type: Distance # ou Edge, Cell
|
||||
```
|
||||
|
||||
## Façonnage du Terrain
|
||||
|
||||
### CliffFunction
|
||||
|
||||
Crée des formations de falaises :
|
||||
|
||||
```java
|
||||
public class CliffFunction implements DensityFunction {
|
||||
private float cliffHeight;
|
||||
private float steepness;
|
||||
|
||||
public float calculate(int x, int y, int z, GenerationContext ctx) {
|
||||
float baseNoise = ctx.noise2D(x, z, 0.01f);
|
||||
float cliffFactor = Math.abs(baseNoise) > 0.3f ? steepness : 1.0f;
|
||||
return (64 - y) * cliffFactor;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### TerraceFunction
|
||||
|
||||
Crée un terrain en terrasses :
|
||||
|
||||
```yaml
|
||||
Type: TerraceDensity
|
||||
TerraceHeight: 8
|
||||
Smoothing: 0.5
|
||||
```
|
||||
|
||||
### OverhangFunction
|
||||
|
||||
Crée des surplombs et des arches :
|
||||
|
||||
```yaml
|
||||
Type: OverhangDensity
|
||||
BaseFunction: terrain_base
|
||||
OverhangNoise: overhang_noise
|
||||
Threshold: 0.3
|
||||
```
|
||||
|
||||
## Fonctions Spécifiques aux Biomes
|
||||
|
||||
```yaml
|
||||
# density/forest_terrain.yaml
|
||||
Type: BiomeDensity
|
||||
Biome: forest
|
||||
Function:
|
||||
Type: AddDensity
|
||||
Functions:
|
||||
- Type: HeightGradient
|
||||
BaseHeight: 68
|
||||
Falloff: 24
|
||||
- Type: NoiseDensity
|
||||
Scale: 0.02
|
||||
Amplitude: 0.3
|
||||
```
|
||||
|
||||
## Fonctions de Masque
|
||||
|
||||
Contrôle où la densité s'applique :
|
||||
|
||||
```yaml
|
||||
Type: MaskedDensity
|
||||
Function: mountain_terrain
|
||||
Mask:
|
||||
Type: NoiseMask
|
||||
Scale: 0.001
|
||||
Threshold: 0.5
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# density/terrain_config.yaml
|
||||
DensityFunctions:
|
||||
terrain_base:
|
||||
Type: HeightGradient
|
||||
BaseHeight: 64
|
||||
Falloff: 32
|
||||
terrain_hills:
|
||||
Type: NoiseDensity
|
||||
Scale: 0.01
|
||||
Amplitude: 16
|
||||
terrain_combined:
|
||||
Type: AddDensity
|
||||
Functions: [terrain_base, terrain_hills]
|
||||
```
|
||||
|
||||
## Fonction de Densité Personnalisée
|
||||
|
||||
```java
|
||||
public class MyDensityFunction implements DensityFunction {
|
||||
@Override
|
||||
public float calculate(int x, int y, int z, GenerationContext ctx) {
|
||||
// Logique de terrain personnalisée
|
||||
float baseHeight = 64 + ctx.noise2D(x, z, 0.01f) * 20;
|
||||
return baseHeight - y;
|
||||
}
|
||||
}
|
||||
|
||||
// Enregistrer dans le setup du plugin
|
||||
densityRegistry.register("my_terrain", new MyDensityFunction());
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives des Fonctions de Densité :**
|
||||
- Utilisez des fonctions composites pour un terrain complexe
|
||||
- Équilibrez les échelles de bruit pour une apparence naturelle
|
||||
- Testez avec des outils de visualisation
|
||||
- Considérez les performances avec les fonctions complexes
|
||||
- Utilisez le cache pour les calculs coûteux
|
||||
{{< /callout >}}
|
||||
328
content/world/worldgen/generation-patterns.en.md
Normal file
328
content/world/worldgen/generation-patterns.en.md
Normal file
@@ -0,0 +1,328 @@
|
||||
---
|
||||
title: Generation Patterns
|
||||
type: docs
|
||||
weight: 11
|
||||
---
|
||||
|
||||
Generation patterns provide reusable algorithms for creating terrain features, structures, and decorations.
|
||||
|
||||
**Packages:**
|
||||
- `com.hypixel.hytale.builtin.hytalegenerator.patterns`
|
||||
- `com.hypixel.hytale.builtin.hytalegenerator.fields`
|
||||
|
||||
## Pattern System
|
||||
|
||||
Patterns encapsulate generation logic:
|
||||
|
||||
```java
|
||||
public interface GenerationPattern {
|
||||
// Apply pattern to container
|
||||
void apply(GenerationContainer container, PatternContext context);
|
||||
}
|
||||
|
||||
public class PatternContext {
|
||||
private Vector3i origin;
|
||||
private int size;
|
||||
private Random random;
|
||||
private Map<String, Object> parameters;
|
||||
}
|
||||
```
|
||||
|
||||
## Built-in Patterns
|
||||
|
||||
### SpherePattern
|
||||
|
||||
Creates spherical formations:
|
||||
|
||||
```yaml
|
||||
Type: SpherePattern
|
||||
Radius: 5
|
||||
Block: stone
|
||||
Hollow: false
|
||||
```
|
||||
|
||||
```java
|
||||
public class SpherePattern implements GenerationPattern {
|
||||
private float radius;
|
||||
private BlockType block;
|
||||
private boolean hollow;
|
||||
|
||||
public void apply(GenerationContainer container, PatternContext ctx) {
|
||||
int r = (int) radius;
|
||||
for (int dx = -r; dx <= r; dx++) {
|
||||
for (int dy = -r; dy <= r; dy++) {
|
||||
for (int dz = -r; dz <= r; dz++) {
|
||||
float dist = (float) Math.sqrt(dx*dx + dy*dy + dz*dz);
|
||||
if (dist <= radius && (!hollow || dist > radius - 1)) {
|
||||
container.setBlock(
|
||||
ctx.origin.x + dx,
|
||||
ctx.origin.y + dy,
|
||||
ctx.origin.z + dz,
|
||||
block
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CylinderPattern
|
||||
|
||||
Creates cylindrical formations:
|
||||
|
||||
```yaml
|
||||
Type: CylinderPattern
|
||||
Radius: 4
|
||||
Height: 10
|
||||
Block: stone
|
||||
Hollow: true
|
||||
```
|
||||
|
||||
### ArchPattern
|
||||
|
||||
Creates arch formations:
|
||||
|
||||
```yaml
|
||||
Type: ArchPattern
|
||||
Width: 8
|
||||
Height: 6
|
||||
Thickness: 2
|
||||
Block: stone
|
||||
```
|
||||
|
||||
### SpirePattern
|
||||
|
||||
Creates spire/stalagmite shapes:
|
||||
|
||||
```yaml
|
||||
Type: SpirePattern
|
||||
BaseRadius: 3
|
||||
Height: 15
|
||||
TaperRate: 0.2
|
||||
Block: stone
|
||||
```
|
||||
|
||||
## Field Generation
|
||||
|
||||
Fields generate values across 2D or 3D space:
|
||||
|
||||
### NoiseField
|
||||
|
||||
```java
|
||||
public class NoiseField implements Field2D {
|
||||
private SimplexNoise noise;
|
||||
private float scale;
|
||||
private int octaves;
|
||||
|
||||
public float getValue(int x, int z) {
|
||||
return noise.noise2D(x * scale, z * scale);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### GradientField
|
||||
|
||||
```java
|
||||
public class GradientField implements Field2D {
|
||||
private Vector2f direction;
|
||||
private float scale;
|
||||
|
||||
public float getValue(int x, int z) {
|
||||
return (x * direction.x + z * direction.y) * scale;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### VoronoiField
|
||||
|
||||
```java
|
||||
public class VoronoiField implements Field2D {
|
||||
private List<Vector2i> points;
|
||||
|
||||
public float getValue(int x, int z) {
|
||||
float minDist = Float.MAX_VALUE;
|
||||
for (Vector2i point : points) {
|
||||
float dist = (float) Math.sqrt(
|
||||
(x - point.x) * (x - point.x) +
|
||||
(z - point.y) * (z - point.y)
|
||||
);
|
||||
minDist = Math.min(minDist, dist);
|
||||
}
|
||||
return minDist;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Composite Patterns
|
||||
|
||||
### RepeatPattern
|
||||
|
||||
Repeats a pattern in a grid:
|
||||
|
||||
```yaml
|
||||
Type: RepeatPattern
|
||||
Pattern: pillar_pattern
|
||||
SpacingX: 10
|
||||
SpacingZ: 10
|
||||
Count: 16
|
||||
```
|
||||
|
||||
### ScatterPattern
|
||||
|
||||
Places patterns at random positions:
|
||||
|
||||
```yaml
|
||||
Type: ScatterPattern
|
||||
Pattern: boulder_pattern
|
||||
Density: 0.05
|
||||
MinSpacing: 5
|
||||
```
|
||||
|
||||
### ConditionalPattern
|
||||
|
||||
Applies pattern based on conditions:
|
||||
|
||||
```yaml
|
||||
Type: ConditionalPattern
|
||||
Pattern: snow_cap
|
||||
Condition:
|
||||
Type: HeightAbove
|
||||
Height: 100
|
||||
```
|
||||
|
||||
## Terrain Patterns
|
||||
|
||||
### RiverPattern
|
||||
|
||||
Carves river channels:
|
||||
|
||||
```java
|
||||
public class RiverPattern implements GenerationPattern {
|
||||
private List<Vector2f> path;
|
||||
private float width;
|
||||
private float depth;
|
||||
|
||||
public void apply(GenerationContainer container, PatternContext ctx) {
|
||||
for (Vector2f point : path) {
|
||||
carveRiverSection(container, point, width, depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CliffPattern
|
||||
|
||||
Creates cliff formations:
|
||||
|
||||
```yaml
|
||||
Type: CliffPattern
|
||||
Height: 20
|
||||
Steepness: 0.9
|
||||
NoiseScale: 0.1
|
||||
```
|
||||
|
||||
### TerracePattern
|
||||
|
||||
Creates terraced terrain:
|
||||
|
||||
```yaml
|
||||
Type: TerracePattern
|
||||
TerraceHeight: 5
|
||||
TerraceCount: 4
|
||||
Smoothing: 0.3
|
||||
```
|
||||
|
||||
## Decoration Patterns
|
||||
|
||||
### ClusterPattern
|
||||
|
||||
Creates clusters of blocks:
|
||||
|
||||
```yaml
|
||||
Type: ClusterPattern
|
||||
Block: flower_red
|
||||
Size: 3-7
|
||||
Density: 0.8
|
||||
```
|
||||
|
||||
### VeinPattern
|
||||
|
||||
Creates ore veins:
|
||||
|
||||
```yaml
|
||||
Type: VeinPattern
|
||||
Block: iron_ore
|
||||
Length: 10-20
|
||||
Branching: 0.3
|
||||
```
|
||||
|
||||
### LayerPattern
|
||||
|
||||
Creates horizontal layers:
|
||||
|
||||
```yaml
|
||||
Type: LayerPattern
|
||||
Layers:
|
||||
- Block: grass_block
|
||||
Thickness: 1
|
||||
- Block: dirt
|
||||
Thickness: 3
|
||||
- Block: stone
|
||||
Thickness: -1 # Fill remaining
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# patterns/config.yaml
|
||||
Patterns:
|
||||
boulder:
|
||||
Type: SpherePattern
|
||||
Radius: 2-4
|
||||
Block: stone
|
||||
tree_trunk:
|
||||
Type: CylinderPattern
|
||||
Radius: 1
|
||||
Height: 5-10
|
||||
Block: oak_log
|
||||
crystal_cluster:
|
||||
Type: ClusterPattern
|
||||
Block: crystal
|
||||
Size: 3-8
|
||||
```
|
||||
|
||||
## Custom Pattern
|
||||
|
||||
```java
|
||||
public class MyPattern implements GenerationPattern {
|
||||
@Override
|
||||
public void apply(GenerationContainer container, PatternContext ctx) {
|
||||
// Custom generation logic
|
||||
int size = ctx.parameters.getInt("size", 5);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
int x = ctx.origin.x + ctx.random.nextInt(size);
|
||||
int z = ctx.origin.z + ctx.random.nextInt(size);
|
||||
int y = container.getHeight(x, z);
|
||||
|
||||
container.setBlock(x, y + 1, z, BlockTypes.STONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
patternRegistry.register("my_pattern", new MyPattern());
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Pattern Guidelines:**
|
||||
- Use patterns for reusable generation logic
|
||||
- Combine patterns with fields for variety
|
||||
- Test patterns at different scales
|
||||
- Consider performance with complex patterns
|
||||
- Document pattern parameters clearly
|
||||
{{< /callout >}}
|
||||
328
content/world/worldgen/generation-patterns.fr.md
Normal file
328
content/world/worldgen/generation-patterns.fr.md
Normal file
@@ -0,0 +1,328 @@
|
||||
---
|
||||
title: Patterns de Génération
|
||||
type: docs
|
||||
weight: 11
|
||||
---
|
||||
|
||||
Les patterns de génération fournissent des algorithmes réutilisables pour créer des caractéristiques de terrain, des structures et des décorations.
|
||||
|
||||
**Packages:**
|
||||
- `com.hypixel.hytale.builtin.hytalegenerator.patterns`
|
||||
- `com.hypixel.hytale.builtin.hytalegenerator.fields`
|
||||
|
||||
## Système de Patterns
|
||||
|
||||
Les patterns encapsulent la logique de génération :
|
||||
|
||||
```java
|
||||
public interface GenerationPattern {
|
||||
// Appliquer le pattern au conteneur
|
||||
void apply(GenerationContainer container, PatternContext context);
|
||||
}
|
||||
|
||||
public class PatternContext {
|
||||
private Vector3i origin;
|
||||
private int size;
|
||||
private Random random;
|
||||
private Map<String, Object> parameters;
|
||||
}
|
||||
```
|
||||
|
||||
## Patterns Intégrés
|
||||
|
||||
### SpherePattern
|
||||
|
||||
Crée des formations sphériques :
|
||||
|
||||
```yaml
|
||||
Type: SpherePattern
|
||||
Radius: 5
|
||||
Block: stone
|
||||
Hollow: false
|
||||
```
|
||||
|
||||
```java
|
||||
public class SpherePattern implements GenerationPattern {
|
||||
private float radius;
|
||||
private BlockType block;
|
||||
private boolean hollow;
|
||||
|
||||
public void apply(GenerationContainer container, PatternContext ctx) {
|
||||
int r = (int) radius;
|
||||
for (int dx = -r; dx <= r; dx++) {
|
||||
for (int dy = -r; dy <= r; dy++) {
|
||||
for (int dz = -r; dz <= r; dz++) {
|
||||
float dist = (float) Math.sqrt(dx*dx + dy*dy + dz*dz);
|
||||
if (dist <= radius && (!hollow || dist > radius - 1)) {
|
||||
container.setBlock(
|
||||
ctx.origin.x + dx,
|
||||
ctx.origin.y + dy,
|
||||
ctx.origin.z + dz,
|
||||
block
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CylinderPattern
|
||||
|
||||
Crée des formations cylindriques :
|
||||
|
||||
```yaml
|
||||
Type: CylinderPattern
|
||||
Radius: 4
|
||||
Height: 10
|
||||
Block: stone
|
||||
Hollow: true
|
||||
```
|
||||
|
||||
### ArchPattern
|
||||
|
||||
Crée des formations d'arches :
|
||||
|
||||
```yaml
|
||||
Type: ArchPattern
|
||||
Width: 8
|
||||
Height: 6
|
||||
Thickness: 2
|
||||
Block: stone
|
||||
```
|
||||
|
||||
### SpirePattern
|
||||
|
||||
Crée des formes de flèche/stalagmite :
|
||||
|
||||
```yaml
|
||||
Type: SpirePattern
|
||||
BaseRadius: 3
|
||||
Height: 15
|
||||
TaperRate: 0.2
|
||||
Block: stone
|
||||
```
|
||||
|
||||
## Génération par Champs
|
||||
|
||||
Les champs génèrent des valeurs à travers l'espace 2D ou 3D :
|
||||
|
||||
### NoiseField
|
||||
|
||||
```java
|
||||
public class NoiseField implements Field2D {
|
||||
private SimplexNoise noise;
|
||||
private float scale;
|
||||
private int octaves;
|
||||
|
||||
public float getValue(int x, int z) {
|
||||
return noise.noise2D(x * scale, z * scale);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### GradientField
|
||||
|
||||
```java
|
||||
public class GradientField implements Field2D {
|
||||
private Vector2f direction;
|
||||
private float scale;
|
||||
|
||||
public float getValue(int x, int z) {
|
||||
return (x * direction.x + z * direction.y) * scale;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### VoronoiField
|
||||
|
||||
```java
|
||||
public class VoronoiField implements Field2D {
|
||||
private List<Vector2i> points;
|
||||
|
||||
public float getValue(int x, int z) {
|
||||
float minDist = Float.MAX_VALUE;
|
||||
for (Vector2i point : points) {
|
||||
float dist = (float) Math.sqrt(
|
||||
(x - point.x) * (x - point.x) +
|
||||
(z - point.y) * (z - point.y)
|
||||
);
|
||||
minDist = Math.min(minDist, dist);
|
||||
}
|
||||
return minDist;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Patterns Composites
|
||||
|
||||
### RepeatPattern
|
||||
|
||||
Répète un pattern dans une grille :
|
||||
|
||||
```yaml
|
||||
Type: RepeatPattern
|
||||
Pattern: pillar_pattern
|
||||
SpacingX: 10
|
||||
SpacingZ: 10
|
||||
Count: 16
|
||||
```
|
||||
|
||||
### ScatterPattern
|
||||
|
||||
Place des patterns à des positions aléatoires :
|
||||
|
||||
```yaml
|
||||
Type: ScatterPattern
|
||||
Pattern: boulder_pattern
|
||||
Density: 0.05
|
||||
MinSpacing: 5
|
||||
```
|
||||
|
||||
### ConditionalPattern
|
||||
|
||||
Applique un pattern selon des conditions :
|
||||
|
||||
```yaml
|
||||
Type: ConditionalPattern
|
||||
Pattern: snow_cap
|
||||
Condition:
|
||||
Type: HeightAbove
|
||||
Height: 100
|
||||
```
|
||||
|
||||
## Patterns de Terrain
|
||||
|
||||
### RiverPattern
|
||||
|
||||
Creuse des canaux de rivière :
|
||||
|
||||
```java
|
||||
public class RiverPattern implements GenerationPattern {
|
||||
private List<Vector2f> path;
|
||||
private float width;
|
||||
private float depth;
|
||||
|
||||
public void apply(GenerationContainer container, PatternContext ctx) {
|
||||
for (Vector2f point : path) {
|
||||
carveRiverSection(container, point, width, depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CliffPattern
|
||||
|
||||
Crée des formations de falaises :
|
||||
|
||||
```yaml
|
||||
Type: CliffPattern
|
||||
Height: 20
|
||||
Steepness: 0.9
|
||||
NoiseScale: 0.1
|
||||
```
|
||||
|
||||
### TerracePattern
|
||||
|
||||
Crée un terrain en terrasses :
|
||||
|
||||
```yaml
|
||||
Type: TerracePattern
|
||||
TerraceHeight: 5
|
||||
TerraceCount: 4
|
||||
Smoothing: 0.3
|
||||
```
|
||||
|
||||
## Patterns de Décoration
|
||||
|
||||
### ClusterPattern
|
||||
|
||||
Crée des groupes de blocs :
|
||||
|
||||
```yaml
|
||||
Type: ClusterPattern
|
||||
Block: flower_red
|
||||
Size: 3-7
|
||||
Density: 0.8
|
||||
```
|
||||
|
||||
### VeinPattern
|
||||
|
||||
Crée des veines de minerai :
|
||||
|
||||
```yaml
|
||||
Type: VeinPattern
|
||||
Block: iron_ore
|
||||
Length: 10-20
|
||||
Branching: 0.3
|
||||
```
|
||||
|
||||
### LayerPattern
|
||||
|
||||
Crée des couches horizontales :
|
||||
|
||||
```yaml
|
||||
Type: LayerPattern
|
||||
Layers:
|
||||
- Block: grass_block
|
||||
Thickness: 1
|
||||
- Block: dirt
|
||||
Thickness: 3
|
||||
- Block: stone
|
||||
Thickness: -1 # Remplir le reste
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# patterns/config.yaml
|
||||
Patterns:
|
||||
boulder:
|
||||
Type: SpherePattern
|
||||
Radius: 2-4
|
||||
Block: stone
|
||||
tree_trunk:
|
||||
Type: CylinderPattern
|
||||
Radius: 1
|
||||
Height: 5-10
|
||||
Block: oak_log
|
||||
crystal_cluster:
|
||||
Type: ClusterPattern
|
||||
Block: crystal
|
||||
Size: 3-8
|
||||
```
|
||||
|
||||
## Pattern Personnalisé
|
||||
|
||||
```java
|
||||
public class MyPattern implements GenerationPattern {
|
||||
@Override
|
||||
public void apply(GenerationContainer container, PatternContext ctx) {
|
||||
// Logique de génération personnalisée
|
||||
int size = ctx.parameters.getInt("size", 5);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
int x = ctx.origin.x + ctx.random.nextInt(size);
|
||||
int z = ctx.origin.z + ctx.random.nextInt(size);
|
||||
int y = container.getHeight(x, z);
|
||||
|
||||
container.setBlock(x, y + 1, z, BlockTypes.STONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enregistrer
|
||||
patternRegistry.register("my_pattern", new MyPattern());
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives des Patterns :**
|
||||
- Utilisez les patterns pour une logique de génération réutilisable
|
||||
- Combinez les patterns avec les champs pour la variété
|
||||
- Testez les patterns à différentes échelles
|
||||
- Considérez les performances avec les patterns complexes
|
||||
- Documentez clairement les paramètres des patterns
|
||||
{{< /callout >}}
|
||||
212
content/world/worldgen/hytale-generator.en.md
Normal file
212
content/world/worldgen/hytale-generator.en.md
Normal file
@@ -0,0 +1,212 @@
|
||||
---
|
||||
title: Hytale Generator
|
||||
type: docs
|
||||
weight: 7
|
||||
---
|
||||
|
||||
The Hytale Generator is the default procedural world generator that creates Hytale's terrain, structures, and features.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.hytalegenerator`
|
||||
|
||||
## Overview
|
||||
|
||||
The Hytale Generator combines multiple systems:
|
||||
|
||||
```
|
||||
Hytale Generator
|
||||
├── Density Functions (terrain shape)
|
||||
├── Material Providers (block selection)
|
||||
├── Prop Placement (vegetation/objects)
|
||||
├── Cave Generation
|
||||
├── Structure Placement
|
||||
└── Biome-specific features
|
||||
```
|
||||
|
||||
## Generator Structure
|
||||
|
||||
```java
|
||||
public class HytaleGenerator implements WorldGenerator {
|
||||
private DensityFunctionRegistry densityFunctions;
|
||||
private MaterialProviderRegistry materialProviders;
|
||||
private PropPlacementRegistry propPlacement;
|
||||
private CaveGenerator caveGenerator;
|
||||
private StructureGenerator structureGenerator;
|
||||
|
||||
@Override
|
||||
public void generate(GenerationContainer container, int chunkX, int chunkZ) {
|
||||
// 1. Generate base terrain
|
||||
generateTerrain(container, chunkX, chunkZ);
|
||||
|
||||
// 2. Carve caves
|
||||
caveGenerator.generate(container, chunkX, chunkZ);
|
||||
|
||||
// 3. Place structures
|
||||
structureGenerator.generate(container, chunkX, chunkZ);
|
||||
|
||||
// 4. Place props
|
||||
propPlacement.generate(container, chunkX, chunkZ);
|
||||
|
||||
// 5. Finalize
|
||||
finalize(container);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Asset Configuration
|
||||
|
||||
Generator assets define generation parameters:
|
||||
|
||||
```yaml
|
||||
# hytalegenerator/world_generator.yaml
|
||||
Type: HytaleGenerator
|
||||
Id: default_generator
|
||||
Seed: 0 # 0 = random
|
||||
TerrainDensity:
|
||||
Function: terrain_combined
|
||||
Scale: 1.0
|
||||
Materials:
|
||||
Provider: biome_materials
|
||||
Caves:
|
||||
Enabled: true
|
||||
Frequency: 0.5
|
||||
Structures:
|
||||
Enabled: true
|
||||
Spacing: 32
|
||||
Props:
|
||||
Density: 1.0
|
||||
```
|
||||
|
||||
## Framework Components
|
||||
|
||||
The generator framework provides core utilities:
|
||||
|
||||
```java
|
||||
// Generation context
|
||||
public class GenerationContext {
|
||||
private long seed;
|
||||
private int chunkX, chunkZ;
|
||||
private Biome biome;
|
||||
private Random random;
|
||||
|
||||
public float noise2D(float x, float z, float scale);
|
||||
public float noise3D(float x, float y, float z, float scale);
|
||||
}
|
||||
|
||||
// Generation phase
|
||||
public enum GenerationPhase {
|
||||
TERRAIN,
|
||||
CARVING,
|
||||
STRUCTURES,
|
||||
DECORATION,
|
||||
FINALIZATION
|
||||
}
|
||||
```
|
||||
|
||||
## Data Structures
|
||||
|
||||
Specialized data structures for generation:
|
||||
|
||||
```java
|
||||
// Height map storage
|
||||
public class HeightMap2D {
|
||||
private float[] data;
|
||||
private int width, height;
|
||||
|
||||
public float get(int x, int z);
|
||||
public void set(int x, int z, float value);
|
||||
}
|
||||
|
||||
// 3D density storage
|
||||
public class DensityField3D {
|
||||
private float[] data;
|
||||
private int sizeX, sizeY, sizeZ;
|
||||
|
||||
public float get(int x, int y, int z);
|
||||
public float sample(float x, float y, float z); // Interpolated
|
||||
}
|
||||
```
|
||||
|
||||
## New System Integration
|
||||
|
||||
The generator integrates newer systems:
|
||||
|
||||
```java
|
||||
public class NewSystemIntegration {
|
||||
// Register custom density function
|
||||
public void registerDensityFunction(String id, DensityFunction function);
|
||||
|
||||
// Register custom material provider
|
||||
public void registerMaterialProvider(String id, MaterialProvider provider);
|
||||
|
||||
// Register custom prop placer
|
||||
public void registerPropPlacer(String id, PropPlacer placer);
|
||||
}
|
||||
```
|
||||
|
||||
## Subpackages
|
||||
|
||||
| Package | Files | Description |
|
||||
|---------|-------|-------------|
|
||||
| `assets/` | 232 | Asset definitions for generation |
|
||||
| `density/` | 76 | Density function implementations |
|
||||
| `newsystem/` | 29 | New generation system |
|
||||
| `materialproviders/` | 29 | Material selection |
|
||||
| `framework/` | 29 | Core framework |
|
||||
| `props/` | 24 | Prop placement |
|
||||
| `datastructures/` | 16 | Data structures |
|
||||
| `positionproviders/` | 14 | Position calculation |
|
||||
| `patterns/` | 13 | Generation patterns |
|
||||
| `fields/` | 8 | Field generation |
|
||||
|
||||
## Custom Generator
|
||||
|
||||
Create a custom generator:
|
||||
|
||||
```java
|
||||
public class MyGenerator extends HytaleGenerator {
|
||||
@Override
|
||||
protected void generateTerrain(GenerationContainer container, int chunkX, int chunkZ) {
|
||||
// Custom terrain generation
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int worldX = chunkX * 16 + x;
|
||||
int worldZ = chunkZ * 16 + z;
|
||||
|
||||
float density = getCustomDensity(worldX, worldZ);
|
||||
int height = (int) (density * 64) + 64;
|
||||
|
||||
fillColumn(container, x, z, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# hytalegenerator/config.yaml
|
||||
HytaleGenerator:
|
||||
WorldType: normal
|
||||
SeaLevel: 64
|
||||
TerrainAmplitude: 1.0
|
||||
CaveFrequency: 0.5
|
||||
StructureSpacing: 32
|
||||
BiomeScale: 256
|
||||
Features:
|
||||
Caves: true
|
||||
Structures: true
|
||||
Props: true
|
||||
Ores: true
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Generator Guidelines:**
|
||||
- Extend HytaleGenerator for custom worlds
|
||||
- Use the asset system for configuration
|
||||
- Register custom components in setup phase
|
||||
- Test generation across different seeds
|
||||
- Profile performance for custom functions
|
||||
{{< /callout >}}
|
||||
212
content/world/worldgen/hytale-generator.fr.md
Normal file
212
content/world/worldgen/hytale-generator.fr.md
Normal file
@@ -0,0 +1,212 @@
|
||||
---
|
||||
title: Hytale Generator
|
||||
type: docs
|
||||
weight: 7
|
||||
---
|
||||
|
||||
Le Hytale Generator est le générateur de monde procédural par défaut qui crée le terrain, les structures et les caractéristiques de Hytale.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.hytalegenerator`
|
||||
|
||||
## Vue d'Ensemble
|
||||
|
||||
Le Hytale Generator combine plusieurs systèmes :
|
||||
|
||||
```
|
||||
Hytale Generator
|
||||
├── Fonctions de Densité (forme du terrain)
|
||||
├── Material Providers (sélection de blocs)
|
||||
├── Placement de Props (végétation/objets)
|
||||
├── Génération de Grottes
|
||||
├── Placement de Structures
|
||||
└── Caractéristiques spécifiques aux biomes
|
||||
```
|
||||
|
||||
## Structure du Générateur
|
||||
|
||||
```java
|
||||
public class HytaleGenerator implements WorldGenerator {
|
||||
private DensityFunctionRegistry densityFunctions;
|
||||
private MaterialProviderRegistry materialProviders;
|
||||
private PropPlacementRegistry propPlacement;
|
||||
private CaveGenerator caveGenerator;
|
||||
private StructureGenerator structureGenerator;
|
||||
|
||||
@Override
|
||||
public void generate(GenerationContainer container, int chunkX, int chunkZ) {
|
||||
// 1. Générer le terrain de base
|
||||
generateTerrain(container, chunkX, chunkZ);
|
||||
|
||||
// 2. Creuser les grottes
|
||||
caveGenerator.generate(container, chunkX, chunkZ);
|
||||
|
||||
// 3. Placer les structures
|
||||
structureGenerator.generate(container, chunkX, chunkZ);
|
||||
|
||||
// 4. Placer les props
|
||||
propPlacement.generate(container, chunkX, chunkZ);
|
||||
|
||||
// 5. Finaliser
|
||||
finalize(container);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration d'Assets
|
||||
|
||||
Les assets du générateur définissent les paramètres de génération :
|
||||
|
||||
```yaml
|
||||
# hytalegenerator/world_generator.yaml
|
||||
Type: HytaleGenerator
|
||||
Id: default_generator
|
||||
Seed: 0 # 0 = aléatoire
|
||||
TerrainDensity:
|
||||
Function: terrain_combined
|
||||
Scale: 1.0
|
||||
Materials:
|
||||
Provider: biome_materials
|
||||
Caves:
|
||||
Enabled: true
|
||||
Frequency: 0.5
|
||||
Structures:
|
||||
Enabled: true
|
||||
Spacing: 32
|
||||
Props:
|
||||
Density: 1.0
|
||||
```
|
||||
|
||||
## Composants du Framework
|
||||
|
||||
Le framework du générateur fournit des utilitaires de base :
|
||||
|
||||
```java
|
||||
// Contexte de génération
|
||||
public class GenerationContext {
|
||||
private long seed;
|
||||
private int chunkX, chunkZ;
|
||||
private Biome biome;
|
||||
private Random random;
|
||||
|
||||
public float noise2D(float x, float z, float scale);
|
||||
public float noise3D(float x, float y, float z, float scale);
|
||||
}
|
||||
|
||||
// Phase de génération
|
||||
public enum GenerationPhase {
|
||||
TERRAIN,
|
||||
CARVING,
|
||||
STRUCTURES,
|
||||
DECORATION,
|
||||
FINALIZATION
|
||||
}
|
||||
```
|
||||
|
||||
## Structures de Données
|
||||
|
||||
Structures de données spécialisées pour la génération :
|
||||
|
||||
```java
|
||||
// Stockage de carte de hauteur
|
||||
public class HeightMap2D {
|
||||
private float[] data;
|
||||
private int width, height;
|
||||
|
||||
public float get(int x, int z);
|
||||
public void set(int x, int z, float value);
|
||||
}
|
||||
|
||||
// Stockage de densité 3D
|
||||
public class DensityField3D {
|
||||
private float[] data;
|
||||
private int sizeX, sizeY, sizeZ;
|
||||
|
||||
public float get(int x, int y, int z);
|
||||
public float sample(float x, float y, float z); // Interpolé
|
||||
}
|
||||
```
|
||||
|
||||
## Intégration Nouveau Système
|
||||
|
||||
Le générateur intègre les systèmes plus récents :
|
||||
|
||||
```java
|
||||
public class NewSystemIntegration {
|
||||
// Enregistrer une fonction de densité personnalisée
|
||||
public void registerDensityFunction(String id, DensityFunction function);
|
||||
|
||||
// Enregistrer un material provider personnalisé
|
||||
public void registerMaterialProvider(String id, MaterialProvider provider);
|
||||
|
||||
// Enregistrer un placeur de props personnalisé
|
||||
public void registerPropPlacer(String id, PropPlacer placer);
|
||||
}
|
||||
```
|
||||
|
||||
## Sous-packages
|
||||
|
||||
| Package | Fichiers | Description |
|
||||
|---------|----------|-------------|
|
||||
| `assets/` | 232 | Définitions d'assets pour la génération |
|
||||
| `density/` | 76 | Implémentations de fonctions de densité |
|
||||
| `newsystem/` | 29 | Nouveau système de génération |
|
||||
| `materialproviders/` | 29 | Sélection de matériaux |
|
||||
| `framework/` | 29 | Framework de base |
|
||||
| `props/` | 24 | Placement de props |
|
||||
| `datastructures/` | 16 | Structures de données |
|
||||
| `positionproviders/` | 14 | Calcul de positions |
|
||||
| `patterns/` | 13 | Patterns de génération |
|
||||
| `fields/` | 8 | Génération par champs |
|
||||
|
||||
## Générateur Personnalisé
|
||||
|
||||
Créer un générateur personnalisé :
|
||||
|
||||
```java
|
||||
public class MyGenerator extends HytaleGenerator {
|
||||
@Override
|
||||
protected void generateTerrain(GenerationContainer container, int chunkX, int chunkZ) {
|
||||
// Génération de terrain personnalisée
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int worldX = chunkX * 16 + x;
|
||||
int worldZ = chunkZ * 16 + z;
|
||||
|
||||
float density = getCustomDensity(worldX, worldZ);
|
||||
int height = (int) (density * 64) + 64;
|
||||
|
||||
fillColumn(container, x, z, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# hytalegenerator/config.yaml
|
||||
HytaleGenerator:
|
||||
WorldType: normal
|
||||
SeaLevel: 64
|
||||
TerrainAmplitude: 1.0
|
||||
CaveFrequency: 0.5
|
||||
StructureSpacing: 32
|
||||
BiomeScale: 256
|
||||
Features:
|
||||
Caves: true
|
||||
Structures: true
|
||||
Props: true
|
||||
Ores: true
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives du Générateur :**
|
||||
- Étendez HytaleGenerator pour des mondes personnalisés
|
||||
- Utilisez le système d'assets pour la configuration
|
||||
- Enregistrez les composants personnalisés dans la phase setup
|
||||
- Testez la génération avec différentes seeds
|
||||
- Profilez les performances des fonctions personnalisées
|
||||
{{< /callout >}}
|
||||
273
content/world/worldgen/material-providers.en.md
Normal file
273
content/world/worldgen/material-providers.en.md
Normal file
@@ -0,0 +1,273 @@
|
||||
---
|
||||
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 >}}
|
||||
273
content/world/worldgen/material-providers.fr.md
Normal file
273
content/world/worldgen/material-providers.fr.md
Normal file
@@ -0,0 +1,273 @@
|
||||
---
|
||||
title: Material Providers
|
||||
type: docs
|
||||
weight: 9
|
||||
---
|
||||
|
||||
Les material providers déterminent quels blocs sont placés à chaque position pendant la génération du terrain.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.hytalegenerator.materialproviders`
|
||||
|
||||
## Concept de Material Provider
|
||||
|
||||
Les material providers sélectionnent les blocs selon le contexte :
|
||||
|
||||
```java
|
||||
public interface MaterialProvider {
|
||||
// Obtenir le bloc pour une 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; // Profondeur sous la surface
|
||||
private boolean underwater;
|
||||
}
|
||||
```
|
||||
|
||||
## Providers de Base
|
||||
|
||||
### SingleMaterialProvider
|
||||
|
||||
Retourne un seul type de bloc :
|
||||
|
||||
```yaml
|
||||
Type: SingleMaterial
|
||||
Block: stone
|
||||
```
|
||||
|
||||
### DepthMaterialProvider
|
||||
|
||||
Change les blocs selon la profondeur :
|
||||
|
||||
```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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Providers Basés sur les Biomes
|
||||
|
||||
### BiomeMaterialProvider
|
||||
|
||||
Sélectionne les matériaux selon le 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
|
||||
|
||||
Provider spécifique à la surface :
|
||||
|
||||
```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;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Providers Basés sur le Bruit
|
||||
|
||||
### NoiseMaterialProvider
|
||||
|
||||
Utilise le bruit pour la variation :
|
||||
|
||||
```yaml
|
||||
Type: NoiseMaterial
|
||||
Noise:
|
||||
Scale: 0.1
|
||||
Threshold: 0.5
|
||||
Materials:
|
||||
Above: stone
|
||||
Below: granite
|
||||
```
|
||||
|
||||
### GradientMaterialProvider
|
||||
|
||||
Mélange les matériaux selon une valeur :
|
||||
|
||||
```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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Providers Composites
|
||||
|
||||
### LayeredMaterialProvider
|
||||
|
||||
Empile plusieurs providers :
|
||||
|
||||
```yaml
|
||||
Type: LayeredMaterial
|
||||
Layers:
|
||||
- Provider: bedrock_layer
|
||||
MaxY: 5
|
||||
- Provider: stone_layer
|
||||
MaxY: 60
|
||||
- Provider: surface_layer
|
||||
MaxY: 256
|
||||
```
|
||||
|
||||
### ConditionalMaterialProvider
|
||||
|
||||
Sélection conditionnelle de blocs :
|
||||
|
||||
```yaml
|
||||
Type: ConditionalMaterial
|
||||
Conditions:
|
||||
- Condition:
|
||||
Type: Underwater
|
||||
Provider: sand_material
|
||||
- Condition:
|
||||
Type: NearCave
|
||||
Distance: 2
|
||||
Provider: cave_stone
|
||||
- Default: default_material
|
||||
```
|
||||
|
||||
## Providers Spéciaux
|
||||
|
||||
### OreMaterialProvider
|
||||
|
||||
Place des veines de minerai :
|
||||
|
||||
```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
|
||||
|
||||
Matériaux pour les surfaces de grottes :
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
## Provider Personnalisé
|
||||
|
||||
```java
|
||||
public class MyMaterialProvider implements MaterialProvider {
|
||||
@Override
|
||||
public BlockType getBlock(int x, int y, int z, MaterialContext ctx) {
|
||||
// Logique de matériau personnalisée
|
||||
if (ctx.underwater) {
|
||||
return BlockTypes.SAND;
|
||||
}
|
||||
if (ctx.depth == 0) {
|
||||
return BlockTypes.GRASS_BLOCK;
|
||||
}
|
||||
return BlockTypes.STONE;
|
||||
}
|
||||
}
|
||||
|
||||
// Enregistrer
|
||||
materialRegistry.register("my_materials", new MyMaterialProvider());
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives des Material Providers :**
|
||||
- Utilisez des providers conscients des biomes pour la variété
|
||||
- Superposez les providers pour des surfaces complexes
|
||||
- Ajoutez du bruit pour une variation naturelle
|
||||
- Considérez les cas spéciaux (sous l'eau, grottes)
|
||||
- Testez les transitions de matériaux entre biomes
|
||||
{{< /callout >}}
|
||||
220
content/world/worldgen/prefabs.en.md
Normal file
220
content/world/worldgen/prefabs.en.md
Normal file
@@ -0,0 +1,220 @@
|
||||
---
|
||||
title: Prefabs
|
||||
type: docs
|
||||
weight: 5
|
||||
---
|
||||
|
||||
Prefabs are pre-built structures that can be placed during world generation, such as buildings, ruins, and dungeons.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.worldgen.prefab`
|
||||
|
||||
## Prefab System
|
||||
|
||||
The prefab system handles structure placement:
|
||||
|
||||
```java
|
||||
public class PrefabPlacer {
|
||||
// Place prefab at position
|
||||
public boolean place(Prefab prefab, World world, Vector3i position);
|
||||
|
||||
// Check if prefab can be placed
|
||||
public boolean canPlace(Prefab prefab, World world, Vector3i position);
|
||||
|
||||
// Find valid position for prefab
|
||||
public Vector3i findPlacement(Prefab prefab, World world, int chunkX, int chunkZ);
|
||||
}
|
||||
```
|
||||
|
||||
## Prefab Definition
|
||||
|
||||
```yaml
|
||||
# prefabs/village_house.yaml
|
||||
Type: Prefab
|
||||
Id: village_house
|
||||
Size: [7, 5, 9]
|
||||
Origin: [3, 0, 4]
|
||||
Palette:
|
||||
W: oak_planks
|
||||
S: stone_bricks
|
||||
G: glass_pane
|
||||
D: oak_door
|
||||
A: air
|
||||
Structure:
|
||||
- "SSSSSSS"
|
||||
- "SWWGWWS"
|
||||
- "SWWAWWS"
|
||||
- "SWWDWWS"
|
||||
- "SSSSSSS"
|
||||
# ... more layers
|
||||
PlacementRules:
|
||||
RequiresSolidGround: true
|
||||
MinGroundLevel: 60
|
||||
MaxGroundLevel: 100
|
||||
AllowedBiomes: [plains, forest]
|
||||
```
|
||||
|
||||
## Prefab Class
|
||||
|
||||
```java
|
||||
public class Prefab {
|
||||
private String id;
|
||||
private Vector3i size;
|
||||
private Vector3i origin;
|
||||
private Map<Character, BlockType> palette;
|
||||
private List<String[]> structure;
|
||||
private PlacementRules rules;
|
||||
|
||||
// Get block at relative position
|
||||
public BlockType getBlock(int x, int y, int z);
|
||||
|
||||
// Get size
|
||||
public Vector3i getSize();
|
||||
|
||||
// Check placement rules
|
||||
public boolean canPlace(World world, Vector3i position);
|
||||
}
|
||||
```
|
||||
|
||||
## Placement Rules
|
||||
|
||||
```java
|
||||
public class PlacementRules {
|
||||
private boolean requiresSolidGround;
|
||||
private int minGroundLevel;
|
||||
private int maxGroundLevel;
|
||||
private Set<String> allowedBiomes;
|
||||
private float spacing;
|
||||
private int maxSlope;
|
||||
|
||||
public boolean evaluate(World world, Vector3i position) {
|
||||
// Check ground level
|
||||
if (position.y < minGroundLevel || position.y > maxGroundLevel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check biome
|
||||
Biome biome = world.getBiome(position.x, position.z);
|
||||
if (!allowedBiomes.contains(biome.getId())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check solid ground
|
||||
if (requiresSolidGround && !hasSolidGround(world, position)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Structure Placement
|
||||
|
||||
```java
|
||||
public class StructurePlacer {
|
||||
public void placeStructure(Prefab prefab, World world, Vector3i position, Rotation rotation) {
|
||||
Vector3i size = prefab.getSize();
|
||||
|
||||
for (int y = 0; y < size.y; y++) {
|
||||
for (int z = 0; z < size.z; z++) {
|
||||
for (int x = 0; x < size.x; x++) {
|
||||
BlockType block = prefab.getBlock(x, y, z);
|
||||
if (block != null && block != BlockTypes.AIR) {
|
||||
Vector3i rotated = rotate(x, y, z, rotation, size);
|
||||
Vector3i worldPos = position.add(rotated);
|
||||
world.setBlock(worldPos, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Rotation Support
|
||||
|
||||
```java
|
||||
public enum Rotation {
|
||||
NONE(0),
|
||||
CW_90(90),
|
||||
CW_180(180),
|
||||
CW_270(270);
|
||||
|
||||
public Vector3i rotate(Vector3i pos, Vector3i size) {
|
||||
switch (this) {
|
||||
case NONE:
|
||||
return pos;
|
||||
case CW_90:
|
||||
return new Vector3i(size.z - pos.z - 1, pos.y, pos.x);
|
||||
case CW_180:
|
||||
return new Vector3i(size.x - pos.x - 1, pos.y, size.z - pos.z - 1);
|
||||
case CW_270:
|
||||
return new Vector3i(pos.z, pos.y, size.x - pos.x - 1);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Prefab Variants
|
||||
|
||||
Support for randomized variants:
|
||||
|
||||
```yaml
|
||||
# prefabs/tree_oak.yaml
|
||||
Type: PrefabGroup
|
||||
Id: tree_oak
|
||||
Variants:
|
||||
- prefabs/tree_oak_small
|
||||
- prefabs/tree_oak_medium
|
||||
- prefabs/tree_oak_large
|
||||
Weights: [0.5, 0.35, 0.15]
|
||||
```
|
||||
|
||||
## Generation Integration
|
||||
|
||||
```java
|
||||
public class PrefabGenerator {
|
||||
private List<PrefabConfig> configs;
|
||||
|
||||
public void generatePrefabs(GenerationContainer container, int chunkX, int chunkZ) {
|
||||
for (PrefabConfig config : configs) {
|
||||
if (random.nextFloat() < config.frequency) {
|
||||
Vector3i position = findValidPosition(config.prefab, container, chunkX, chunkZ);
|
||||
if (position != null) {
|
||||
Rotation rotation = Rotation.values()[random.nextInt(4)];
|
||||
placePrefab(config.prefab, container, position, rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Entity Spawners
|
||||
|
||||
Prefabs can include entity spawn points:
|
||||
|
||||
```yaml
|
||||
# prefabs/dungeon_room.yaml
|
||||
Type: Prefab
|
||||
Id: dungeon_room
|
||||
EntitySpawns:
|
||||
- Type: skeleton
|
||||
Position: [5, 1, 5]
|
||||
Count: 2
|
||||
- Type: chest
|
||||
Position: [7, 1, 7]
|
||||
LootTable: dungeon_loot
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Prefab Guidelines:**
|
||||
- Use palettes for easy block substitution
|
||||
- Define clear placement rules
|
||||
- Support rotation for variety
|
||||
- Include variants for visual diversity
|
||||
- Consider performance with complex structures
|
||||
{{< /callout >}}
|
||||
220
content/world/worldgen/prefabs.fr.md
Normal file
220
content/world/worldgen/prefabs.fr.md
Normal file
@@ -0,0 +1,220 @@
|
||||
---
|
||||
title: Prefabs
|
||||
type: docs
|
||||
weight: 5
|
||||
---
|
||||
|
||||
Les prefabs sont des structures pré-construites qui peuvent être placées pendant la génération de monde, comme des bâtiments, des ruines et des donjons.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.worldgen.prefab`
|
||||
|
||||
## Système de Prefabs
|
||||
|
||||
Le système de prefabs gère le placement des structures :
|
||||
|
||||
```java
|
||||
public class PrefabPlacer {
|
||||
// Placer un prefab à une position
|
||||
public boolean place(Prefab prefab, World world, Vector3i position);
|
||||
|
||||
// Vérifier si un prefab peut être placé
|
||||
public boolean canPlace(Prefab prefab, World world, Vector3i position);
|
||||
|
||||
// Trouver une position valide pour un prefab
|
||||
public Vector3i findPlacement(Prefab prefab, World world, int chunkX, int chunkZ);
|
||||
}
|
||||
```
|
||||
|
||||
## Définition de Prefab
|
||||
|
||||
```yaml
|
||||
# prefabs/village_house.yaml
|
||||
Type: Prefab
|
||||
Id: village_house
|
||||
Size: [7, 5, 9]
|
||||
Origin: [3, 0, 4]
|
||||
Palette:
|
||||
W: oak_planks
|
||||
S: stone_bricks
|
||||
G: glass_pane
|
||||
D: oak_door
|
||||
A: air
|
||||
Structure:
|
||||
- "SSSSSSS"
|
||||
- "SWWGWWS"
|
||||
- "SWWAWWS"
|
||||
- "SWWDWWS"
|
||||
- "SSSSSSS"
|
||||
# ... plus de couches
|
||||
PlacementRules:
|
||||
RequiresSolidGround: true
|
||||
MinGroundLevel: 60
|
||||
MaxGroundLevel: 100
|
||||
AllowedBiomes: [plains, forest]
|
||||
```
|
||||
|
||||
## Classe Prefab
|
||||
|
||||
```java
|
||||
public class Prefab {
|
||||
private String id;
|
||||
private Vector3i size;
|
||||
private Vector3i origin;
|
||||
private Map<Character, BlockType> palette;
|
||||
private List<String[]> structure;
|
||||
private PlacementRules rules;
|
||||
|
||||
// Obtenir le bloc à une position relative
|
||||
public BlockType getBlock(int x, int y, int z);
|
||||
|
||||
// Obtenir la taille
|
||||
public Vector3i getSize();
|
||||
|
||||
// Vérifier les règles de placement
|
||||
public boolean canPlace(World world, Vector3i position);
|
||||
}
|
||||
```
|
||||
|
||||
## Règles de Placement
|
||||
|
||||
```java
|
||||
public class PlacementRules {
|
||||
private boolean requiresSolidGround;
|
||||
private int minGroundLevel;
|
||||
private int maxGroundLevel;
|
||||
private Set<String> allowedBiomes;
|
||||
private float spacing;
|
||||
private int maxSlope;
|
||||
|
||||
public boolean evaluate(World world, Vector3i position) {
|
||||
// Vérifier le niveau du sol
|
||||
if (position.y < minGroundLevel || position.y > maxGroundLevel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Vérifier le biome
|
||||
Biome biome = world.getBiome(position.x, position.z);
|
||||
if (!allowedBiomes.contains(biome.getId())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Vérifier le sol solide
|
||||
if (requiresSolidGround && !hasSolidGround(world, position)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Placement de Structure
|
||||
|
||||
```java
|
||||
public class StructurePlacer {
|
||||
public void placeStructure(Prefab prefab, World world, Vector3i position, Rotation rotation) {
|
||||
Vector3i size = prefab.getSize();
|
||||
|
||||
for (int y = 0; y < size.y; y++) {
|
||||
for (int z = 0; z < size.z; z++) {
|
||||
for (int x = 0; x < size.x; x++) {
|
||||
BlockType block = prefab.getBlock(x, y, z);
|
||||
if (block != null && block != BlockTypes.AIR) {
|
||||
Vector3i rotated = rotate(x, y, z, rotation, size);
|
||||
Vector3i worldPos = position.add(rotated);
|
||||
world.setBlock(worldPos, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Support de Rotation
|
||||
|
||||
```java
|
||||
public enum Rotation {
|
||||
NONE(0),
|
||||
CW_90(90),
|
||||
CW_180(180),
|
||||
CW_270(270);
|
||||
|
||||
public Vector3i rotate(Vector3i pos, Vector3i size) {
|
||||
switch (this) {
|
||||
case NONE:
|
||||
return pos;
|
||||
case CW_90:
|
||||
return new Vector3i(size.z - pos.z - 1, pos.y, pos.x);
|
||||
case CW_180:
|
||||
return new Vector3i(size.x - pos.x - 1, pos.y, size.z - pos.z - 1);
|
||||
case CW_270:
|
||||
return new Vector3i(pos.z, pos.y, size.x - pos.x - 1);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Variantes de Prefabs
|
||||
|
||||
Support pour des variantes aléatoires :
|
||||
|
||||
```yaml
|
||||
# prefabs/tree_oak.yaml
|
||||
Type: PrefabGroup
|
||||
Id: tree_oak
|
||||
Variants:
|
||||
- prefabs/tree_oak_small
|
||||
- prefabs/tree_oak_medium
|
||||
- prefabs/tree_oak_large
|
||||
Weights: [0.5, 0.35, 0.15]
|
||||
```
|
||||
|
||||
## Intégration à la Génération
|
||||
|
||||
```java
|
||||
public class PrefabGenerator {
|
||||
private List<PrefabConfig> configs;
|
||||
|
||||
public void generatePrefabs(GenerationContainer container, int chunkX, int chunkZ) {
|
||||
for (PrefabConfig config : configs) {
|
||||
if (random.nextFloat() < config.frequency) {
|
||||
Vector3i position = findValidPosition(config.prefab, container, chunkX, chunkZ);
|
||||
if (position != null) {
|
||||
Rotation rotation = Rotation.values()[random.nextInt(4)];
|
||||
placePrefab(config.prefab, container, position, rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Spawners d'Entités
|
||||
|
||||
Les prefabs peuvent inclure des points de spawn d'entités :
|
||||
|
||||
```yaml
|
||||
# prefabs/dungeon_room.yaml
|
||||
Type: Prefab
|
||||
Id: dungeon_room
|
||||
EntitySpawns:
|
||||
- Type: skeleton
|
||||
Position: [5, 1, 5]
|
||||
Count: 2
|
||||
- Type: chest
|
||||
Position: [7, 1, 7]
|
||||
LootTable: dungeon_loot
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives des Prefabs :**
|
||||
- Utilisez des palettes pour une substitution de blocs facile
|
||||
- Définissez des règles de placement claires
|
||||
- Supportez la rotation pour la variété
|
||||
- Incluez des variantes pour la diversité visuelle
|
||||
- Considérez les performances avec les structures complexes
|
||||
{{< /callout >}}
|
||||
281
content/world/worldgen/prop-placement.en.md
Normal file
281
content/world/worldgen/prop-placement.en.md
Normal 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 >}}
|
||||
281
content/world/worldgen/prop-placement.fr.md
Normal file
281
content/world/worldgen/prop-placement.fr.md
Normal file
@@ -0,0 +1,281 @@
|
||||
---
|
||||
title: Placement de Props
|
||||
type: docs
|
||||
weight: 10
|
||||
---
|
||||
|
||||
Le placement de props gère la génération de végétation, de décorations et de petits objets sur les surfaces du terrain.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.hytalegenerator.props`
|
||||
|
||||
## Système de Props
|
||||
|
||||
Les props sont de petites caractéristiques placées après la génération du terrain :
|
||||
|
||||
```java
|
||||
public interface PropPlacer {
|
||||
// Placer des props dans un 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;
|
||||
}
|
||||
```
|
||||
|
||||
## Définition de Prop
|
||||
|
||||
```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]
|
||||
```
|
||||
|
||||
## Fournisseurs de Position
|
||||
|
||||
Déterminent où les props peuvent être placés :
|
||||
|
||||
### RandomPositionProvider
|
||||
|
||||
Positions de surface aléatoires :
|
||||
|
||||
```yaml
|
||||
Type: RandomPosition
|
||||
Density: 0.1
|
||||
GridSize: 4 # Une tentative par zone 4x4
|
||||
```
|
||||
|
||||
### GridPositionProvider
|
||||
|
||||
Grille régulière avec gigue :
|
||||
|
||||
```yaml
|
||||
Type: GridPosition
|
||||
Spacing: 8
|
||||
Jitter: 3
|
||||
```
|
||||
|
||||
### NoisePositionProvider
|
||||
|
||||
Regroupement basé sur le bruit :
|
||||
|
||||
```yaml
|
||||
Type: NoisePosition
|
||||
NoiseScale: 0.05
|
||||
Threshold: 0.3
|
||||
Density: 0.5
|
||||
```
|
||||
|
||||
## Règles de Placement
|
||||
|
||||
```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) {
|
||||
// Vérifier le type de surface
|
||||
if (!validSurfaces.contains(ctx.surfaceBlock)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Vérifier la pente
|
||||
if (ctx.slope < minSlope || ctx.slope > maxSlope) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Vérifier l'espacement des autres props
|
||||
if (!hasMinSpacing(ctx)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Vérifier le dégagement
|
||||
if (!hasClearance(ctx)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Props de Végétation
|
||||
|
||||
### TreePlacer
|
||||
|
||||
Place des arbres avec variation par biome :
|
||||
|
||||
```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
|
||||
|
||||
Place de l'herbe et des fleurs :
|
||||
|
||||
```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
|
||||
|
||||
Place des buissons et arbustes :
|
||||
|
||||
```yaml
|
||||
Type: BushPlacer
|
||||
Density: 0.1
|
||||
Prefabs: [bush_small, bush_medium]
|
||||
NearTreesOnly: true
|
||||
TreeDistance: 5
|
||||
```
|
||||
|
||||
## Props d'Objets
|
||||
|
||||
### RockPlacer
|
||||
|
||||
Place des rochers et blocs :
|
||||
|
||||
```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
|
||||
|
||||
Place des troncs tombés, branches :
|
||||
|
||||
```yaml
|
||||
Type: DebrisPlacer
|
||||
Density: 0.03
|
||||
Items:
|
||||
- fallen_log
|
||||
- branch
|
||||
- leaf_pile
|
||||
ForestOnly: true
|
||||
```
|
||||
|
||||
## Intégration des Biomes
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
## Prop Placer Personnalisé
|
||||
|
||||
```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);
|
||||
// Placer un prop personnalisé
|
||||
placeMyProp(container, x, surfaceY + 1, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives de Placement de Props :**
|
||||
- Utilisez une densité appropriée pour l'ambiance du biome
|
||||
- Assurez-vous que les props ne se chevauchent pas
|
||||
- Ajoutez de la variété avec plusieurs variantes
|
||||
- Considérez les performances avec une haute densité
|
||||
- Testez la distribution visuelle sur le terrain
|
||||
{{< /callout >}}
|
||||
241
content/world/worldgen/world-loader.en.md
Normal file
241
content/world/worldgen/world-loader.en.md
Normal file
@@ -0,0 +1,241 @@
|
||||
---
|
||||
title: World Loader
|
||||
type: docs
|
||||
weight: 1
|
||||
---
|
||||
|
||||
The World Loader system manages chunk loading, generation scheduling, and world streaming.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.worldgen.loader`
|
||||
|
||||
## WorldLoader Class
|
||||
|
||||
The `WorldLoader` coordinates chunk loading and generation:
|
||||
|
||||
```java
|
||||
public class WorldLoader {
|
||||
// Load chunk at coordinates
|
||||
public CompletableFuture<Chunk> loadChunk(int chunkX, int chunkZ);
|
||||
|
||||
// Unload chunk
|
||||
public void unloadChunk(int chunkX, int chunkZ);
|
||||
|
||||
// Check if chunk is loaded
|
||||
public boolean isChunkLoaded(int chunkX, int chunkZ);
|
||||
|
||||
// Get loaded chunk
|
||||
public Chunk getChunk(int chunkX, int chunkZ);
|
||||
|
||||
// Request chunk generation
|
||||
public void requestGeneration(int chunkX, int chunkZ, int priority);
|
||||
}
|
||||
```
|
||||
|
||||
## Loading Pipeline
|
||||
|
||||
The chunk loading process follows several stages:
|
||||
|
||||
```
|
||||
Chunk Loading Pipeline
|
||||
├── 1. Check Cache
|
||||
│ └── Return if cached
|
||||
├── 2. Load from Disk
|
||||
│ └── Return if saved
|
||||
├── 3. Queue for Generation
|
||||
│ ├── Priority Assignment
|
||||
│ └── Thread Pool Dispatch
|
||||
├── 4. Generate Chunk
|
||||
│ ├── Terrain Pass
|
||||
│ ├── Cave Pass
|
||||
│ ├── Structure Pass
|
||||
│ └── Decoration Pass
|
||||
└── 5. Cache and Return
|
||||
```
|
||||
|
||||
## ChunkLoadRequest
|
||||
|
||||
```java
|
||||
public class ChunkLoadRequest {
|
||||
private int chunkX;
|
||||
private int chunkZ;
|
||||
private int priority;
|
||||
private LoadReason reason;
|
||||
private CompletableFuture<Chunk> future;
|
||||
|
||||
public enum LoadReason {
|
||||
PLAYER_PROXIMITY,
|
||||
ENTITY_SPAWN,
|
||||
STRUCTURE_CHECK,
|
||||
EXPLICIT_REQUEST
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Load Priority System
|
||||
|
||||
Chunks are loaded based on priority:
|
||||
|
||||
```java
|
||||
public class LoadPriority {
|
||||
// Highest priority - player's current chunk
|
||||
public static final int IMMEDIATE = 0;
|
||||
|
||||
// High priority - chunks around player
|
||||
public static final int PLAYER_VIEW = 100;
|
||||
|
||||
// Normal priority - entity needs
|
||||
public static final int ENTITY = 200;
|
||||
|
||||
// Low priority - preloading
|
||||
public static final int PRELOAD = 300;
|
||||
|
||||
// Lowest priority - background tasks
|
||||
public static final int BACKGROUND = 400;
|
||||
}
|
||||
```
|
||||
|
||||
## Generation Threading
|
||||
|
||||
World generation uses a thread pool:
|
||||
|
||||
```java
|
||||
public class GenerationThreadPool {
|
||||
private int threadCount;
|
||||
private PriorityBlockingQueue<ChunkLoadRequest> queue;
|
||||
|
||||
// Configure thread count
|
||||
public void setThreadCount(int count);
|
||||
|
||||
// Get queue size
|
||||
public int getPendingCount();
|
||||
|
||||
// Clear low-priority requests
|
||||
public void clearLowPriority(int threshold);
|
||||
}
|
||||
```
|
||||
|
||||
## Chunk Cache
|
||||
|
||||
The loader maintains a chunk cache:
|
||||
|
||||
```java
|
||||
public class ChunkCache {
|
||||
private int maxSize;
|
||||
private Map<ChunkPos, Chunk> cache;
|
||||
|
||||
// Get cached chunk
|
||||
public Chunk get(int chunkX, int chunkZ);
|
||||
|
||||
// Add to cache
|
||||
public void put(int chunkX, int chunkZ, Chunk chunk);
|
||||
|
||||
// Remove from cache
|
||||
public void invalidate(int chunkX, int chunkZ);
|
||||
|
||||
// Clear cache
|
||||
public void clear();
|
||||
|
||||
// Get cache statistics
|
||||
public CacheStats getStats();
|
||||
}
|
||||
```
|
||||
|
||||
## View Distance Loading
|
||||
|
||||
```java
|
||||
public class ViewDistanceLoader {
|
||||
private int viewDistance;
|
||||
private Player player;
|
||||
|
||||
// Update loaded chunks for player
|
||||
public void updatePlayerChunks(Player player) {
|
||||
Vector3d pos = player.getPosition();
|
||||
int centerX = (int) pos.x >> 4;
|
||||
int centerZ = (int) pos.z >> 4;
|
||||
|
||||
// Load chunks in view distance
|
||||
for (int dx = -viewDistance; dx <= viewDistance; dx++) {
|
||||
for (int dz = -viewDistance; dz <= viewDistance; dz++) {
|
||||
int priority = Math.abs(dx) + Math.abs(dz);
|
||||
worldLoader.requestGeneration(centerX + dx, centerZ + dz, priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Container System
|
||||
|
||||
Generation containers manage intermediate data:
|
||||
|
||||
```java
|
||||
public class GenerationContainer {
|
||||
private int chunkX;
|
||||
private int chunkZ;
|
||||
private BlockBuffer blockBuffer;
|
||||
private BiomeMap biomeMap;
|
||||
private HeightMap heightMap;
|
||||
|
||||
// Set block in container
|
||||
public void setBlock(int x, int y, int z, BlockType type);
|
||||
|
||||
// Get block from container
|
||||
public BlockType getBlock(int x, int y, int z);
|
||||
|
||||
// Finalize to chunk
|
||||
public Chunk toChunk();
|
||||
}
|
||||
```
|
||||
|
||||
## Event Hooks
|
||||
|
||||
```java
|
||||
// Pre-generation event
|
||||
getEventRegistry().register(ChunkPreGenerateEvent.class, event -> {
|
||||
int chunkX = event.getChunkX();
|
||||
int chunkZ = event.getChunkZ();
|
||||
// Modify generation parameters
|
||||
});
|
||||
|
||||
// Post-generation event
|
||||
getEventRegistry().register(ChunkGeneratedEvent.class, event -> {
|
||||
Chunk chunk = event.getChunk();
|
||||
// Post-process chunk
|
||||
});
|
||||
|
||||
// Chunk load event
|
||||
getEventRegistry().register(ChunkLoadEvent.class, event -> {
|
||||
Chunk chunk = event.getChunk();
|
||||
// Handle chunk load
|
||||
});
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# worldgen/loader_config.yaml
|
||||
WorldLoader:
|
||||
ThreadCount: 4
|
||||
MaxQueueSize: 1000
|
||||
CacheSize: 512
|
||||
ViewDistance: 12
|
||||
PreloadDistance: 2
|
||||
UnloadDelay: 30000
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Loader Guidelines:**
|
||||
- Use appropriate priorities for chunk requests
|
||||
- Don't request too many chunks at once
|
||||
- Let the cache system handle repeated requests
|
||||
- Monitor queue size for performance issues
|
||||
{{< /callout >}}
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
**Performance:** Chunk generation is expensive. Avoid:
|
||||
- Requesting chunks far from players
|
||||
- Bypassing the cache system
|
||||
- Blocking on chunk futures on the main thread
|
||||
{{< /callout >}}
|
||||
241
content/world/worldgen/world-loader.fr.md
Normal file
241
content/world/worldgen/world-loader.fr.md
Normal file
@@ -0,0 +1,241 @@
|
||||
---
|
||||
title: World Loader
|
||||
type: docs
|
||||
weight: 1
|
||||
---
|
||||
|
||||
Le système World Loader gère le chargement des chunks, la planification de génération et le streaming du monde.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.worldgen.loader`
|
||||
|
||||
## Classe WorldLoader
|
||||
|
||||
Le `WorldLoader` coordonne le chargement et la génération des chunks :
|
||||
|
||||
```java
|
||||
public class WorldLoader {
|
||||
// Charger un chunk aux coordonnées
|
||||
public CompletableFuture<Chunk> loadChunk(int chunkX, int chunkZ);
|
||||
|
||||
// Décharger un chunk
|
||||
public void unloadChunk(int chunkX, int chunkZ);
|
||||
|
||||
// Vérifier si un chunk est chargé
|
||||
public boolean isChunkLoaded(int chunkX, int chunkZ);
|
||||
|
||||
// Obtenir un chunk chargé
|
||||
public Chunk getChunk(int chunkX, int chunkZ);
|
||||
|
||||
// Demander la génération d'un chunk
|
||||
public void requestGeneration(int chunkX, int chunkZ, int priority);
|
||||
}
|
||||
```
|
||||
|
||||
## Pipeline de Chargement
|
||||
|
||||
Le processus de chargement de chunk suit plusieurs étapes :
|
||||
|
||||
```
|
||||
Pipeline de Chargement de Chunk
|
||||
├── 1. Vérifier le Cache
|
||||
│ └── Retourner si en cache
|
||||
├── 2. Charger depuis le Disque
|
||||
│ └── Retourner si sauvegardé
|
||||
├── 3. Mettre en Queue pour Génération
|
||||
│ ├── Attribution de Priorité
|
||||
│ └── Dispatch Thread Pool
|
||||
├── 4. Générer le Chunk
|
||||
│ ├── Passe Terrain
|
||||
│ ├── Passe Grottes
|
||||
│ ├── Passe Structures
|
||||
│ └── Passe Décoration
|
||||
└── 5. Mettre en Cache et Retourner
|
||||
```
|
||||
|
||||
## ChunkLoadRequest
|
||||
|
||||
```java
|
||||
public class ChunkLoadRequest {
|
||||
private int chunkX;
|
||||
private int chunkZ;
|
||||
private int priority;
|
||||
private LoadReason reason;
|
||||
private CompletableFuture<Chunk> future;
|
||||
|
||||
public enum LoadReason {
|
||||
PLAYER_PROXIMITY,
|
||||
ENTITY_SPAWN,
|
||||
STRUCTURE_CHECK,
|
||||
EXPLICIT_REQUEST
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Système de Priorité de Chargement
|
||||
|
||||
Les chunks sont chargés selon leur priorité :
|
||||
|
||||
```java
|
||||
public class LoadPriority {
|
||||
// Priorité la plus haute - chunk actuel du joueur
|
||||
public static final int IMMEDIATE = 0;
|
||||
|
||||
// Haute priorité - chunks autour du joueur
|
||||
public static final int PLAYER_VIEW = 100;
|
||||
|
||||
// Priorité normale - besoins des entités
|
||||
public static final int ENTITY = 200;
|
||||
|
||||
// Basse priorité - préchargement
|
||||
public static final int PRELOAD = 300;
|
||||
|
||||
// Priorité la plus basse - tâches de fond
|
||||
public static final int BACKGROUND = 400;
|
||||
}
|
||||
```
|
||||
|
||||
## Threading de Génération
|
||||
|
||||
La génération de monde utilise un pool de threads :
|
||||
|
||||
```java
|
||||
public class GenerationThreadPool {
|
||||
private int threadCount;
|
||||
private PriorityBlockingQueue<ChunkLoadRequest> queue;
|
||||
|
||||
// Configurer le nombre de threads
|
||||
public void setThreadCount(int count);
|
||||
|
||||
// Obtenir la taille de la queue
|
||||
public int getPendingCount();
|
||||
|
||||
// Effacer les requêtes basse priorité
|
||||
public void clearLowPriority(int threshold);
|
||||
}
|
||||
```
|
||||
|
||||
## Cache de Chunks
|
||||
|
||||
Le loader maintient un cache de chunks :
|
||||
|
||||
```java
|
||||
public class ChunkCache {
|
||||
private int maxSize;
|
||||
private Map<ChunkPos, Chunk> cache;
|
||||
|
||||
// Obtenir un chunk en cache
|
||||
public Chunk get(int chunkX, int chunkZ);
|
||||
|
||||
// Ajouter au cache
|
||||
public void put(int chunkX, int chunkZ, Chunk chunk);
|
||||
|
||||
// Supprimer du cache
|
||||
public void invalidate(int chunkX, int chunkZ);
|
||||
|
||||
// Vider le cache
|
||||
public void clear();
|
||||
|
||||
// Obtenir les statistiques du cache
|
||||
public CacheStats getStats();
|
||||
}
|
||||
```
|
||||
|
||||
## Chargement par Distance de Vue
|
||||
|
||||
```java
|
||||
public class ViewDistanceLoader {
|
||||
private int viewDistance;
|
||||
private Player player;
|
||||
|
||||
// Mettre à jour les chunks chargés pour un joueur
|
||||
public void updatePlayerChunks(Player player) {
|
||||
Vector3d pos = player.getPosition();
|
||||
int centerX = (int) pos.x >> 4;
|
||||
int centerZ = (int) pos.z >> 4;
|
||||
|
||||
// Charger les chunks dans la distance de vue
|
||||
for (int dx = -viewDistance; dx <= viewDistance; dx++) {
|
||||
for (int dz = -viewDistance; dz <= viewDistance; dz++) {
|
||||
int priority = Math.abs(dx) + Math.abs(dz);
|
||||
worldLoader.requestGeneration(centerX + dx, centerZ + dz, priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Système de Conteneurs
|
||||
|
||||
Les conteneurs de génération gèrent les données intermédiaires :
|
||||
|
||||
```java
|
||||
public class GenerationContainer {
|
||||
private int chunkX;
|
||||
private int chunkZ;
|
||||
private BlockBuffer blockBuffer;
|
||||
private BiomeMap biomeMap;
|
||||
private HeightMap heightMap;
|
||||
|
||||
// Définir un bloc dans le conteneur
|
||||
public void setBlock(int x, int y, int z, BlockType type);
|
||||
|
||||
// Obtenir un bloc du conteneur
|
||||
public BlockType getBlock(int x, int y, int z);
|
||||
|
||||
// Finaliser en chunk
|
||||
public Chunk toChunk();
|
||||
}
|
||||
```
|
||||
|
||||
## Hooks d'Événements
|
||||
|
||||
```java
|
||||
// Événement pré-génération
|
||||
getEventRegistry().register(ChunkPreGenerateEvent.class, event -> {
|
||||
int chunkX = event.getChunkX();
|
||||
int chunkZ = event.getChunkZ();
|
||||
// Modifier les paramètres de génération
|
||||
});
|
||||
|
||||
// Événement post-génération
|
||||
getEventRegistry().register(ChunkGeneratedEvent.class, event -> {
|
||||
Chunk chunk = event.getChunk();
|
||||
// Post-traiter le chunk
|
||||
});
|
||||
|
||||
// Événement de chargement de chunk
|
||||
getEventRegistry().register(ChunkLoadEvent.class, event -> {
|
||||
Chunk chunk = event.getChunk();
|
||||
// Gérer le chargement du chunk
|
||||
});
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
# worldgen/loader_config.yaml
|
||||
WorldLoader:
|
||||
ThreadCount: 4
|
||||
MaxQueueSize: 1000
|
||||
CacheSize: 512
|
||||
ViewDistance: 12
|
||||
PreloadDistance: 2
|
||||
UnloadDelay: 30000
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives du Loader :**
|
||||
- Utilisez des priorités appropriées pour les requêtes de chunks
|
||||
- Ne demandez pas trop de chunks à la fois
|
||||
- Laissez le système de cache gérer les requêtes répétées
|
||||
- Surveillez la taille de la queue pour les problèmes de performance
|
||||
{{< /callout >}}
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
**Performance :** La génération de chunks est coûteuse. Évitez :
|
||||
- De demander des chunks loin des joueurs
|
||||
- De contourner le système de cache
|
||||
- De bloquer sur les futures de chunks sur le thread principal
|
||||
{{< /callout >}}
|
||||
226
content/world/worldgen/zones.en.md
Normal file
226
content/world/worldgen/zones.en.md
Normal file
@@ -0,0 +1,226 @@
|
||||
---
|
||||
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 >}}
|
||||
226
content/world/worldgen/zones.fr.md
Normal file
226
content/world/worldgen/zones.fr.md
Normal file
@@ -0,0 +1,226 @@
|
||||
---
|
||||
title: Zones
|
||||
type: docs
|
||||
weight: 6
|
||||
---
|
||||
|
||||
Les zones définissent des régions distinctes du monde avec des règles de génération, des biomes et des caractéristiques spécifiques.
|
||||
|
||||
**Package:** `com.hypixel.hytale.server.worldgen.zone`
|
||||
|
||||
## Système de Zones
|
||||
|
||||
Les zones partitionnent le monde en zones distinctes :
|
||||
|
||||
```java
|
||||
public class ZoneManager {
|
||||
// Obtenir la zone à une position
|
||||
public Zone getZone(int x, int z);
|
||||
|
||||
// Enregistrer une zone
|
||||
public void registerZone(Zone zone);
|
||||
|
||||
// Obtenir toutes les zones
|
||||
public List<Zone> getZones();
|
||||
}
|
||||
```
|
||||
|
||||
## Définition de Zone
|
||||
|
||||
```yaml
|
||||
# zones/emerald_grove.yaml
|
||||
Type: Zone
|
||||
Id: emerald_grove
|
||||
DisplayName: "Bosquet d'Émeraude"
|
||||
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
|
||||
```
|
||||
|
||||
## Classe Zone
|
||||
|
||||
```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;
|
||||
|
||||
// Vérifier si une position est dans la zone
|
||||
public boolean contains(int x, int z);
|
||||
|
||||
// Obtenir le biome spécifique à la zone
|
||||
public Biome getBiome(int x, int z);
|
||||
|
||||
// Modifier la génération
|
||||
public void modifyGeneration(GenerationContainer container);
|
||||
}
|
||||
```
|
||||
|
||||
## Formes de Zones
|
||||
|
||||
```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) {
|
||||
// Algorithme point-dans-polygone
|
||||
return isPointInPolygon(x, z, vertices);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Transitions de Zones
|
||||
|
||||
Transitions douces entre 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; // Complètement dans la zone 'from'
|
||||
}
|
||||
if (distTo > transitionWidth) {
|
||||
return 1.0f; // Complètement dans la zone 'to'
|
||||
}
|
||||
|
||||
return distFrom / (distFrom + distTo);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Couches de Zones
|
||||
|
||||
Les zones peuvent avoir des couches verticales :
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
## Priorité des Zones
|
||||
|
||||
Quand les zones se chevauchent, la priorité détermine laquelle s'applique :
|
||||
|
||||
```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);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Zones Dynamiques
|
||||
|
||||
Zones qui peuvent changer à l'exécution :
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives des Zones :**
|
||||
- Utilisez les zones pour des régions distinctes du monde
|
||||
- Définissez des transitions douces entre zones
|
||||
- Considérez la priorité des zones pour les chevauchements
|
||||
- Utilisez des formes appropriées pour les limites de zones
|
||||
- Testez minutieusement la génération des zones
|
||||
{{< /callout >}}
|
||||
Reference in New Issue
Block a user