From 4b11511bd1674efec48aed6dabf2317e895f4fc0 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 28 Jun 2018 15:48:21 -0400 Subject: [PATCH] Minor world load time optimization --- core/src/io/anuke/mindustry/core/World.java | 23 ++-- core/src/io/anuke/mindustry/io/SaveIO.java | 6 +- .../world/mapgen/WorldGenerator.java | 128 +++++++++--------- 3 files changed, 84 insertions(+), 73 deletions(-) diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index 5a0c840f73..7b8c71ba77 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -174,25 +174,30 @@ public class World extends Module{ /**Loads up a procedural map. This does not call play(), but calls reset().*/ public void loadProceduralMap(){ Timers.mark(); - MapTileData data = WorldGenerator.generate(); - Map map = new Map("generated-map", new MapMeta(0, new ObjectMap<>(), data.width(), data.height(), null), true, () -> null); + Timers.mark(); logic.reset(); 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); - int width = map.meta.width, height = map.meta.height; - - Tile[][] tiles = createTiles(data.width(), data.height()); - 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(); - Log.info("Time to generate: {0}", Timers.elapsed()); + Log.info("Full time to generate: {0}", Timers.elapsed()); } public void setMap(Map map){ @@ -214,7 +219,7 @@ public class World extends Module{ 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(); } diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index e5b275b734..4b3add8272 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -127,12 +127,12 @@ public class SaveIO{ public static void load(FileHandle file){ try { - load(file.read()); + load(new InflaterInputStream(file.read())); }catch (RuntimeException e){ e.printStackTrace(); FileHandle backup = file.sibling(file.name() + "-backup." + file.extension()); if(backup.exists()){ - load(backup.read()); + load(new InflaterInputStream(backup.read())); } } } @@ -143,7 +143,7 @@ public class SaveIO{ DataInputStream stream; try{ - stream = new DataInputStream(new InflaterInputStream(is)); + stream = new DataInputStream(is); int version = stream.readInt(); SaveFileVersion ver = versions.get(version); diff --git a/core/src/io/anuke/mindustry/world/mapgen/WorldGenerator.java b/core/src/io/anuke/mindustry/world/mapgen/WorldGenerator.java index 273a6660be..536931c90c 100644 --- a/core/src/io/anuke/mindustry/world/mapgen/WorldGenerator.java +++ b/core/src/io/anuke/mindustry/world/mapgen/WorldGenerator.java @@ -11,14 +11,12 @@ import io.anuke.mindustry.content.blocks.OreBlocks; import io.anuke.mindustry.content.blocks.StorageBlocks; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.io.MapTileData; -import io.anuke.mindustry.io.MapTileData.DataPosition; import io.anuke.mindustry.io.MapTileData.TileDataMarker; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.noise.RidgedPerlin; import io.anuke.ucore.noise.Simplex; -import io.anuke.ucore.util.Bits; import io.anuke.ucore.util.Geometry; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.SeedRandom; @@ -31,42 +29,40 @@ public class WorldGenerator { static int oreIndex = 0; /**Should fill spawns with the correct spawnpoints.*/ - public static void generate(Tile[][] tiles, MapTileData data, boolean genOres, int seed){ - oreIndex = 0; - - Array 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(); - + public static void loadTileData(Tile[][] tiles, MapTileData data, boolean genOres, int seed){ data.position(0, 0); TileDataMarker marker = data.newDataMarker(); for(int y = 0; y < data.height(); y ++){ for(int x = 0; x < data.width(); x ++){ 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()){ - multiblocks.add(tile.packedPosition()); - } + for(int x = 0; x < tiles.length; x ++) { + for (int y = 0; y < tiles[0].length; y++) { + Tile tile = tiles[x][y]; + + Team team = tile.getTeam(); if(tile.block() == StorageBlocks.core && state.teams.has(team)){ state.teams.get(team).cores.add(tile); } - - tiles[x][y] = tile; - - //TODO ores, plants, extra decoration? + + if(tiles[x][y].block().isMultiblock()){ + multiblocks.add(tiles[x][y].packedPosition()); + } } } @@ -99,8 +95,8 @@ public class WorldGenerator { } //update cliffs, occlusion data - for(int x = 0; x < data.width(); x ++){ - for(int y = 0; y < data.height(); y ++) { + for(int x = 0; x < tiles.length; x ++){ + for(int y = 0; y < tiles[0].length; y ++) { Tile tile = tiles[x][y]; tile.updateOcclusion(); @@ -112,10 +108,19 @@ public class WorldGenerator { } } - if(genOres) { + oreIndex = 0; - for (int x = 0; x < data.width(); x++) { - for (int y = 0; y < data.height(); y++) { + if(genOres) { + Array 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]; @@ -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 sim2 = new Simplex(Mathf.random(99999)); Simplex sim3 = new Simplex(Mathf.random(99999)); SeedRandom random = new SeedRandom(Mathf.random(99999)); - MapTileData data = new MapTileData(400, 400); - TileDataMarker marker = data.newDataMarker(); + int width = tiles.length, height = tiles[0].length; ObjectMap decoration = new ObjectMap<>(); @@ -155,16 +159,17 @@ public class WorldGenerator { decoration.put(Blocks.snow, Blocks.icerock); decoration.put(Blocks.blackstone, Blocks.blackrock); - for (int x = 0; x < data.width(); x++) { - for (int y = 0; y < data.height(); y++) { - marker.floor = (byte)Blocks.stone.id; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + Block floor = Blocks.stone; + Block wall = Blocks.air; 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 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 dst = Vector2.dst(data.width()/2, data.height()/2, x, y); + double edgeDist = Math.max(width/2, height/2) - Math.max(Math.abs(x - width/2), Math.abs(y - height/2)); + double dst = Vector2.dst(width/2, height/2, x, y); double elevDip = 30; double border = 14; @@ -174,53 +179,53 @@ public class WorldGenerator { } if(temp < 0.35){ - marker.floor = (byte)Blocks.snow.id; + floor = Blocks.snow; }else if(temp < 0.45){ - marker.floor = (byte)Blocks.stone.id; + floor = Blocks.stone; }else if(temp < 0.65){ - marker.floor = (byte)Blocks.grass.id; + floor = Blocks.grass; }else if(temp < 0.8){ - marker.floor = (byte)Blocks.sand.id; + floor = Blocks.sand; }else if(temp < 0.9){ - marker.floor = (byte)Blocks.blackstone.id; + floor = Blocks.blackstone; elevation = 0f; }else{ - marker.floor = (byte)Blocks.lava.id; + floor = Blocks.lava; } if(dst < elevDip){ elevation -= (elevDip - dst)/elevDip * 3.0; }else if(r > 0.9){ - marker.floor = (byte)Blocks.water.id; + floor = Blocks.water; elevation = 0; if(r > 0.94){ - marker.floor = (byte)Blocks.deepwater.id; + floor = Blocks.deepwater; } } - marker.elevation = (byte)Math.max(elevation, 0); - - if(marker.wall == 0 && decoration.containsKey(Block.getByID(marker.floor)) && random.chance(0.03)){ - marker.wall = (byte)decoration.get(Block.getByID(marker.floor)).id; + if(wall == Blocks.air && decoration.containsKey(floor) && random.chance(0.03)){ + wall = decoration.get(floor); } - data.write(marker); - - marker.wall = 0; + Tile tile = new Tile(x, y, (byte)floor.id, (byte)wall.id); + tile.elevation = (byte)Math.max(elevation, 0); + tiles[x][y] = tile; } } - for (int x = 0; x < data.width(); x++) { - for (int y = 0; y < data.height(); y++) { - byte elevation = data.read(x, y, DataPosition.elevation); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + Tile tile = tiles[x][y]; + + byte elevation = tile.elevation; for(GridPoint2 point : Geometry.d4){ - if(!Mathf.inBounds(x + point.x, y + point.y, data.width(), data.height())) continue; - if(data.read(x + point.x, y + point.y, DataPosition.elevation) < elevation){ + if(!Mathf.inBounds(x + point.x, y + point.y, width, height)) continue; + if(tiles[x + point.x][y + point.y].elevation < elevation){ if(Mathf.chance(0.05)){ - data.write(x, y, DataPosition.elevation, (byte)-1); + tile.elevation = -1; } break; } @@ -228,9 +233,10 @@ public class WorldGenerator { } } - data.write(data.width()/2, data.height()/2, DataPosition.wall, (byte)StorageBlocks.core.id); - data.write(data.width()/2, data.height()/2, DataPosition.rotationTeam, Bits.packByte((byte)0, (byte)Team.blue.ordinal())); - return data; + tiles[width/2][height/2].setBlock(StorageBlocks.core); + tiles[width/2][height/2].setTeam(Team.blue); + + prepareTiles(tiles, seed, true); } static class OreEntry{