Skip to content

Commit 3d81769

Browse files
committed
fix: use world access to map biome name to id rather than using Minestom registry
1 parent 089e6a4 commit 3d81769

File tree

4 files changed

+73
-19
lines changed

4 files changed

+73
-19
lines changed

src/main/java/net/hollowcube/polar/PolarLoader.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import net.minestom.server.instance.block.BlockManager;
1313
import net.minestom.server.instance.light.LightCompute;
1414
import net.minestom.server.network.NetworkBuffer;
15-
import net.minestom.server.registry.DynamicRegistry;
1615
import net.minestom.server.world.DimensionType;
1716
import net.minestom.server.world.biome.Biome;
1817
import org.jetbrains.annotations.ApiStatus;
@@ -39,9 +38,7 @@
3938
public class PolarLoader implements IChunkLoader {
4039
static final Logger logger = LoggerFactory.getLogger(PolarLoader.class);
4140
private static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
42-
static final DynamicRegistry<Biome> BIOME_REGISTRY = MinecraftServer.getBiomeRegistry();
4341
private static final ExceptionManager EXCEPTION_HANDLER = MinecraftServer.getExceptionManager();
44-
static final int PLAINS_BIOME_ID = BIOME_REGISTRY.getId(Biome.PLAINS);
4542

4643
/**
4744
* Loads a polar world into an instance in a streaming manner.
@@ -86,6 +83,8 @@ public class PolarLoader implements IChunkLoader {
8683
private boolean parallel = false;
8784
private boolean loadLighting = true;
8885

86+
private int plainsBiomeId = 0; // Always 0 in minestom
87+
8988
public PolarLoader(@NotNull Path path) throws IOException {
9089
this(path, Files.exists(path) ? PolarReader.read(Files.readAllBytes(path)) : new PolarWorld());
9190
}
@@ -114,6 +113,12 @@ public PolarLoader(@NotNull PolarWorld world) {
114113
@Contract("_ -> this")
115114
public @NotNull PolarLoader setWorldAccess(@NotNull PolarWorldAccess worldAccess) {
116115
this.worldAccess = worldAccess;
116+
117+
this.plainsBiomeId = this.worldAccess.getBiomeId(Biome.PLAINS.name());
118+
if (this.plainsBiomeId == -1) {
119+
throw new IllegalStateException("Plains biome not found");
120+
}
121+
117122
return this;
118123
}
119124

@@ -234,10 +239,10 @@ private void loadSection(@NotNull PolarSection sectionData, @NotNull Section sec
234239
var biomePalette = new int[rawBiomePalette.length];
235240
for (int i = 0; i < rawBiomePalette.length; i++) {
236241
biomePalette[i] = biomeReadCache.computeIfAbsent(rawBiomePalette[i], name -> {
237-
var biomeId = BIOME_REGISTRY.getId(worldAccess.getBiome(name));
242+
var biomeId = this.worldAccess.getBiomeId(name);
238243
if (biomeId == -1) {
239244
logger.error("Failed to find biome: {}", name);
240-
biomeId = PLAINS_BIOME_ID;
245+
biomeId = plainsBiomeId;
241246
}
242247
return biomeId;
243248
});
@@ -255,7 +260,7 @@ private void loadSection(@NotNull PolarSection sectionData, @NotNull Section sec
255260
if (paletteIndex >= biomePalette.length) {
256261
logger.error("Invalid biome palette index. This is probably a corrupted world, " +
257262
"but it has been loaded with plains instead. No data has been written.");
258-
section.biomePalette().set(x, y, z, PLAINS_BIOME_ID);
263+
section.biomePalette().set(x, y, z, plainsBiomeId);
259264
}
260265

261266
section.biomePalette().set(x, y, z, biomePalette[paletteIndex]);

src/main/java/net/hollowcube/polar/PolarWorldAccess.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,18 @@ default void saveHeightmaps(@NotNull Chunk chunk, int[][] heightmaps) {
7474
}
7575

7676
/**
77-
* Called when a chunk is being loaded by a {@link PolarLoader} to convert biome ids back to instances.
77+
* Called when a chunk is being loaded by a {@link PolarLoader} to convert biome namespaces back to id.
7878
* <br/><br/>
7979
* It is valid to change the behavior as long as a biome is returned in all cases (i.e. have a default).
8080
* <br/><br/>
8181
* Biomes are cached by the loader per loader instance, so there will only be a single call per loader, even over many chunks.
8282
*
8383
* @param name The namespace ID of the biome, eg minecraft:plains
84-
* @return The biome instance
84+
* @return The biome id
8585
*/
86-
default @NotNull DynamicRegistry.Key<Biome> getBiome(@NotNull String name) {
86+
default int getBiomeId(@NotNull String name) {
8787
var biomeRegistry = MinecraftServer.getBiomeRegistry();
88-
var key = DynamicRegistry.Key.<Biome>of(name);
89-
var biome = biomeRegistry.get(key);
90-
if (biome == null) {
91-
PolarLoader.logger.error("Failed to find biome: {}", name);
92-
return Biome.PLAINS;
93-
}
94-
return key;
88+
return biomeRegistry.getId(DynamicRegistry.Key.of(name));
9589
}
9690

9791
default @NotNull String getBiomeName(int id) {

src/main/java/net/hollowcube/polar/StreamingPolarLoader.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import net.minestom.server.instance.Section;
1212
import net.minestom.server.network.NetworkBuffer;
1313
import net.minestom.server.utils.validate.Check;
14+
import net.minestom.server.world.biome.Biome;
1415
import org.jetbrains.annotations.NotNull;
1516
import org.jetbrains.annotations.Nullable;
1617

@@ -36,13 +37,20 @@ final class StreamingPolarLoader {
3637

3738
private final Object2IntMap<String> blockToStateIdCache = new Object2IntOpenHashMap<>();
3839
private final Object2IntMap<String> biomeToIdCache = new Object2IntOpenHashMap<>();
40+
private final int plainsBiomeId;
3941

4042
StreamingPolarLoader(@NotNull InstanceContainer instance, @NotNull PolarDataConverter dataConverter,
4143
@Nullable PolarWorldAccess worldAccess, boolean loadLighting) {
4244
this.instance = instance;
4345
this.dataConverter = dataConverter;
4446
this.worldAccess = worldAccess;
4547
this.loadLighting = loadLighting;
48+
49+
var searchWorldAccess = Objects.requireNonNullElse(worldAccess, PolarWorldAccess.DEFAULT);
50+
this.plainsBiomeId = searchWorldAccess.getBiomeId(Biome.PLAINS.name());
51+
if (this.plainsBiomeId == -1) {
52+
throw new IllegalStateException("Plains biome not found");
53+
}
4654
}
4755

4856
public void loadAllSequential(@NotNull ReadableByteChannel channel, long fileSize) throws IOException {
@@ -280,11 +288,11 @@ private int[] readBiomePalette(@NotNull NetworkBuffer buffer) {
280288
int[] biomePalette = new int[rawBiomePalette.length];
281289
for (int i = 0; i < rawBiomePalette.length; i++) {
282290
biomePalette[i] = biomeToIdCache.computeIfAbsent(rawBiomePalette[i], (String name) -> {
283-
PolarWorldAccess worldAccess = Objects.requireNonNullElse(this.worldAccess, PolarWorldAccess.DEFAULT);
284-
var biomeId = BIOME_REGISTRY.getId(worldAccess.getBiome(name));
291+
PolarWorldAccess searchWorldAccess = Objects.requireNonNullElse(this.worldAccess, PolarWorldAccess.DEFAULT);
292+
var biomeId = searchWorldAccess.getBiomeId(name);
285293
if (biomeId == -1) {
286294
logger.error("Failed to find biome: {}", name);
287-
biomeId = PLAINS_BIOME_ID;
295+
biomeId = this.plainsBiomeId;
288296
}
289297
return biomeId;
290298
});
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package net.hollowcube.polar;
2+
3+
import net.minestom.server.MinecraftServer;
4+
import net.minestom.server.instance.InstanceContainer;
5+
import net.minestom.server.world.DimensionType;
6+
import org.jetbrains.annotations.NotNull;
7+
import org.junit.jupiter.api.Test;
8+
9+
import java.util.UUID;
10+
11+
import static org.junit.jupiter.api.Assertions.assertEquals;
12+
13+
class TestCustomBiomes {
14+
15+
static {
16+
MinecraftServer.init();
17+
}
18+
19+
@Test
20+
void testWriteRead() {
21+
var world = new PolarWorld();
22+
23+
var wa = new PolarWorldAccess() {
24+
@Override
25+
public int getBiomeId(@NotNull String name) {
26+
return "test:biome".equals(name) ? 1000 : PolarWorldAccess.super.getBiomeId(name);
27+
}
28+
29+
@Override
30+
public @NotNull String getBiomeName(int id) {
31+
return id == 1000 ? "test:biome" : PolarWorldAccess.super.getBiomeName(id);
32+
}
33+
};
34+
var loader = new PolarLoader(world).setWorldAccess(wa);
35+
var instance = new InstanceContainer(UUID.randomUUID(), DimensionType.OVERWORLD, loader);
36+
var chunk = instance.loadChunk(0, 0).join();
37+
chunk.getSection(0).biomePalette().fill(1000);
38+
39+
loader.saveChunk(chunk);
40+
41+
var newInstance = new InstanceContainer(UUID.randomUUID(), DimensionType.OVERWORLD, loader);
42+
var newChunk = loader.loadChunk(newInstance, 0, 0);
43+
44+
assertEquals(1000, newChunk.getSection(0).biomePalette().get(2, 2, 2));
45+
}
46+
47+
}

0 commit comments

Comments
 (0)