biome data definitions, notes on how to distribute
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-10-23 15:30:27 -04:00
parent aa70f39eb9
commit 70f7a78626
16 changed files with 1638 additions and 2 deletions

View File

@ -0,0 +1,45 @@
{
"biomes": [
{
"id": "sky",
"displayName": "Sky",
"isAerial": true,
"isSurface": false,
"isSubterranean": false,
"regions": [
{
"frequency": 1.0,
"baseFloorVoxel": 0,
"floorVariants": [],
"foliageDescription": []
}
]
},
{
"id": "plains",
"displayName": "Plains",
"isAerial": false,
"isSurface": true,
"isSubterranean": false,
"regions": [
{
"frequency": 1.0,
"baseFloorVoxel": 1,
"floorVariants": [
{
"voxelId": 2,
"frequency": 1.0,
"dispersion": 1.0,
"priority": 1.0
}
],
"foliageDescription": [
]
}
]
}
],
"files": [
]
}

View File

@ -19,6 +19,7 @@
- @subpage server
- @subpage indexrendering
- @subpage entitytypesindex
- @subpage worldgenerationindex
# What is this section

View File

@ -0,0 +1,19 @@
@page biomeselection Biome Selection
Details on how biome selection works
The world is segmented into "zones" via voronoi partitioning
These zones have themes attached to them
The themes filter the biomes that can be picked from the overall biome pool
The biomes are also filtered by terrain attributes (elevation, moisture, temperature, magic count, etc)
The biome pool is then mapped to regions which are indexed into based on noise functions
Once the biome is selected, a fine grain surface value is calculated
All other generation proceeds based on the specific biome selected from the pool via noise

View File

@ -0,0 +1,4 @@
@page worldgenerationindex World Generation
[TOC]
- @subpage biomeselection

View File

@ -7,9 +7,9 @@ Different terrain levels:
Sky 1: 12000m - 14000m
Sky 3: 12000m - 14000m
Sky 1: 10000m - 12000m
Sky 2: 10000m - 12000m
Sky 1: 8000m - 10000m

View File

@ -21,5 +21,10 @@ Types of data we need:
- magic (?)
Also stored to disk is the zone map
This is stored in the format of a pixel map that maps pixels to zone IDs
These IDs map to a list of zone definitions
# In Memory

View File

@ -1011,6 +1011,9 @@ Bug fixes
Debug
- Draw all bones with orientations
Biome description enhancements
- Weather description
Would be nice to be able to cut clients that stream their logs to my server
Refactor render flags

View File

@ -4,6 +4,7 @@ import java.util.LinkedList;
import java.util.List;
import electrosphere.game.data.audio.SurfaceAudioCollection;
import electrosphere.game.data.biome.BiomeTypeMap;
import electrosphere.game.data.common.CommonEntityLoader;
import electrosphere.game.data.common.CommonEntityMap;
import electrosphere.game.data.common.CommonEntityType;
@ -56,6 +57,11 @@ public class Config {
* The crafting recipe map
*/
RecipeDataMap recipeMap;
/**
* The biome map
*/
BiomeTypeMap biomeMap;
/**
* Loads the default data
@ -76,6 +82,7 @@ public class Config {
config.projectileTypeHolder.init();
config.unitLoader = UnitLoader.create(FileUtils.loadObjectFromAssetPath("Data/game/units/units.json", UnitDefinitionFile.class));
config.recipeMap = RecipeDataMap.loadRecipeFiles("Data/game/recipes.json");
config.biomeMap = BiomeTypeMap.loadBiomeFile("Data/game/biomes.json");
//validate
ConfigValidator.valdiate(config);
@ -260,5 +267,13 @@ public class Config {
public RecipeDataMap getRecipeMap(){
return recipeMap;
}
/**
* Gets the biome map
* @return The biome map
*/
public BiomeTypeMap getBiomeMap(){
return biomeMap;
}
}

View File

@ -0,0 +1,90 @@
package electrosphere.game.data.biome;
import java.util.List;
/**
* Data about a given biome
*/
public class BiomeData {
/**
* The id of the biome
*/
String id;
/**
* The display name of the biome
*/
String displayName;
/**
* The regions available to the biome
*/
List<BiomeRegion> regions;
/**
* True if this region applies above the surface
*/
Boolean isAerial;
/**
* True if this region applies to the surface
*/
Boolean isSurface;
/**
* True if this region applies below the surface
*/
Boolean isSubterranean;
/**
* Gets the id of the biome
* @return The id of the biome
*/
public String getId() {
return id;
}
/**
* Gets the display name of the biome
* @return The display name
*/
public String getDisplayName() {
return displayName;
}
/**
* Gets the regions of the biome
* @return The regions
*/
public List<BiomeRegion> getRegions(){
return regions;
}
/**
* Gets whether the biome is a surface biome or not
* @return true if is a surface biome, false otherwise
*/
public Boolean isSurface(){
return isSurface;
}
/**
* Gets whether the biome is an aerial biome or not
* @return true if is an aerial biome, false otherwise
*/
public Boolean isAerial(){
return isAerial;
}
/**
* Gets whether the biome is a subterreanean biome or not
* @return true if is a subterreanean biome, false otherwise
*/
public Boolean isSubterranean(){
return isSubterranean;
}
}

View File

@ -0,0 +1,52 @@
package electrosphere.game.data.biome;
import java.util.List;
/**
* The data file containing all biome data
*/
public class BiomeDataFile {
/**
* The biome data in this file
*/
List<BiomeData> biomes;
/**
* All child files of this one
*/
List<String> files;
/**
* Gets the biome data in this file
* @return The biome data in this file
*/
public List<BiomeData> getBiomes() {
return biomes;
}
/**
* Sets the biome data in this file
* @param biomes The biome data in this file
*/
public void setBiomes(List<BiomeData> biomes) {
this.biomes = biomes;
}
/**
* Gets all child files of this one
* @return All child files of this one
*/
public List<String> getFiles() {
return files;
}
/**
* Sets all child files of this one
* @param files All child files of this one
*/
public void setFiles(List<String> files) {
this.files = files;
}
}

View File

@ -0,0 +1,28 @@
package electrosphere.game.data.biome;
/**
* Describes how a given voxel type may be used to populate the floor of the biome
*/
public class BiomeFloorElement {
/**
* The id of the voxel type for this element in particular
*/
int voxelId;
/**
* The frequency of this element in particular
*/
Double frequency;
/**
* The scale of the noise used to generate this element
*/
Double dispersion;
/**
* The priority of this floor element in particular
*/
Double priority;
}

View File

@ -0,0 +1,30 @@
package electrosphere.game.data.biome;
import java.util.List;
/**
* Describes behavior for spawning a specific type of foliage in the biome
*/
public class BiomeFoliageDescription {
/**
* The liust of entity IDs of this foliage type in particular
*/
List<String> entityIDs;
/**
* The frequency of this element in particular
*/
Double frequency;
/**
* The scale of the noise used to generate this element
*/
Double dispersion;
/**
* The priority of this floor element in particular
*/
Double priority;
}

View File

@ -0,0 +1,43 @@
package electrosphere.game.data.biome;
import java.util.List;
/**
* A region type that can generate inside a biome
* Examples:
* A field
* A natural trail
* A grove of trees
* A field of stalactites
*
* The idea of having regions is to allow spatially isolating different generation components within a larger biome.
* The prime example of this is generating a large tree within a larger forest biome.
* You might want to spatially separate the tree so that you can apply special generation rules around it in particular.
* IE, generate roots, but only around the tree.
*/
public class BiomeRegion {
/**
* The frequency of this region within the biome
*/
Double frequency;
/**
* The base floor voxel
* This is populated by default, then overridden if any of the floor variants trigger/supercede it
*/
Integer baseFloorVoxel;
/**
* The different floor elements
*/
List<BiomeFloorElement> floorVariants;
/**
* The list of foliage descriptions available to this biome type
*/
List<BiomeFoliageDescription> foliageDescriptions;
}

View File

@ -0,0 +1,141 @@
package electrosphere.game.data.biome;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import electrosphere.util.FileUtils;
/**
* Structure for efficiently accessing biome data
*/
public class BiomeTypeMap {
/**
* The map of biome id -> biome data
*/
Map<String,BiomeData> idBiomeMap = new HashMap<String,BiomeData>();
/**
* The list of surface biomes
*/
List<BiomeData> surfaceBiomes = new LinkedList<BiomeData>();
/**
* The list of sky biomes
*/
List<BiomeData> skyBiomes = new LinkedList<BiomeData>();
/**
* The list of subterranean biomes
*/
List<BiomeData> subterraneanBiomes = new LinkedList<BiomeData>();
/**
* Adds biome data to the loader
* @param name The id of the biome
* @param type The biome data
*/
public void putBiome(String id, BiomeData biome){
idBiomeMap.put(id,biome);
if(biome.isSurface()){
this.surfaceBiomes.add(biome);
}
if(biome.isAerial()){
this.skyBiomes.add(biome);
}
if(biome.isSubterranean()){
this.subterraneanBiomes.add(biome);
}
}
/**
* Gets biome data from the id of the biome
* @param id The id of the biome
* @return The biome data if it exists, null otherwise
*/
public BiomeData getType(String id){
return idBiomeMap.get(id);
}
/**
* Gets the collection of all biome data
* @return the collection of all biome data
*/
public Collection<BiomeData> getTypes(){
return idBiomeMap.values();
}
/**
* Gets the set of all biome data id's stored in the loader
* @return the set of all biome data ids
*/
public Set<String> getTypeIds(){
return idBiomeMap.keySet();
}
/**
* Reads a child biome defintion file
* @param filename The filename
* @return The list of biomes in the file
*/
static List<BiomeData> recursiveReadBiomeLoader(String filename){
List<BiomeData> typeList = new LinkedList<BiomeData>();
BiomeDataFile loaderFile = FileUtils.loadObjectFromAssetPath(filename, BiomeDataFile.class);
//push the types from this file
for(BiomeData type : loaderFile.getBiomes()){
typeList.add(type);
}
//push types from any other files
for(String filepath : loaderFile.getFiles()){
List<BiomeData> parsedTypeList = recursiveReadBiomeLoader(filepath);
for(BiomeData type : parsedTypeList){
typeList.add(type);
}
}
return typeList;
}
/**
* Loads all biome definition files recursively
* @param initialPath The initial path to recurse from
* @return The biome defintion interface
*/
public static BiomeTypeMap loadBiomeFile(String initialPath) {
BiomeTypeMap rVal = new BiomeTypeMap();
List<BiomeData> typeList = recursiveReadBiomeLoader(initialPath);
for(BiomeData biome : typeList){
rVal.putBiome(biome.getId(), biome);
}
return rVal;
}
/**
* Gets the list of surface biomes
* @return The list of surface biomes
*/
public List<BiomeData> getSurfaceBiomes(){
return this.surfaceBiomes;
}
/**
* Gets the list of sky biomes
* @return The list of sky biomes
*/
public List<BiomeData> getSkyBiomes(){
return this.skyBiomes;
}
/**
* Gets the list of subterranean biomes
* @return The list of subterranean biomes
*/
public List<BiomeData> getSubterraneanBiomes(){
return this.subterraneanBiomes;
}
}

View File

@ -3,6 +3,8 @@ package electrosphere.server.terrain.models;
import java.util.HashMap;
import java.util.Map;
import electrosphere.engine.Globals;
import electrosphere.game.data.biome.BiomeData;
import electrosphere.util.annotation.Exclude;
/**
@ -456,5 +458,16 @@ public class TerrainModel {
public void setElevationArray(float[][] elevation){
this.elevation = elevation;
}
/**
* Gets the biome for a given world position
* @param worldX The world X
* @param worldY The world Y
* @param worldZ The world Z
* @return The biome
*/
public BiomeData getBiome(int worldX, int worldY, int worldZ){
return Globals.gameConfigCurrent.getBiomeMap().getTypes().iterator().next();
}
}

File diff suppressed because it is too large Load Diff