mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-08-02 07:59:15 +07:00
Minor world load time optimization
This commit is contained in:
@ -174,25 +174,30 @@ public class World extends Module{
|
|||||||
/**Loads up a procedural map. This does not call play(), but calls reset().*/
|
/**Loads up a procedural map. This does not call play(), but calls reset().*/
|
||||||
public void loadProceduralMap(){
|
public void loadProceduralMap(){
|
||||||
Timers.mark();
|
Timers.mark();
|
||||||
MapTileData data = WorldGenerator.generate();
|
Timers.mark();
|
||||||
Map map = new Map("generated-map", new MapMeta(0, new ObjectMap<>(), data.width(), data.height(), null), true, () -> null);
|
|
||||||
|
|
||||||
logic.reset();
|
logic.reset();
|
||||||
|
|
||||||
beginMapLoad();
|
beginMapLoad();
|
||||||
|
|
||||||
|
int width = 400, height = 400;
|
||||||
|
|
||||||
|
Tile[][] tiles = createTiles(width, height);
|
||||||
|
|
||||||
|
Map map = new Map("Generated Map", new MapMeta(0, new ObjectMap<>(), width, height, null), true, () -> null);
|
||||||
setMap(map);
|
setMap(map);
|
||||||
|
|
||||||
int width = map.meta.width, height = map.meta.height;
|
|
||||||
|
|
||||||
Tile[][] tiles = createTiles(data.width(), data.height());
|
|
||||||
|
|
||||||
EntityPhysics.resizeTree(0, 0, width * tilesize, height * tilesize);
|
EntityPhysics.resizeTree(0, 0, width * tilesize, height * tilesize);
|
||||||
|
|
||||||
WorldGenerator.generate(tiles, data, true, Mathf.random(9999999));
|
Timers.mark();
|
||||||
|
WorldGenerator.generateMap(tiles, Mathf.random(9999999));
|
||||||
|
Log.info("Time to generate base map: {0}", Timers.elapsed());
|
||||||
|
|
||||||
|
Log.info("Time to generate fully without additional events: {0}", Timers.elapsed());
|
||||||
|
|
||||||
endMapLoad();
|
endMapLoad();
|
||||||
|
|
||||||
Log.info("Time to generate: {0}", Timers.elapsed());
|
Log.info("Full time to generate: {0}", Timers.elapsed());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMap(Map map){
|
public void setMap(Map map){
|
||||||
@ -214,7 +219,7 @@ public class World extends Module{
|
|||||||
|
|
||||||
EntityPhysics.resizeTree(0, 0, width * tilesize, height * tilesize);
|
EntityPhysics.resizeTree(0, 0, width * tilesize, height * tilesize);
|
||||||
|
|
||||||
WorldGenerator.generate(tiles, MapIO.readTileData(map, true), map.meta.hasOreGen(), seed);
|
WorldGenerator.loadTileData(tiles, MapIO.readTileData(map, true), map.meta.hasOreGen(), seed);
|
||||||
|
|
||||||
endMapLoad();
|
endMapLoad();
|
||||||
}
|
}
|
||||||
|
@ -127,12 +127,12 @@ public class SaveIO{
|
|||||||
|
|
||||||
public static void load(FileHandle file){
|
public static void load(FileHandle file){
|
||||||
try {
|
try {
|
||||||
load(file.read());
|
load(new InflaterInputStream(file.read()));
|
||||||
}catch (RuntimeException e){
|
}catch (RuntimeException e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
FileHandle backup = file.sibling(file.name() + "-backup." + file.extension());
|
FileHandle backup = file.sibling(file.name() + "-backup." + file.extension());
|
||||||
if(backup.exists()){
|
if(backup.exists()){
|
||||||
load(backup.read());
|
load(new InflaterInputStream(backup.read()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ public class SaveIO{
|
|||||||
DataInputStream stream;
|
DataInputStream stream;
|
||||||
|
|
||||||
try{
|
try{
|
||||||
stream = new DataInputStream(new InflaterInputStream(is));
|
stream = new DataInputStream(is);
|
||||||
int version = stream.readInt();
|
int version = stream.readInt();
|
||||||
SaveFileVersion ver = versions.get(version);
|
SaveFileVersion ver = versions.get(version);
|
||||||
|
|
||||||
|
@ -11,14 +11,12 @@ import io.anuke.mindustry.content.blocks.OreBlocks;
|
|||||||
import io.anuke.mindustry.content.blocks.StorageBlocks;
|
import io.anuke.mindustry.content.blocks.StorageBlocks;
|
||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.io.MapTileData;
|
import io.anuke.mindustry.io.MapTileData;
|
||||||
import io.anuke.mindustry.io.MapTileData.DataPosition;
|
|
||||||
import io.anuke.mindustry.io.MapTileData.TileDataMarker;
|
import io.anuke.mindustry.io.MapTileData.TileDataMarker;
|
||||||
import io.anuke.mindustry.type.Item;
|
import io.anuke.mindustry.type.Item;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.ucore.noise.RidgedPerlin;
|
import io.anuke.ucore.noise.RidgedPerlin;
|
||||||
import io.anuke.ucore.noise.Simplex;
|
import io.anuke.ucore.noise.Simplex;
|
||||||
import io.anuke.ucore.util.Bits;
|
|
||||||
import io.anuke.ucore.util.Geometry;
|
import io.anuke.ucore.util.Geometry;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.SeedRandom;
|
import io.anuke.ucore.util.SeedRandom;
|
||||||
@ -31,42 +29,40 @@ public class WorldGenerator {
|
|||||||
static int oreIndex = 0;
|
static int oreIndex = 0;
|
||||||
|
|
||||||
/**Should fill spawns with the correct spawnpoints.*/
|
/**Should fill spawns with the correct spawnpoints.*/
|
||||||
public static void generate(Tile[][] tiles, MapTileData data, boolean genOres, int seed){
|
public static void loadTileData(Tile[][] tiles, MapTileData data, boolean genOres, int seed){
|
||||||
oreIndex = 0;
|
|
||||||
|
|
||||||
Array<OreEntry> ores = Array.with(
|
|
||||||
new OreEntry(Items.tungsten, 0.3f, seed),
|
|
||||||
new OreEntry(Items.coal, 0.284f, seed),
|
|
||||||
new OreEntry(Items.lead, 0.28f, seed),
|
|
||||||
new OreEntry(Items.titanium, 0.27f, seed),
|
|
||||||
new OreEntry(Items.thorium, 0.26f, seed)
|
|
||||||
);
|
|
||||||
|
|
||||||
IntArray multiblocks = new IntArray();
|
|
||||||
|
|
||||||
data.position(0, 0);
|
data.position(0, 0);
|
||||||
TileDataMarker marker = data.newDataMarker();
|
TileDataMarker marker = data.newDataMarker();
|
||||||
|
|
||||||
for(int y = 0; y < data.height(); y ++){
|
for(int y = 0; y < data.height(); y ++){
|
||||||
for(int x = 0; x < data.width(); x ++){
|
for(int x = 0; x < data.width(); x ++){
|
||||||
data.read(marker);
|
data.read(marker);
|
||||||
|
|
||||||
|
tiles[x][y] = new Tile(x, y, marker.floor, marker.wall == Blocks.blockpart.id ? 0 : marker.wall, marker.rotation, marker.team, marker.elevation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Tile tile = new Tile(x, y, marker.floor, marker.wall == Blocks.blockpart.id ? 0 : marker.wall, marker.rotation, marker.team, marker.elevation);
|
prepareTiles(tiles, seed, genOres);
|
||||||
|
}
|
||||||
|
|
||||||
Team team = Team.all[marker.team];
|
public static void prepareTiles(Tile[][] tiles, int seed, boolean genOres){
|
||||||
|
|
||||||
|
//find multiblocks
|
||||||
|
IntArray multiblocks = new IntArray();
|
||||||
|
|
||||||
if(tile.block().isMultiblock()){
|
for(int x = 0; x < tiles.length; x ++) {
|
||||||
multiblocks.add(tile.packedPosition());
|
for (int y = 0; y < tiles[0].length; y++) {
|
||||||
}
|
Tile tile = tiles[x][y];
|
||||||
|
|
||||||
|
Team team = tile.getTeam();
|
||||||
|
|
||||||
if(tile.block() == StorageBlocks.core &&
|
if(tile.block() == StorageBlocks.core &&
|
||||||
state.teams.has(team)){
|
state.teams.has(team)){
|
||||||
state.teams.get(team).cores.add(tile);
|
state.teams.get(team).cores.add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
tiles[x][y] = tile;
|
if(tiles[x][y].block().isMultiblock()){
|
||||||
|
multiblocks.add(tiles[x][y].packedPosition());
|
||||||
//TODO ores, plants, extra decoration?
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,8 +95,8 @@ public class WorldGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//update cliffs, occlusion data
|
//update cliffs, occlusion data
|
||||||
for(int x = 0; x < data.width(); x ++){
|
for(int x = 0; x < tiles.length; x ++){
|
||||||
for(int y = 0; y < data.height(); y ++) {
|
for(int y = 0; y < tiles[0].length; y ++) {
|
||||||
Tile tile = tiles[x][y];
|
Tile tile = tiles[x][y];
|
||||||
|
|
||||||
tile.updateOcclusion();
|
tile.updateOcclusion();
|
||||||
@ -112,10 +108,19 @@ public class WorldGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(genOres) {
|
oreIndex = 0;
|
||||||
|
|
||||||
for (int x = 0; x < data.width(); x++) {
|
if(genOres) {
|
||||||
for (int y = 0; y < data.height(); y++) {
|
Array<OreEntry> ores = Array.with(
|
||||||
|
new OreEntry(Items.tungsten, 0.3f, seed),
|
||||||
|
new OreEntry(Items.coal, 0.284f, seed),
|
||||||
|
new OreEntry(Items.lead, 0.28f, seed),
|
||||||
|
new OreEntry(Items.titanium, 0.27f, seed),
|
||||||
|
new OreEntry(Items.thorium, 0.26f, seed)
|
||||||
|
);
|
||||||
|
|
||||||
|
for (int x = 0; x < tiles.length; x++) {
|
||||||
|
for (int y = 0; y < tiles[0].length; y++) {
|
||||||
|
|
||||||
Tile tile = tiles[x][y];
|
Tile tile = tiles[x][y];
|
||||||
|
|
||||||
@ -137,15 +142,14 @@ public class WorldGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MapTileData generate(){
|
public static void generateMap(Tile[][] tiles, int seed){
|
||||||
Simplex sim = new Simplex(Mathf.random(99999));
|
Simplex sim = new Simplex(Mathf.random(99999));
|
||||||
Simplex sim2 = new Simplex(Mathf.random(99999));
|
Simplex sim2 = new Simplex(Mathf.random(99999));
|
||||||
Simplex sim3 = new Simplex(Mathf.random(99999));
|
Simplex sim3 = new Simplex(Mathf.random(99999));
|
||||||
|
|
||||||
SeedRandom random = new SeedRandom(Mathf.random(99999));
|
SeedRandom random = new SeedRandom(Mathf.random(99999));
|
||||||
|
|
||||||
MapTileData data = new MapTileData(400, 400);
|
int width = tiles.length, height = tiles[0].length;
|
||||||
TileDataMarker marker = data.newDataMarker();
|
|
||||||
|
|
||||||
ObjectMap<Block, Block> decoration = new ObjectMap<>();
|
ObjectMap<Block, Block> decoration = new ObjectMap<>();
|
||||||
|
|
||||||
@ -155,16 +159,17 @@ public class WorldGenerator {
|
|||||||
decoration.put(Blocks.snow, Blocks.icerock);
|
decoration.put(Blocks.snow, Blocks.icerock);
|
||||||
decoration.put(Blocks.blackstone, Blocks.blackrock);
|
decoration.put(Blocks.blackstone, Blocks.blackrock);
|
||||||
|
|
||||||
for (int x = 0; x < data.width(); x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
for (int y = 0; y < data.height(); y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
marker.floor = (byte)Blocks.stone.id;
|
Block floor = Blocks.stone;
|
||||||
|
Block wall = Blocks.air;
|
||||||
|
|
||||||
double elevation = sim.octaveNoise2D(3, 0.5, 1f/100, x, y) * 4.1 - 1;
|
double elevation = sim.octaveNoise2D(3, 0.5, 1f/100, x, y) * 4.1 - 1;
|
||||||
double temp = sim3.octaveNoise2D(7, 0.53, 1f/320f, x, y);
|
double temp = sim3.octaveNoise2D(7, 0.53, 1f/320f, x, y);
|
||||||
|
|
||||||
double r = sim2.octaveNoise2D(1, 0.6, 1f/70, x, y);
|
double r = sim2.octaveNoise2D(1, 0.6, 1f/70, x, y);
|
||||||
double edgeDist = Math.max(data.width()/2, data.height()/2) - Math.max(Math.abs(x - data.width()/2), Math.abs(y - data.height()/2));
|
double edgeDist = Math.max(width/2, height/2) - Math.max(Math.abs(x - width/2), Math.abs(y - height/2));
|
||||||
double dst = Vector2.dst(data.width()/2, data.height()/2, x, y);
|
double dst = Vector2.dst(width/2, height/2, x, y);
|
||||||
double elevDip = 30;
|
double elevDip = 30;
|
||||||
|
|
||||||
double border = 14;
|
double border = 14;
|
||||||
@ -174,53 +179,53 @@ public class WorldGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(temp < 0.35){
|
if(temp < 0.35){
|
||||||
marker.floor = (byte)Blocks.snow.id;
|
floor = Blocks.snow;
|
||||||
}else if(temp < 0.45){
|
}else if(temp < 0.45){
|
||||||
marker.floor = (byte)Blocks.stone.id;
|
floor = Blocks.stone;
|
||||||
}else if(temp < 0.65){
|
}else if(temp < 0.65){
|
||||||
marker.floor = (byte)Blocks.grass.id;
|
floor = Blocks.grass;
|
||||||
}else if(temp < 0.8){
|
}else if(temp < 0.8){
|
||||||
marker.floor = (byte)Blocks.sand.id;
|
floor = Blocks.sand;
|
||||||
}else if(temp < 0.9){
|
}else if(temp < 0.9){
|
||||||
marker.floor = (byte)Blocks.blackstone.id;
|
floor = Blocks.blackstone;
|
||||||
elevation = 0f;
|
elevation = 0f;
|
||||||
}else{
|
}else{
|
||||||
marker.floor = (byte)Blocks.lava.id;
|
floor = Blocks.lava;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dst < elevDip){
|
if(dst < elevDip){
|
||||||
elevation -= (elevDip - dst)/elevDip * 3.0;
|
elevation -= (elevDip - dst)/elevDip * 3.0;
|
||||||
}else if(r > 0.9){
|
}else if(r > 0.9){
|
||||||
marker.floor = (byte)Blocks.water.id;
|
floor = Blocks.water;
|
||||||
elevation = 0;
|
elevation = 0;
|
||||||
|
|
||||||
if(r > 0.94){
|
if(r > 0.94){
|
||||||
marker.floor = (byte)Blocks.deepwater.id;
|
floor = Blocks.deepwater;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
marker.elevation = (byte)Math.max(elevation, 0);
|
if(wall == Blocks.air && decoration.containsKey(floor) && random.chance(0.03)){
|
||||||
|
wall = decoration.get(floor);
|
||||||
if(marker.wall == 0 && decoration.containsKey(Block.getByID(marker.floor)) && random.chance(0.03)){
|
|
||||||
marker.wall = (byte)decoration.get(Block.getByID(marker.floor)).id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data.write(marker);
|
Tile tile = new Tile(x, y, (byte)floor.id, (byte)wall.id);
|
||||||
|
tile.elevation = (byte)Math.max(elevation, 0);
|
||||||
marker.wall = 0;
|
tiles[x][y] = tile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x = 0; x < data.width(); x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
for (int y = 0; y < data.height(); y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
byte elevation = data.read(x, y, DataPosition.elevation);
|
Tile tile = tiles[x][y];
|
||||||
|
|
||||||
|
byte elevation = tile.elevation;
|
||||||
|
|
||||||
for(GridPoint2 point : Geometry.d4){
|
for(GridPoint2 point : Geometry.d4){
|
||||||
if(!Mathf.inBounds(x + point.x, y + point.y, data.width(), data.height())) continue;
|
if(!Mathf.inBounds(x + point.x, y + point.y, width, height)) continue;
|
||||||
if(data.read(x + point.x, y + point.y, DataPosition.elevation) < elevation){
|
if(tiles[x + point.x][y + point.y].elevation < elevation){
|
||||||
|
|
||||||
if(Mathf.chance(0.05)){
|
if(Mathf.chance(0.05)){
|
||||||
data.write(x, y, DataPosition.elevation, (byte)-1);
|
tile.elevation = -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -228,9 +233,10 @@ public class WorldGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.write(data.width()/2, data.height()/2, DataPosition.wall, (byte)StorageBlocks.core.id);
|
tiles[width/2][height/2].setBlock(StorageBlocks.core);
|
||||||
data.write(data.width()/2, data.height()/2, DataPosition.rotationTeam, Bits.packByte((byte)0, (byte)Team.blue.ordinal()));
|
tiles[width/2][height/2].setTeam(Team.blue);
|
||||||
return data;
|
|
||||||
|
prepareTiles(tiles, seed, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class OreEntry{
|
static class OreEntry{
|
||||||
|
Reference in New Issue
Block a user