seed saved per world and ui input for seed
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-03-30 22:07:24 -04:00
parent 32641d0035
commit 28735cea4e
23 changed files with 159 additions and 10 deletions

View File

@ -11,6 +11,7 @@ import electrosphere.entity.scene.SceneGenerator;
import electrosphere.renderer.ui.elements.Button; import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.Div; import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.FormElement; import electrosphere.renderer.ui.elements.FormElement;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.TextInput; import electrosphere.renderer.ui.elements.TextInput;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment; import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification; import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
@ -89,23 +90,37 @@ public class MenuWorldSelect {
public static Element createWorldCreationMenu(){ public static Element createWorldCreationMenu(){
FormElement rVal = new FormElement(); FormElement rVal = new FormElement();
//text entry (address) //text entry (world name)
Div worldNameInputContainer = Div.createRow(); Div worldNameInputContainer = Div.createRow();
worldNameInputContainer.setMarginBottom(20); worldNameInputContainer.setMarginBottom(20);
Label worldNameLabel = Label.createLabel("Input Name: ");
worldNameInputContainer.addChild(worldNameLabel);
TextInput worldNameInput = TextInput.createTextInput(); TextInput worldNameInput = TextInput.createTextInput();
worldNameInput.setMinWidth(100); worldNameInput.setMinWidth(100);
worldNameInput.setMaxWidthPercent(50); worldNameInput.setMaxWidthPercent(50);
worldNameInput.setText("World name"); worldNameInput.setText("World name");
worldNameInputContainer.addChild(worldNameInput); worldNameInputContainer.addChild(worldNameInput);
//text entry (world seed)
Div worldSeedInputContainer = Div.createRow();
worldSeedInputContainer.setMarginBottom(20);
Label worldSeedLabel = Label.createLabel("Input Seed: ");
worldSeedInputContainer.addChild(worldSeedLabel);
TextInput worldSeedInput = TextInput.createTextInput();
worldSeedInput.setMinWidth(100);
worldSeedInput.setMaxWidthPercent(50);
worldSeedInput.setText(System.currentTimeMillis() + "");
worldSeedInputContainer.addChild(worldSeedInput);
//button (create) //button (create)
Div createButtonContainer = Div.createCol(); Div createButtonContainer = Div.createCol();
createButtonContainer.setMarginTop(20); createButtonContainer.setMarginTop(20);
createButtonContainer.addChild(Button.createButton("Create", () -> { createButtonContainer.addChild(Button.createButton("Create", () -> {
String saveName = worldNameInput.getText(); String saveName = worldNameInput.getText();
String seed = worldSeedInput.getText();
//create save dir //create save dir
SaveUtils.createOrOverwriteSave(saveName, SceneGenerator.createProceduralSceneFile(saveName)); SaveUtils.createOrOverwriteSave(saveName, SceneGenerator.createProceduralSceneFile(saveName, seed));
WindowUtils.replaceMainMenuContents(MenuWorldSelect.createWorldSelectMenu()); WindowUtils.replaceMainMenuContents(MenuWorldSelect.createWorldSelectMenu());
})); }));
@ -113,6 +128,7 @@ public class MenuWorldSelect {
//layout content //layout content
Div mainLayout = Div.createCol( Div mainLayout = Div.createCol(
worldNameInputContainer, worldNameInputContainer,
worldSeedInputContainer,
createButtonContainer createButtonContainer
); );
mainLayout.setMarginTop(300); mainLayout.setMarginTop(300);

View File

@ -33,7 +33,7 @@ public class DebugSPWorldLoading {
//the juicy server GENERATION part //the juicy server GENERATION part
// //
//init save structure //init save structure
SaveUtils.createOrOverwriteSave(saveName, SceneGenerator.createProceduralSceneFile(saveName)); SaveUtils.createOrOverwriteSave(saveName, SceneGenerator.createProceduralSceneFile(saveName, ""));
} }
//load just-created save //load just-created save
SaveUtils.loadSave(saveName, false); SaveUtils.loadSave(saveName, false);

View File

@ -37,7 +37,7 @@ public class ServerLoading {
//the juicy server GENERATION part //the juicy server GENERATION part
// //
//init save structure //init save structure
SaveUtils.createOrOverwriteSave(saveName, SceneGenerator.createProceduralSceneFile(saveName)); SaveUtils.createOrOverwriteSave(saveName, SceneGenerator.createProceduralSceneFile(saveName, ""));
} }
//load just-created save //load just-created save
SaveUtils.loadSave(saveName, false); SaveUtils.loadSave(saveName, false);

View File

@ -38,6 +38,11 @@ public class SceneFile {
*/ */
boolean loadAllCells; boolean loadAllCells;
/**
* The seed for the random number generator
*/
long seed = 0;
/** /**
* Private constructor * Private constructor
@ -117,4 +122,12 @@ public class SceneFile {
return loadAllCells; return loadAllCells;
} }
/**
* Gets the seed of the scene file
* @return The seed
*/
public long getSeed(){
return seed;
}
} }

View File

@ -1,5 +1,7 @@
package electrosphere.entity.scene; package electrosphere.entity.scene;
import java.util.Objects;
import electrosphere.server.datacell.gridded.GriddedDataCellManager; import electrosphere.server.datacell.gridded.GriddedDataCellManager;
import electrosphere.server.terrain.generation.TestGenerationChunkGenerator; import electrosphere.server.terrain.generation.TestGenerationChunkGenerator;
@ -13,7 +15,7 @@ public class SceneGenerator {
* @param gridSize The size of the terrain grid of the scene * @param gridSize The size of the terrain grid of the scene
* @return The scene file * @return The scene file
*/ */
public static SceneFile createProceduralSceneFile(String saveName){ public static SceneFile createProceduralSceneFile(String saveName, String seed){
//base file stuff //base file stuff
SceneFile file = SceneFile.createSceneFile(); SceneFile file = SceneFile.createSceneFile();
//realm descriptor stuff //realm descriptor stuff
@ -21,7 +23,7 @@ public class SceneGenerator {
file.realmDescriptor.griddedRealmSize = GriddedDataCellManager.MAX_GRID_SIZE; file.realmDescriptor.griddedRealmSize = GriddedDataCellManager.MAX_GRID_SIZE;
file.createSaveInstance = true; //won't have a predefined scene to load, so must create one in the save file.createSaveInstance = true; //won't have a predefined scene to load, so must create one in the save
file.loadAllCells = false; // do not load all cells on init file.loadAllCells = false; // do not load all cells on init
file.seed = Objects.hash(seed);
return file; return file;
} }

View File

@ -115,7 +115,7 @@ public class SaveUtils {
ServerWorldData serverWorldData = ServerWorldData.createGriddedRealmWorldData(ServerWorldData.PROCEDURAL_WORLD_SIZE); ServerWorldData serverWorldData = ServerWorldData.createGriddedRealmWorldData(ServerWorldData.PROCEDURAL_WORLD_SIZE);
FileUtils.serializeObjectToSavePath(saveName, "./world.json", serverWorldData); FileUtils.serializeObjectToSavePath(saveName, "./world.json", serverWorldData);
//terrain manager //terrain manager
ServerTerrainManager serverTerrainManager = new ServerTerrainManager(serverWorldData, 0, new TestGenerationChunkGenerator(serverWorldData, false)); ServerTerrainManager serverTerrainManager = new ServerTerrainManager(serverWorldData, sceneFile.getSeed(), new TestGenerationChunkGenerator(serverWorldData, false));
serverTerrainManager.generate(); serverTerrainManager.generate();
serverTerrainManager.save(saveName); serverTerrainManager.save(saveName);
//fluid manager //fluid manager

View File

@ -395,6 +395,12 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
@Override @Override
public void setModel(TerrainModel model) { public void setModel(TerrainModel model) {
this.terrainModel = model; this.terrainModel = model;
for(HeightmapGenerator generator : this.tagHeightmapMap.values()){
generator.setSeed(model.getSeed());
}
for(VoxelGenerator generator : this.tagVoxelMap.values()){
generator.setSeed(model.getSeed());
}
} }
} }

View File

@ -169,7 +169,7 @@ public class TerrainGenerator {
// MOUNTAIN_THRESHOLD * verticalInterpolationRatio, // MOUNTAIN_THRESHOLD * verticalInterpolationRatio,
// dynamicInterpRatio // dynamicInterpRatio
// ); // );
rVal = TerrainModel.create(); rVal = TerrainModel.create(0);
//create internal renderer //create internal renderer

View File

@ -2,6 +2,11 @@ package electrosphere.server.terrain.generation.heightmap;
public class EmptySkyGen implements HeightmapGenerator { public class EmptySkyGen implements HeightmapGenerator {
/**
* The seed of the generator
*/
long seed = 0;
@Override @Override
public float getHeight(long SEED, double x, double y) { public float getHeight(long SEED, double x, double y) {
return 0; return 0;
@ -11,5 +16,10 @@ public class EmptySkyGen implements HeightmapGenerator {
public String getTag() { public String getTag() {
return "empty"; return "empty";
} }
@Override
public void setSeed(long seed){
this.seed = seed;
}
} }

View File

@ -20,4 +20,10 @@ public interface HeightmapGenerator {
*/ */
public String getTag(); public String getTag();
/**
* Sets the seed of the generator
* @param seed The seed
*/
public void setSeed(long seed);
} }

View File

@ -13,6 +13,11 @@ public class HeightmapNoiseGen implements HeightmapGenerator {
*/ */
String tag; String tag;
/**
* The seed of the generator
*/
long seed = 0;
/** /**
* The sampler to pull from when allocating voxels * The sampler to pull from when allocating voxels
*/ */
@ -36,5 +41,10 @@ public class HeightmapNoiseGen implements HeightmapGenerator {
public String getTag() { public String getTag() {
return tag; return tag;
} }
@Override
public void setSeed(long seed){
this.seed = seed;
}
} }

View File

@ -40,6 +40,11 @@ public class HillsGen implements HeightmapGenerator {
//param for controlling how pointer the initial layers are //param for controlling how pointer the initial layers are
public static float GRAD_INFLUENCE_DROPOFF = 0.35f; public static float GRAD_INFLUENCE_DROPOFF = 0.35f;
/**
* The seed of the generator
*/
long seed = 0;
/** /**
* Gets the height at a given position for this generation approach * Gets the height at a given position for this generation approach
@ -95,5 +100,10 @@ public class HillsGen implements HeightmapGenerator {
public String getTag() { public String getTag() {
return "hills"; return "hills";
} }
@Override
public void setSeed(long seed){
this.seed = seed;
}
} }

View File

@ -46,6 +46,10 @@ public class MountainGen implements HeightmapGenerator {
{0.3, 0.2}, {0.3, 0.2},
}; };
/**
* The seed of the generator
*/
long seed = 0;
/** /**
* Gets the height at a given position for this generation approach * Gets the height at a given position for this generation approach
@ -94,4 +98,9 @@ public class MountainGen implements HeightmapGenerator {
public String getTag() { public String getTag() {
return "mountains"; return "mountains";
} }
@Override
public void setSeed(long seed){
this.seed = seed;
}
} }

View File

@ -17,6 +17,11 @@ public class PlainsGen implements HeightmapGenerator {
*/ */
static final float GEN_SCALE = 0.2f; static final float GEN_SCALE = 0.2f;
/**
* The seed of the generator
*/
long seed = 0;
//the different scales of noise to sample from //the different scales of noise to sample from
static final double[][] NOISE_SCALES = new double[][]{ static final double[][] NOISE_SCALES = new double[][]{
{0.01, 3.0}, {0.01, 3.0},
@ -61,5 +66,10 @@ public class PlainsGen implements HeightmapGenerator {
public String getTag() { public String getTag() {
return "plains"; return "plains";
} }
@Override
public void setSeed(long seed){
this.seed = seed;
}
} }

View File

@ -7,6 +7,11 @@ import electrosphere.util.noise.OpenSimplex2S;
*/ */
public class SeaFloorGen implements HeightmapGenerator { public class SeaFloorGen implements HeightmapGenerator {
/**
* The seed of the generator
*/
long seed = 0;
/** /**
* The scale of the noise * The scale of the noise
*/ */
@ -22,5 +27,10 @@ public class SeaFloorGen implements HeightmapGenerator {
public String getTag() { public String getTag() {
return "seafloor"; return "seafloor";
} }
@Override
public void setSeed(long seed){
this.seed = seed;
}
} }

View File

@ -17,6 +17,7 @@ public class DefaultMacroGenerator implements MacroGenerator {
int DIM = model.getDiscreteArrayDimension(); int DIM = model.getDiscreteArrayDimension();
float[][] elevation = model.getElevation(); float[][] elevation = model.getElevation();
short[][] biome = model.getBiome(); short[][] biome = model.getBiome();
long seed = model.getSeed();
for(int x = 0; x < DIM; x++){ for(int x = 0; x < DIM; x++){
for(int y = 0; y < DIM; y++){ for(int y = 0; y < DIM; y++){

View File

@ -57,11 +57,21 @@ public class AnimeMountainsGen implements VoxelGenerator {
*/ */
public static final double VERTICAL_ROTATION_OFFSET_VARIANCE = 0.2; public static final double VERTICAL_ROTATION_OFFSET_VARIANCE = 0.2;
/**
* The seed for the generator
*/
long seed = 0;
@Override @Override
public String getTag() { public String getTag() {
return "animeMountain"; return "animeMountain";
} }
@Override
public void setSeed(long seed){
this.seed = seed;
}
@Override @Override
public void getVoxel( public void getVoxel(
GeneratedVoxel voxel, GeneratedVoxel voxel,

View File

@ -15,12 +15,22 @@ public class HillsVoxelGen implements VoxelGenerator {
*/ */
public static final int SURFACE_VOXEL_WIDTH = 2; public static final int SURFACE_VOXEL_WIDTH = 2;
/**
* The seed of the generator
*/
long seed;
@Override @Override
public String getTag(){ public String getTag(){
return "hills"; return "hills";
} }
@Override
public void setSeed(long seed){
this.seed = seed;
}
@Override @Override
public void getVoxel( public void getVoxel(
GeneratedVoxel voxel, GeneratedVoxel voxel,

View File

@ -22,12 +22,21 @@ public class MountainVoxelGen implements VoxelGenerator {
*/ */
public static final float GRADIENT_DIRT_CUTOFF = 0.1f; public static final float GRADIENT_DIRT_CUTOFF = 0.1f;
/**
* The seed of the generator
*/
long seed;
@Override @Override
public String getTag(){ public String getTag(){
return "mountains"; return "mountains";
} }
@Override
public void setSeed(long seed){
this.seed = seed;
}
@Override @Override
public void getVoxel( public void getVoxel(
GeneratedVoxel voxel, GeneratedVoxel voxel,

View File

@ -31,6 +31,11 @@ public class NoiseVoxelGen implements VoxelGenerator {
*/ */
NoiseSampler sampler; NoiseSampler sampler;
/**
* The seed of the generator
*/
long seed;
/** /**
* Constructor * Constructor
* @param samplerDefinitionFile The file to model this generator off of * @param samplerDefinitionFile The file to model this generator off of
@ -45,6 +50,11 @@ public class NoiseVoxelGen implements VoxelGenerator {
return tag; return tag;
} }
@Override
public void setSeed(long seed){
this.seed = seed;
}
@Override @Override
public void getVoxel( public void getVoxel(
GeneratedVoxel voxel, GeneratedVoxel voxel,

View File

@ -17,6 +17,12 @@ public interface VoxelGenerator {
*/ */
public String getTag(); public String getTag();
/**
* Sets the seed of the generator
* @param seed The seed
*/
public void setSeed(long seed);
/** /**
* Gets the value for a chunk * Gets the value for a chunk

View File

@ -100,7 +100,7 @@ public class ServerTerrainManager {
* Generates a terrain model for the manager * Generates a terrain model for the manager
*/ */
public void generate(){ public void generate(){
this.model = TerrainModel.create(); this.model = TerrainModel.create(this.seed);
DefaultMacroGenerator generator = new DefaultMacroGenerator(); DefaultMacroGenerator generator = new DefaultMacroGenerator();
generator.generate(this.model); generator.generate(this.model);
this.chunkGenerator.setModel(this.model); this.chunkGenerator.setModel(this.model);

View File

@ -83,10 +83,11 @@ public class TerrainModel {
* Creates the default terrain model * Creates the default terrain model
* @return The default terrain model * @return The default terrain model
*/ */
public static TerrainModel create(){ public static TerrainModel create(long seed){
TerrainModel rVal = new TerrainModel(); TerrainModel rVal = new TerrainModel();
rVal.elevation = new float[rVal.discreteArrayDimension][rVal.discreteArrayDimension]; rVal.elevation = new float[rVal.discreteArrayDimension][rVal.discreteArrayDimension];
rVal.biome = new short[rVal.discreteArrayDimension][rVal.discreteArrayDimension]; rVal.biome = new short[rVal.discreteArrayDimension][rVal.discreteArrayDimension];
rVal.seed = seed;
return rVal; return rVal;
} }