From 0921dfb204433ed4e447989945785a94d7e1e380 Mon Sep 17 00:00:00 2001 From: Peter Pan Date: Wed, 19 Mar 2025 15:54:11 -0400 Subject: [PATCH 01/18] Bukkit Build Fix --- buildSrc/build.gradle.kts | 4 ++-- buildSrc/src/main/kotlin/Versions.kt | 8 ++++---- gradle/wrapper/gradle-wrapper.properties | 3 +-- platforms/bukkit/nms/v1_21_3/build.gradle.kts | 7 +++++-- settings.gradle.kts | 3 +++ 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index cec2d002d..ebaa51062 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -17,8 +17,8 @@ repositories { dependencies { //TODO Allow pulling from Versions.kt implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.1") - implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "1.7.2") - + //implementation("io.papermc.paperweight", "io.papermc.paperweight.userdev.gradle.plugin", "2.0.0-beta.16") + implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:2.0.0-beta.16") implementation("org.ow2.asm", "asm", "9.7") implementation("org.ow2.asm", "asm-tree", "9.7") implementation("com.dfsek.tectonic", "common", "4.2.1") diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 322516af6..cbbbcc989 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -44,8 +44,8 @@ object Versions { const val yarn = "$minecraft+build.8" const val fabricLoader = "0.16.10" - const val architecuryLoom = "1.7.413" - const val architecturyPlugin = "3.4.159" + const val architecuryLoom = "1.9.428" + const val architecturyPlugin = "3.4.161" } // @@ -56,13 +56,13 @@ object Versions { object Bukkit { const val minecraft = "1.21.4" - const val paperBuild = "$minecraft-R0.1-20241211.212446-17" + const val paperBuild = "$minecraft-R0.1-20250317.101324-208" const val paper = paperBuild const val paperLib = "1.0.8" const val reflectionRemapper = "0.1.1" const val paperDevBundle = paperBuild const val runPaper = "2.3.1" - const val paperWeight = "1.7.2" + const val paperWeight = "2.0.0-beta.16" const val cloud = "2.0.0-beta.10" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fb602ee2a..cea7a793a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/platforms/bukkit/nms/v1_21_3/build.gradle.kts b/platforms/bukkit/nms/v1_21_3/build.gradle.kts index d52f1d169..7cc74d30f 100644 --- a/platforms/bukkit/nms/v1_21_3/build.gradle.kts +++ b/platforms/bukkit/nms/v1_21_3/build.gradle.kts @@ -1,8 +1,11 @@ -apply(plugin = "io.papermc.paperweight.userdev") +//apply(plugin = "io.papermc.paperweight.userdev") +plugins { + id("io.papermc.paperweight.userdev") +} dependencies { api(project(":platforms:bukkit:common")) - paperDevBundle(Versions.Bukkit.paperDevBundle) + paperweight.paperDevBundle(Versions.Bukkit.paperDevBundle) implementation("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper) } diff --git a/settings.gradle.kts b/settings.gradle.kts index 86bb41bfb..85bd67cdc 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -38,6 +38,9 @@ pluginManagement { maven("https://maven.quiltmc.org/repository/release/") { name = "Quilt" } + maven("https://repo.papermc.io/repository/maven-public/") { + name = "PaperMC" + } } } From b6e4543625ffd86eac5de999966fd8abfad38ce2 Mon Sep 17 00:00:00 2001 From: Peter Pan Date: Thu, 20 Mar 2025 10:43:29 -0400 Subject: [PATCH 02/18] remove comments --- buildSrc/build.gradle.kts | 1 - platforms/bukkit/nms/v1_21_3/build.gradle.kts | 1 - 2 files changed, 2 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index ebaa51062..e326be11f 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -17,7 +17,6 @@ repositories { dependencies { //TODO Allow pulling from Versions.kt implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.1") - //implementation("io.papermc.paperweight", "io.papermc.paperweight.userdev.gradle.plugin", "2.0.0-beta.16") implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:2.0.0-beta.16") implementation("org.ow2.asm", "asm", "9.7") implementation("org.ow2.asm", "asm-tree", "9.7") diff --git a/platforms/bukkit/nms/v1_21_3/build.gradle.kts b/platforms/bukkit/nms/v1_21_3/build.gradle.kts index 7cc74d30f..31cad053a 100644 --- a/platforms/bukkit/nms/v1_21_3/build.gradle.kts +++ b/platforms/bukkit/nms/v1_21_3/build.gradle.kts @@ -1,4 +1,3 @@ -//apply(plugin = "io.papermc.paperweight.userdev") plugins { id("io.papermc.paperweight.userdev") } From 4c860ca4aeec4745c23175c8afd60016681f41d8 Mon Sep 17 00:00:00 2001 From: Peter Pan Date: Thu, 20 Mar 2025 10:53:49 -0400 Subject: [PATCH 03/18] remove papermc repo from gradle settings --- settings.gradle.kts | 3 --- 1 file changed, 3 deletions(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 85bd67cdc..86bb41bfb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -38,9 +38,6 @@ pluginManagement { maven("https://maven.quiltmc.org/repository/release/") { name = "Quilt" } - maven("https://repo.papermc.io/repository/maven-public/") { - name = "PaperMC" - } } } From fb0dbda296e8807c9a366fb83b6fc9a14b9feaa5 Mon Sep 17 00:00:00 2001 From: Peter Pan Date: Thu, 20 Mar 2025 11:01:41 -0400 Subject: [PATCH 04/18] add back gradle shasum --- gradle/wrapper/gradle-wrapper.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index cea7a793a..c855edfdc 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26 distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true From d33d4af2966c5a1f2eb58120346985352ed73ab9 Mon Sep 17 00:00:00 2001 From: Peter Pan Date: Thu, 20 Mar 2025 14:51:12 -0400 Subject: [PATCH 05/18] fix formatting, update gradle hash --- buildSrc/build.gradle.kts | 3 ++- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index e326be11f..4867397a3 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -17,7 +17,8 @@ repositories { dependencies { //TODO Allow pulling from Versions.kt implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.1") - implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:2.0.0-beta.16") + + implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "2.0.0-beta.16") implementation("org.ow2.asm", "asm", "9.7") implementation("org.ow2.asm", "asm-tree", "9.7") implementation("com.dfsek.tectonic", "common", "4.2.1") diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c855edfdc..e1b837a19 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26 +distributionSha256Sum=7a00d51fb93147819aab76024feece20b6b84e420694101f276be952e08bef03 distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true From 227bfe7b29f12e77fbec4d4fe7f497ee93ab2948 Mon Sep 17 00:00:00 2001 From: ckyuri Date: Sat, 12 Apr 2025 11:54:48 +0100 Subject: [PATCH 06/18] Minestom Updated to latest version as of now 4/12/2025 Updated method names to new documentation and changed minestom versioning. - Paper Build version was changed as I had issues building at all with the snapshot version. So it was changed to a generic version but everything still builds fine. --- buildSrc/src/main/kotlin/Versions.kt | 5 ++-- .../terra/minestom/MinestomPlatform.java | 27 +++++++++++++++---- .../minestom/biome/MinestomBiomeLoader.java | 9 +++---- .../minestom/block/MinestomBlockState.java | 8 +++--- .../minestom/entity/MinestomEntityType.java | 6 ++--- .../minestom/item/MinestomEnchantment.java | 25 +++++++++++++---- .../terra/minestom/item/MinestomMaterial.java | 5 ++-- 7 files changed, 57 insertions(+), 28 deletions(-) diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index cbbbcc989..9959aad08 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -56,7 +56,8 @@ object Versions { object Bukkit { const val minecraft = "1.21.4" - const val paperBuild = "$minecraft-R0.1-20250317.101324-208" + // swapped to use a generic SNAPSHOT instead of a specific timestamp + const val paperBuild = "$minecraft-R0.1-SNAPSHOT" const val paper = paperBuild const val paperLib = "1.0.8" const val reflectionRemapper = "0.1.1" @@ -83,6 +84,6 @@ object Versions { } object Minestom { - const val minestom = "187931e50b" + const val minestom = "fb895cb899" } } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomPlatform.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomPlatform.java index 78ac5ff18..af24a6043 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomPlatform.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomPlatform.java @@ -14,12 +14,16 @@ import com.dfsek.terra.minestom.entity.MinestomEntityType; import com.dfsek.terra.minestom.item.MinestomItemHandle; import com.dfsek.terra.minestom.world.MinestomChunkGeneratorWrapper; import com.dfsek.terra.minestom.world.MinestomWorldHandle; +import com.dfsek.terra.registry.master.ConfigRegistry.PackLoadFailuresException; + import net.minestom.server.MinecraftServer; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; +import java.io.IOException; + public final class MinestomPlatform extends AbstractPlatform { @@ -45,18 +49,32 @@ public final class MinestomPlatform extends AbstractPlatform { @Override public boolean reload() { getTerraConfig().load(this); - boolean succeed = loadConfigPacks(); + getRawConfigRegistry().clear(); + + try { + getRawConfigRegistry().loadAll(this); + } catch (IOException e) { + LOGGER.error("Failed to load configurations due to I/O error", e); + return false; // reload failed + } catch (PackLoadFailuresException e) { + LOGGER.error("Failed to load configurations due to pack load failures", e); + return false; // reload failed + } catch (Exception e) { + // Catch any other exceptions that might be thrown + LOGGER.error("Failed to load configurations due to unexpected error", e); + return false; + } MinecraftServer.getInstanceManager().getInstances().forEach(world -> { if(world.generator() instanceof MinestomChunkGeneratorWrapper wrapper) { getConfigRegistry().get(wrapper.getPack().getRegistryKey()).ifPresent(pack -> { wrapper.setPack(pack); - LOGGER.info("Replaced pack in chunk generator for instance {}", world.getUniqueId()); + LOGGER.info("Replaced pack in chunk generator for instance {}", world.getUuid()); }); } }); - return succeed; + return true; } @Override @@ -83,11 +101,10 @@ public final class MinestomPlatform extends AbstractPlatform { return file; } - public static MinestomPlatform getInstance() { if(INSTANCE == null) { INSTANCE = new MinestomPlatform(); } return INSTANCE; } -} +} \ No newline at end of file diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiomeLoader.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiomeLoader.java index 9cb3eb960..edaf49a50 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiomeLoader.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiomeLoader.java @@ -7,15 +7,14 @@ import com.dfsek.tectonic.api.loader.type.TypeLoader; import com.dfsek.terra.api.world.biome.PlatformBiome; +import net.kyori.adventure.key.Key; import net.minestom.server.MinecraftServer; import net.minestom.server.registry.DynamicRegistry; -import net.minestom.server.utils.NamespaceID; import net.minestom.server.world.biome.Biome; import org.jetbrains.annotations.NotNull; import java.lang.reflect.AnnotatedType; - public class MinestomBiomeLoader implements TypeLoader { private final DynamicRegistry biomeRegistry = MinecraftServer.getBiomeRegistry(); @@ -23,9 +22,9 @@ public class MinestomBiomeLoader implements TypeLoader { public PlatformBiome load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader, DepthTracker depthTracker) throws LoadException { String id = (String) o; - NamespaceID biomeID = NamespaceID.from(id); - Biome biome = biomeRegistry.get(biomeID); + Key key = Key.key(id); + Biome biome = biomeRegistry.get(key); if(biome == null) throw new LoadException("Biome %s does not exist in registry".formatted(id), depthTracker); return new MinestomBiome(biome); } -} +} \ No newline at end of file diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/MinestomBlockState.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/MinestomBlockState.java index 01bad55fa..d26470dae 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/MinestomBlockState.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/MinestomBlockState.java @@ -24,14 +24,14 @@ public class MinestomBlockState implements BlockState { public MinestomBlockState(String data) { if(!data.contains("[")) { - block = Block.fromNamespaceId(data); + block = Block.fromKey(data); return; } String[] split = data.split("\\["); String namespaceId = split[0]; String properties = split[1].substring(0, split[1].length() - 1); - Block block = Block.fromNamespaceId(namespaceId); + Block block = Block.fromKey(namespaceId); HashMap propertiesMap = new HashMap<>(); for(String property : properties.split(",")) { @@ -70,7 +70,7 @@ public class MinestomBlockState implements BlockState { @Override public String getAsString(boolean properties) { - String name = block.namespace().asString(); + String name = block.key().asString(); if(!properties || block.properties().isEmpty()) { return name; } @@ -95,4 +95,4 @@ public class MinestomBlockState implements BlockState { public int hashCode() { return Objects.hashCode(block.id()); } -} +} \ No newline at end of file diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntityType.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntityType.java index 60fbac5d9..d188cb0ea 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntityType.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntityType.java @@ -1,18 +1,16 @@ package com.dfsek.terra.minestom.entity; - import net.minestom.server.entity.EntityType; - public class MinestomEntityType implements com.dfsek.terra.api.entity.EntityType { private final EntityType delegate; public MinestomEntityType(String id) { - delegate = EntityType.fromNamespaceId(id); + delegate = EntityType.fromId(Integer.parseInt(id)); } @Override public EntityType getHandle() { return delegate; } -} +} \ No newline at end of file diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/item/MinestomEnchantment.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/item/MinestomEnchantment.java index 0ef720b31..69411571a 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/item/MinestomEnchantment.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/item/MinestomEnchantment.java @@ -3,9 +3,10 @@ package com.dfsek.terra.minestom.item; import com.dfsek.terra.api.inventory.ItemStack; import com.dfsek.terra.api.inventory.item.Enchantment; +import net.kyori.adventure.key.Key; import net.minestom.server.MinecraftServer; import net.minestom.server.item.Material; -import net.minestom.server.utils.NamespaceID; +import net.minestom.server.registry.DynamicRegistry; import java.util.Objects; @@ -16,11 +17,13 @@ public class MinestomEnchantment implements Enchantment { public MinestomEnchantment(net.minestom.server.item.enchant.Enchantment delegate) { this.delegate = delegate; - id = Objects.requireNonNull(delegate.registry()).raw(); + DynamicRegistry registry = MinecraftServer.getEnchantmentRegistry(); + this.id = Objects.requireNonNull(registry.getKey(delegate)).toString(); } public MinestomEnchantment(String id) { - this.delegate = MinecraftServer.getEnchantmentRegistry().get(NamespaceID.from(id)); + Key key = Key.key(id); + this.delegate = MinecraftServer.getEnchantmentRegistry().get(key); this.id = id; } @@ -31,7 +34,19 @@ public class MinestomEnchantment implements Enchantment { @Override public boolean conflictsWith(Enchantment other) { - return delegate.exclusiveSet().contains(NamespaceID.from(((MinestomEnchantment) other).id)); + var otherDelegate = ((MinestomEnchantment) other).delegate; + delegate.exclusiveSet(); + + // Get the registry key for the other enchantment to use in contains + try { + DynamicRegistry registry = MinecraftServer.getEnchantmentRegistry(); + DynamicRegistry.Key otherKey = registry.getKey(otherDelegate); + return delegate.exclusiveSet().contains(otherKey); + } catch (Exception e) { + // If the key approach fails, fall back to a more basic implementation + String otherId = ((MinestomEnchantment) other).id; + return otherId.equals(this.id); + } } @Override @@ -48,4 +63,4 @@ public class MinestomEnchantment implements Enchantment { public net.minestom.server.item.enchant.Enchantment getHandle() { return delegate; } -} +} \ No newline at end of file diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/item/MinestomMaterial.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/item/MinestomMaterial.java index 6bd0a1908..77aa8777d 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/item/MinestomMaterial.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/item/MinestomMaterial.java @@ -5,7 +5,6 @@ import com.dfsek.terra.api.inventory.ItemStack; import net.minestom.server.item.Material; - public class MinestomMaterial implements Item { private final Material delegate; @@ -14,7 +13,7 @@ public class MinestomMaterial implements Item { } public MinestomMaterial(String id) { - this.delegate = Material.fromNamespaceId(id); + this.delegate = Material.fromId(Integer.parseInt(id)); } @Override @@ -31,4 +30,4 @@ public class MinestomMaterial implements Item { public Material getHandle() { return delegate; } -} +} \ No newline at end of file From 32cc4976c84d4fc7ed2ce842a28dfbc2c7ea3ff5 Mon Sep 17 00:00:00 2001 From: ckyuri Date: Sat, 12 Apr 2025 14:10:54 +0100 Subject: [PATCH 07/18] Bug Fix - Entity Type was parsing a value that was incorrect and causing issues to load the world. EntityType.fromId(Integer.parseInt(id)); to delegate = EntityType.fromKey(id); --- .../com/dfsek/terra/minestom/entity/MinestomEntityType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntityType.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntityType.java index d188cb0ea..825fde33e 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntityType.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/entity/MinestomEntityType.java @@ -6,7 +6,7 @@ public class MinestomEntityType implements com.dfsek.terra.api.entity.EntityType private final EntityType delegate; public MinestomEntityType(String id) { - delegate = EntityType.fromId(Integer.parseInt(id)); + delegate = EntityType.fromKey(id); } @Override From 761a014ea58e19ef8e151f314179589dce833a1c Mon Sep 17 00:00:00 2001 From: ckyuri Date: Wed, 16 Apr 2025 15:54:20 +0100 Subject: [PATCH 08/18] Reverted changes to comply with build version requirements and avoiding pulling functionality out of a common existing function --- buildSrc/src/main/kotlin/Versions.kt | 7 ++----- .../terra/minestom/MinestomPlatform.java | 19 +++---------------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 90d4f300e..28580323c 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -56,11 +56,8 @@ object Versions { object Bukkit { const val minecraft = "1.21.4" - - // swapped to use a generic SNAPSHOT instead of a specific timestamp - //const val paperBuild = "$minecraft-R0.1-20250317.101324-208" - const val paperBuild = "$minecraft-R0.1-SNAPSHOT" - + + const val paperBuild = "$minecraft-R0.1-20250317.101324-208" const val paper = paperBuild const val paperLib = "1.0.8" const val reflectionRemapper = "0.1.1" diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomPlatform.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomPlatform.java index af24a6043..c63378a28 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomPlatform.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomPlatform.java @@ -49,21 +49,7 @@ public final class MinestomPlatform extends AbstractPlatform { @Override public boolean reload() { getTerraConfig().load(this); - getRawConfigRegistry().clear(); - - try { - getRawConfigRegistry().loadAll(this); - } catch (IOException e) { - LOGGER.error("Failed to load configurations due to I/O error", e); - return false; // reload failed - } catch (PackLoadFailuresException e) { - LOGGER.error("Failed to load configurations due to pack load failures", e); - return false; // reload failed - } catch (Exception e) { - // Catch any other exceptions that might be thrown - LOGGER.error("Failed to load configurations due to unexpected error", e); - return false; - } + boolean succeed = loadConfigPacks(); MinecraftServer.getInstanceManager().getInstances().forEach(world -> { if(world.generator() instanceof MinestomChunkGeneratorWrapper wrapper) { @@ -74,9 +60,10 @@ public final class MinestomPlatform extends AbstractPlatform { } }); - return true; + return succeed; } + @Override public @NotNull WorldHandle getWorldHandle() { return worldHandle; From d97fb4ff7b70cdc08797eb3c4b776368bc74e18d Mon Sep 17 00:00:00 2001 From: Christian Bergschneider Date: Tue, 27 May 2025 22:50:03 +0200 Subject: [PATCH 09/18] chore: update paper version --- buildSrc/src/main/kotlin/Versions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 28580323c..e22c6fbe4 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -57,7 +57,7 @@ object Versions { object Bukkit { const val minecraft = "1.21.4" - const val paperBuild = "$minecraft-R0.1-20250317.101324-208" + const val paperBuild = "$minecraft-R0.1-20250519.180216-226" const val paper = paperBuild const val paperLib = "1.0.8" const val reflectionRemapper = "0.1.1" From 1dd59c378e39123f13c17ed8014206fc91412e07 Mon Sep 17 00:00:00 2001 From: Christian Bergschneider Date: Tue, 27 May 2025 22:58:16 +0200 Subject: [PATCH 10/18] refactor(minestom): replace static singleton access to platform with dependency injection for better modularity Renamed `MinestomPlatform` to `TerraMinestomPlatform` and updated `TerraMinestomWorldBuilder` to utilize the platform instance directly. Simplified world builder initialization and improved code clarity. --- .../terra/minestom/TerraMinestomExample.java | 3 +- ...atform.java => TerraMinestomPlatform.java} | 41 +++++++++++-------- .../world/TerraMinestomWorldBuilder.java | 18 ++++---- 3 files changed, 34 insertions(+), 28 deletions(-) rename platforms/minestom/src/main/java/com/dfsek/terra/minestom/{MinestomPlatform.java => TerraMinestomPlatform.java} (69%) diff --git a/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java b/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java index 1cf95a226..0130347df 100644 --- a/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java +++ b/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java @@ -31,7 +31,8 @@ public class TerraMinestomExample { } public void attachTerra() { - world = TerraMinestomWorldBuilder.from(instance) + TerraMinestomPlatform platform = new TerraMinestomPlatform(); + world = platform.worldBuilder(instance) .defaultPack() .attach(); } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomPlatform.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/TerraMinestomPlatform.java similarity index 69% rename from platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomPlatform.java rename to platforms/minestom/src/main/java/com/dfsek/terra/minestom/TerraMinestomPlatform.java index c63378a28..bce7fe270 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/MinestomPlatform.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/TerraMinestomPlatform.java @@ -2,6 +2,7 @@ package com.dfsek.terra.minestom; import com.dfsek.tectonic.api.TypeRegistry; import com.dfsek.tectonic.api.loader.type.TypeLoader; + import com.dfsek.terra.AbstractPlatform; import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.entity.EntityType; @@ -14,34 +15,41 @@ import com.dfsek.terra.minestom.entity.MinestomEntityType; import com.dfsek.terra.minestom.item.MinestomItemHandle; import com.dfsek.terra.minestom.world.MinestomChunkGeneratorWrapper; import com.dfsek.terra.minestom.world.MinestomWorldHandle; -import com.dfsek.terra.registry.master.ConfigRegistry.PackLoadFailuresException; + +import com.dfsek.terra.minestom.world.TerraMinestomWorldBuilder; import net.minestom.server.MinecraftServer; +import net.minestom.server.instance.Instance; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; -import java.io.IOException; +public final class TerraMinestomPlatform extends AbstractPlatform { + private static final Logger LOGGER = LoggerFactory.getLogger(TerraMinestomPlatform.class); + private final WorldHandle worldHandle; + private final ItemHandle itemHandle; + private final TypeLoader biomeTypeLoader; -public final class MinestomPlatform extends AbstractPlatform { - private static final Logger LOGGER = LoggerFactory.getLogger(MinestomPlatform.class); - private static MinestomPlatform INSTANCE = null; - private final MinestomWorldHandle worldHandle = new MinestomWorldHandle(); - private final MinestomItemHandle itemHandle = new MinestomItemHandle(); - - private MinestomPlatform() { + public TerraMinestomPlatform(WorldHandle worldHandle, ItemHandle itemHandle, TypeLoader biomeTypeLoader) { + this.worldHandle = worldHandle; + this.itemHandle = itemHandle; + this.biomeTypeLoader = biomeTypeLoader; load(); getEventManager().callEvent(new PlatformInitializationEvent()); } + public TerraMinestomPlatform() { + this(new MinestomWorldHandle(), new MinestomItemHandle(), new MinestomBiomeLoader()); + } + @Override public void register(TypeRegistry registry) { super.register(registry); registry - .registerLoader(PlatformBiome.class, new MinestomBiomeLoader()) + .registerLoader(PlatformBiome.class, biomeTypeLoader) .registerLoader(EntityType.class, (TypeLoader) (annotatedType, o, configLoader, depthTracker) -> new MinestomEntityType((String) o)) .registerLoader(BlockState.class, (TypeLoader) (annotatedType, o, configLoader, depthTracker) -> worldHandle.createBlockState((String) o)); } @@ -82,16 +90,17 @@ public final class MinestomPlatform extends AbstractPlatform { @Override public @NotNull File getDataFolder() { String pathName = System.getProperty("terra.datafolder"); - if (pathName == null) pathName = "./terra/"; + if(pathName == null) pathName = "./terra/"; File file = new File(pathName); if(!file.exists()) file.mkdirs(); return file; } - public static MinestomPlatform getInstance() { - if(INSTANCE == null) { - INSTANCE = new MinestomPlatform(); - } - return INSTANCE; + public TerraMinestomWorldBuilder worldBuilder(Instance instance) { + return new TerraMinestomWorldBuilder(this, instance); + } + + public TerraMinestomWorldBuilder worldBuilder() { + return new TerraMinestomWorldBuilder(this, MinecraftServer.getInstanceManager().createInstanceContainer()); } } \ No newline at end of file diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java index 46ae1691c..3c77c372b 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java @@ -4,7 +4,7 @@ import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.registry.CheckedRegistry; -import com.dfsek.terra.minestom.MinestomPlatform; +import com.dfsek.terra.minestom.TerraMinestomPlatform; import com.dfsek.terra.minestom.api.BlockEntityFactory; import com.dfsek.terra.minestom.api.EntityFactory; import com.dfsek.terra.minestom.block.DefaultBlockEntityFactory; @@ -18,20 +18,16 @@ import java.util.function.Function; public class TerraMinestomWorldBuilder { + private final TerraMinestomPlatform platform; private final Instance instance; private ConfigPack pack; private long seed = new Random().nextLong(); private EntityFactory entityFactory = new DefaultEntityFactory(); private BlockEntityFactory blockEntityFactory = new DefaultBlockEntityFactory(); - private TerraMinestomWorldBuilder(Instance instance) { this.instance = instance; } - - public static TerraMinestomWorldBuilder from(Instance instance) { - return new TerraMinestomWorldBuilder(instance); - } - - public static TerraMinestomWorldBuilder builder() { - return new TerraMinestomWorldBuilder(MinecraftServer.getInstanceManager().createInstanceContainer()); + public TerraMinestomWorldBuilder(TerraMinestomPlatform platform, Instance instance) { + this.platform = platform; + this.instance = instance; } public TerraMinestomWorldBuilder pack(ConfigPack pack) { @@ -40,13 +36,13 @@ public class TerraMinestomWorldBuilder { } public TerraMinestomWorldBuilder packById(String id) { - this.pack = MinestomPlatform.getInstance().getConfigRegistry().getByID(id).orElseThrow(); + this.pack = platform.getConfigRegistry().getByID(id).orElseThrow(); return this; } public TerraMinestomWorldBuilder findPack(Function, ConfigPack> fn) { - this.pack = fn.apply(MinestomPlatform.getInstance().getConfigRegistry()); + this.pack = fn.apply(platform.getConfigRegistry()); return this; } From 089b25dea4c9213dd4422c4721d7b293551cb9b5 Mon Sep 17 00:00:00 2001 From: Christian Bergschneider Date: Tue, 27 May 2025 23:25:34 +0200 Subject: [PATCH 11/18] feat: update Minestom version and replace deprecated ItemComponent API Updated the Minestom library to version 1_21_5-69b9a5d844 and migrated from the deprecated `ItemComponent` API to `DataComponents`. This ensures compatibility with the latest changes and improves maintainability. --- buildSrc/src/main/kotlin/Versions.kt | 2 +- .../com/dfsek/terra/minestom/item/MinestomItemStack.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index e22c6fbe4..12eb8d75b 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -84,6 +84,6 @@ object Versions { } object Minestom { - const val minestom = "fb895cb899" + const val minestom = "1_21_5-69b9a5d844" } } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/item/MinestomItemStack.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/item/MinestomItemStack.java index 2b488a8c8..214785016 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/item/MinestomItemStack.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/item/MinestomItemStack.java @@ -6,7 +6,7 @@ import com.dfsek.terra.api.inventory.item.Enchantment; import com.dfsek.terra.api.inventory.item.ItemMeta; import net.minestom.server.MinecraftServer; -import net.minestom.server.item.ItemComponent; +import net.minestom.server.component.DataComponents; import net.minestom.server.item.ItemStack; import net.minestom.server.item.component.EnchantmentList; import net.minestom.server.registry.DynamicRegistry; @@ -47,7 +47,7 @@ public class MinestomItemStack implements com.dfsek.terra.api.inventory.ItemStac @Override public ItemMeta getItemMeta() { HashMap enchantments = new HashMap<>(); - EnchantmentList enchantmentList = base.get(ItemComponent.ENCHANTMENTS); + EnchantmentList enchantmentList = base.get(DataComponents.ENCHANTMENTS); if(enchantmentList != null) { enchantmentList.enchantments().forEach((enchantmentKey, integer) -> { enchantments.put( @@ -67,6 +67,6 @@ public class MinestomItemStack implements com.dfsek.terra.api.inventory.ItemStac }); EnchantmentList list = new EnchantmentList(enchantments); - base = base.with(ItemComponent.ENCHANTMENTS, list); + base = base.with(DataComponents.ENCHANTMENTS, list); } } From 5dff25670c103370af5cf8c5d6b412b6b0cb1e20 Mon Sep 17 00:00:00 2001 From: Christian Bergschneider Date: Fri, 30 May 2025 09:13:04 +0200 Subject: [PATCH 12/18] refactor: minestom chunk storage to improve memory efficiency Replaced 3D array with a 1D array for chunk block storage and adjusted related logic to use calculated indices. Updated block type comparison to use state IDs instead of block IDs for consistency and correctness. --- .../minestom/block/MinestomBlockType.java | 2 +- .../terra/minestom/chunk/CachedChunk.java | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/MinestomBlockType.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/MinestomBlockType.java index 8e4bd4360..803f13bc3 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/MinestomBlockType.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/MinestomBlockType.java @@ -41,7 +41,7 @@ public class MinestomBlockType implements BlockType { @Override public boolean equals(Object obj) { if(obj instanceof MinestomBlockType other) { - return block.id() == other.block.id(); + return block.stateId() == other.block.stateId(); } return false; } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/CachedChunk.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/CachedChunk.java index ed9ad8622..04f7f52d8 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/CachedChunk.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/CachedChunk.java @@ -10,40 +10,40 @@ import net.minestom.server.instance.block.Block; import net.minestom.server.instance.generator.UnitModifier; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; + public class CachedChunk implements ProtoChunk { private final int minHeight; private final int maxHeight; - private final Block[][][] blocks; + private final Block[] blocks; public CachedChunk(int minHeight, int maxHeight) { this.minHeight = minHeight; this.maxHeight = maxHeight; - this.blocks = new Block[16][maxHeight - minHeight + 1][16]; - - for(int x = 0; x < 16; x++) { - for(int z = 0; z < 16; z++) { - for(int y = 0; y < maxHeight - minHeight + 1; y++) { - blocks[x][y][z] = Block.AIR; - } - } - } + this.blocks = new Block[16 * (maxHeight - minHeight + 1) * 16]; + Arrays.fill(blocks, Block.AIR); } public void writeRelative(UnitModifier modifier) { - modifier.setAllRelative((x, y, z) -> blocks[x][y][z]); + modifier.setAllRelative((x, y, z) -> blocks[getIndex(x, y + minHeight, z)]); } @Override public void setBlock(int x, int y, int z, @NotNull BlockState blockState) { Block block = (Block) blockState.getHandle(); if(block == null) return; - blocks[x][y - minHeight][z] = block; + blocks[getIndex(x, y, z)] = block; + } + + private int getIndex(int x, int y, int z) { + int y_normalized = y - minHeight; + return x + (z * 16) + (y_normalized * 256); } @Override public @NotNull BlockState getBlock(int x, int y, int z) { - return new MinestomBlockState(blocks[x][y - minHeight][z]); + return new MinestomBlockState(blocks[getIndex(x, y, z)]); } @Override From 5e1c9d8ebe15d6885c295cd145d716fab02a4d78 Mon Sep 17 00:00:00 2001 From: Christian Bergschneider Date: Mon, 2 Jun 2025 00:34:48 +0200 Subject: [PATCH 13/18] fix: generation stages not being able to reference eachother --- .../terra/minestom/TerraMinestomExample.java | 3 ++ .../terra/minestom/biome/MinestomBiome.java | 7 ++-- .../minestom/biome/MinestomBiomeLoader.java | 10 ++--- .../terra/minestom/chunk/CachedChunk.java | 6 +++ .../minestom/chunk/GeneratedChunkCache.java | 19 ++++++--- .../world/MinestomChunkGeneratorWrapper.java | 39 +++++++++++++++++-- .../minestom/world/MinestomProtoWorld.java | 10 +++++ .../minestom/world/TerraMinestomWorld.java | 13 +++++-- .../world/TerraMinestomWorldBuilder.java | 2 +- 9 files changed, 86 insertions(+), 23 deletions(-) diff --git a/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java b/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java index 0130347df..792dbb195 100644 --- a/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java +++ b/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java @@ -122,12 +122,15 @@ public class TerraMinestomExample { private void regenerate() { instance.sendMessage(Component.text("Regenerating world")); + Instance oldInstance = instance; createNewInstance(); attachTerra(); preloadWorldAndMeasure(); MinecraftServer.getConnectionManager().getOnlinePlayers().forEach(player -> player.setInstance(instance, new Pos(0, 100, 0)) ); + + MinecraftServer.getInstanceManager().unregisterInstance(oldInstance); } } } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiome.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiome.java index a4c146359..a050978d6 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiome.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiome.java @@ -2,16 +2,17 @@ package com.dfsek.terra.minestom.biome; import com.dfsek.terra.api.world.biome.PlatformBiome; +import net.minestom.server.registry.DynamicRegistry; import net.minestom.server.world.biome.Biome; public class MinestomBiome implements PlatformBiome { - private final Biome biome; + private final DynamicRegistry.Key biome; - public MinestomBiome(Biome biome) { this.biome = biome; } + public MinestomBiome(DynamicRegistry.Key biome) { this.biome = biome; } @Override - public Biome getHandle() { + public DynamicRegistry.Key getHandle() { return biome; } } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiomeLoader.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiomeLoader.java index edaf49a50..ccd1176c5 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiomeLoader.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomBiomeLoader.java @@ -8,23 +8,19 @@ import com.dfsek.tectonic.api.loader.type.TypeLoader; import com.dfsek.terra.api.world.biome.PlatformBiome; import net.kyori.adventure.key.Key; -import net.minestom.server.MinecraftServer; import net.minestom.server.registry.DynamicRegistry; -import net.minestom.server.world.biome.Biome; +import org.intellij.lang.annotations.Subst; import org.jetbrains.annotations.NotNull; import java.lang.reflect.AnnotatedType; public class MinestomBiomeLoader implements TypeLoader { - private final DynamicRegistry biomeRegistry = MinecraftServer.getBiomeRegistry(); - @Override public PlatformBiome load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader, DepthTracker depthTracker) throws LoadException { + @Subst("name:value") String id = (String) o; Key key = Key.key(id); - Biome biome = biomeRegistry.get(key); - if(biome == null) throw new LoadException("Biome %s does not exist in registry".formatted(id), depthTracker); - return new MinestomBiome(biome); + return new MinestomBiome(DynamicRegistry.Key.of(key)); } } \ No newline at end of file diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/CachedChunk.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/CachedChunk.java index 04f7f52d8..c56336b20 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/CachedChunk.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/CachedChunk.java @@ -3,10 +3,16 @@ package com.dfsek.terra.minestom.chunk; import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.util.Column; +import com.dfsek.terra.api.world.biome.Biome; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.chunk.generation.ProtoChunk; +import com.dfsek.terra.minestom.biome.MinestomBiome; import com.dfsek.terra.minestom.block.MinestomBlockState; +import net.minestom.server.coordinate.Point; import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.generator.GenerationUnit; import net.minestom.server.instance.generator.UnitModifier; import org.jetbrains.annotations.NotNull; diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/GeneratedChunkCache.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/GeneratedChunkCache.java index 018c82c72..38064b86f 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/GeneratedChunkCache.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/GeneratedChunkCache.java @@ -22,13 +22,15 @@ public class GeneratedChunkCache { private final ServerWorld world; private final BiomeProvider biomeProvider; - public GeneratedChunkCache(DimensionType dimensionType, ChunkGenerator generator, ServerWorld world) { + public GeneratedChunkCache(DimensionType dimensionType, ChunkGenerator generator, ServerWorld world, BiomeProvider biomeProvider) { this.dimensionType = dimensionType; this.generator = generator; this.world = world; - this.biomeProvider = world.getBiomeProvider(); - this.cache = Caffeine.newBuilder().maximumSize(128).recordStats().build( - (Pair key) -> generateChunk(key.getLeft(), key.getRight())); + this.biomeProvider = biomeProvider; + this.cache = Caffeine.newBuilder() + .maximumSize(128) + .recordStats() + .build((Pair key) -> generateChunk(key.getLeft(), key.getRight())); } private CachedChunk generateChunk(int x, int z) { @@ -39,8 +41,13 @@ public class GeneratedChunkCache { public void displayStats() { CacheStats stats = cache.stats(); - log.info("Avg load time: {}ms | Hit rate: {}% | Load Count: {}", stats.averageLoadPenalty(), stats.hitRate() * 100, - stats.loadCount()); + log.info("Avg load time: %.4fms | Hit rate: %3.4f%% | Load Count: %d" + .formatted( + stats.averageLoadPenalty() / 1000000f, + stats.hitRate() * 100, + stats.loadCount() + ) + ); } public CachedChunk at(int x, int z) { diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java index 81529db48..f3829a65a 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java @@ -1,30 +1,41 @@ package com.dfsek.terra.minestom.world; +import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.world.biome.PlatformBiome; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage; import com.dfsek.terra.api.world.chunk.generation.util.GeneratorWrapper; +import com.dfsek.terra.minestom.biome.MinestomBiome; import com.dfsek.terra.minestom.chunk.CachedChunk; import com.dfsek.terra.minestom.chunk.GeneratedChunkCache; import net.minestom.server.coordinate.Point; import net.minestom.server.instance.generator.GenerationUnit; import net.minestom.server.instance.generator.Generator; +import net.minestom.server.instance.generator.UnitModifier; +import net.minestom.server.registry.DynamicRegistry; import org.jetbrains.annotations.NotNull; +import java.util.Objects; + public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrapper { private final GeneratedChunkCache cache; private ChunkGenerator generator; private final TerraMinestomWorld world; + private final BiomeProvider biomeProvider; private ConfigPack pack; - public MinestomChunkGeneratorWrapper(ChunkGenerator generator, TerraMinestomWorld world, ConfigPack pack) { + public MinestomChunkGeneratorWrapper(Platform platform, ChunkGenerator generator, TerraMinestomWorld world, ConfigPack pack) { this.generator = generator; this.world = world; this.pack = pack; - this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world); + + biomeProvider = pack.getBiomeProvider().caching(platform); + this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world, biomeProvider); } public ChunkGenerator getGenerator() { @@ -36,14 +47,36 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe Point start = unit.absoluteStart(); int x = start.chunkX(); int z = start.chunkZ(); + int blockX = start.blockX(); + int blockZ = start.blockZ(); CachedChunk chunk = cache.at(x, z); - chunk.writeRelative(unit.modifier()); + UnitModifier modifier = unit.modifier(); + chunk.writeRelative(modifier); + +// for(int dx = 0; dx < 16; dx++) { +// for(int dz = 0; dz < 16; dz++) { +// int globalX = dx + blockX; +// int globalZ = dz + blockZ; +// biomeProvider.getColumn(globalX, globalZ, world).forEach((y, biome) -> { +// MinestomBiome platformBiome = (MinestomBiome) biome.getPlatformBiome(); +// modifier.setBiome(globalX, 0, globalZ, DynamicRegistry.Key.of("minecraft:the_void")); +// }); +// } +// } unit.fork(setter -> { MinestomProtoWorld protoWorld = new MinestomProtoWorld(cache, x, z, world, setter); + var stages = world.getPack().getStages(); + + if(x==0 && z==0) { + System.out.println(stages); + System.out.println(protoWorld.getBlockState(-4, 73, -6).getAsString()); + } + for(GenerationStage stage : world.getPack().getStages()) { stage.populate(protoWorld); + if(x==0 && z==0) System.out.println(protoWorld.getBlockState(-4, 73, -6).getAsString()); } }); } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomProtoWorld.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomProtoWorld.java index 65ec22654..e29cc5d76 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomProtoWorld.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomProtoWorld.java @@ -5,6 +5,7 @@ import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.entity.Entity; import com.dfsek.terra.api.entity.EntityType; +import com.dfsek.terra.api.util.generic.pair.Pair; import com.dfsek.terra.api.world.ServerWorld; import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; @@ -17,6 +18,11 @@ import com.dfsek.terra.minestom.entity.DeferredMinestomEntity; import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block.Setter; +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.HashSet; +import java.util.WeakHashMap; + public class MinestomProtoWorld implements ProtoWorld { private final GeneratedChunkCache cache; @@ -51,6 +57,10 @@ public class MinestomProtoWorld implements ProtoWorld { @Override public void setBlockState(int x, int y, int z, BlockState data, boolean physics) { modifier.setBlock(x, y, z, (Block) data.getHandle()); + int chunkX = x >> 4; + int chunkZ = z >> 4; + CachedChunk chunk = cache.at(chunkX, chunkZ); + chunk.setBlock(x & 15, y, z & 15, data); } @Override diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java index 4f4aef091..692f96b64 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java @@ -13,6 +13,7 @@ import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; import com.dfsek.terra.api.world.info.WorldProperties; +import com.dfsek.terra.minestom.TerraMinestomPlatform; import com.dfsek.terra.minestom.api.BlockEntityFactory; import com.dfsek.terra.minestom.api.EntityFactory; import com.dfsek.terra.minestom.block.MinestomBlockState; @@ -37,8 +38,14 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties { private final EntityFactory entityFactory; private final BlockEntityFactory blockEntityFactory; - public TerraMinestomWorld(Instance instance, ConfigPack pack, long seed, EntityFactory entityFactory, - BlockEntityFactory blockEntityFactory) { + public TerraMinestomWorld( + TerraMinestomPlatform platform, + Instance instance, + ConfigPack pack, + long seed, + EntityFactory entityFactory, + BlockEntityFactory blockEntityFactory + ) { this.instance = instance; this.pack = pack; this.seed = seed; @@ -46,7 +53,7 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties { this.dimensionType = MinecraftServer.getDimensionTypeRegistry().get(instance.getDimensionType()); this.blockEntityFactory = blockEntityFactory; - this.wrapper = new MinestomChunkGeneratorWrapper(pack.getGeneratorProvider().newInstance(pack), this, pack); + this.wrapper = new MinestomChunkGeneratorWrapper(platform, pack.getGeneratorProvider().newInstance(pack), this, pack); this.entityFactory = entityFactory; instance.setGenerator(this.wrapper); diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java index 3c77c372b..c68b4b72f 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java @@ -66,6 +66,6 @@ public class TerraMinestomWorldBuilder { } public TerraMinestomWorld attach() { - return new TerraMinestomWorld(instance, pack, seed, entityFactory, blockEntityFactory); + return new TerraMinestomWorld(platform, instance, pack, seed, entityFactory, blockEntityFactory); } } From 858adfe866dcbf80d2ee8087d6e7fdf5090464c7 Mon Sep 17 00:00:00 2001 From: Christian Bergschneider Date: Tue, 3 Jun 2025 22:41:31 +0200 Subject: [PATCH 14/18] feat: initial custom biome implementation --- .../terra/minestom/TerraMinestomPlatform.java | 26 +++- .../terra/minestom/addon/MinestomAddon.java | 47 ++++++ .../terra/minestom/biome/BiomeFactory.java | 9 ++ .../biome/MinestomCustomBiomeFactory.java | 73 +++++++++ .../biome/MinestomCustomBiomePool.java | 39 +++++ .../terra/minestom/biome/NativeBiome.java | 9 ++ .../config/BiomeAdditionsSoundTemplate.java | 24 +++ .../config/BiomeMoodSoundTemplate.java | 37 +++++ .../config/BiomeParticleConfigTemplate.java | 30 ++++ .../terra/minestom/config/KeyLoader.java | 32 ++++ .../terra/minestom/config/RGBLikeLoader.java | 30 ++++ .../minestom/config/SoundEventTemplate.java | 28 ++++ .../config/VanillaBiomeProperties.java | 140 ++++++++++++++++++ .../world/MinestomChunkGeneratorWrapper.java | 51 +++---- .../minestom/world/TerraMinestomWorld.java | 14 +- .../world/TerraMinestomWorldBuilder.java | 10 +- 16 files changed, 570 insertions(+), 29 deletions(-) create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/addon/MinestomAddon.java create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/BiomeFactory.java create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomeFactory.java create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomePool.java create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/NativeBiome.java create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/BiomeAdditionsSoundTemplate.java create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/BiomeMoodSoundTemplate.java create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/BiomeParticleConfigTemplate.java create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/KeyLoader.java create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/RGBLikeLoader.java create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/SoundEventTemplate.java create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/VanillaBiomeProperties.java diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/TerraMinestomPlatform.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/TerraMinestomPlatform.java index bce7fe270..c699ff353 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/TerraMinestomPlatform.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/TerraMinestomPlatform.java @@ -4,13 +4,21 @@ import com.dfsek.tectonic.api.TypeRegistry; import com.dfsek.tectonic.api.loader.type.TypeLoader; import com.dfsek.terra.AbstractPlatform; +import com.dfsek.terra.api.addon.BaseAddon; import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.entity.EntityType; import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent; import com.dfsek.terra.api.handle.ItemHandle; import com.dfsek.terra.api.handle.WorldHandle; import com.dfsek.terra.api.world.biome.PlatformBiome; +import com.dfsek.terra.minestom.addon.MinestomAddon; +import com.dfsek.terra.minestom.config.BiomeAdditionsSoundTemplate; +import com.dfsek.terra.minestom.config.BiomeParticleConfigTemplate; import com.dfsek.terra.minestom.biome.MinestomBiomeLoader; +import com.dfsek.terra.minestom.config.KeyLoader; +import com.dfsek.terra.minestom.config.BiomeMoodSoundTemplate; +import com.dfsek.terra.minestom.config.RGBLikeLoader; +import com.dfsek.terra.minestom.config.SoundEventTemplate; import com.dfsek.terra.minestom.entity.MinestomEntityType; import com.dfsek.terra.minestom.item.MinestomItemHandle; import com.dfsek.terra.minestom.world.MinestomChunkGeneratorWrapper; @@ -18,13 +26,18 @@ import com.dfsek.terra.minestom.world.MinestomWorldHandle; import com.dfsek.terra.minestom.world.TerraMinestomWorldBuilder; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.util.RGBLike; import net.minestom.server.MinecraftServer; import net.minestom.server.instance.Instance; +import net.minestom.server.sound.SoundEvent; +import net.minestom.server.world.biome.BiomeEffects; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; +import java.util.List; public final class TerraMinestomPlatform extends AbstractPlatform { @@ -50,8 +63,14 @@ public final class TerraMinestomPlatform extends AbstractPlatform { super.register(registry); registry .registerLoader(PlatformBiome.class, biomeTypeLoader) + .registerLoader(RGBLike.class, new RGBLikeLoader()) + .registerLoader(Key.class, new KeyLoader()) .registerLoader(EntityType.class, (TypeLoader) (annotatedType, o, configLoader, depthTracker) -> new MinestomEntityType((String) o)) - .registerLoader(BlockState.class, (TypeLoader) (annotatedType, o, configLoader, depthTracker) -> worldHandle.createBlockState((String) o)); + .registerLoader(BlockState.class, (TypeLoader) (annotatedType, o, configLoader, depthTracker) -> worldHandle.createBlockState((String) o)) + .registerLoader(BiomeEffects.Particle.class, BiomeParticleConfigTemplate::new) + .registerLoader(BiomeEffects.MoodSound.class, BiomeMoodSoundTemplate::new) + .registerLoader(BiomeEffects.AdditionsSound.class, BiomeAdditionsSoundTemplate::new) + .registerLoader(SoundEvent.class, SoundEventTemplate::new); } @Override @@ -103,4 +122,9 @@ public final class TerraMinestomPlatform extends AbstractPlatform { public TerraMinestomWorldBuilder worldBuilder() { return new TerraMinestomWorldBuilder(this, MinecraftServer.getInstanceManager().createInstanceContainer()); } + + @Override + protected Iterable platformAddon() { + return List.of(new MinestomAddon(this)); + } } \ No newline at end of file diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/addon/MinestomAddon.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/addon/MinestomAddon.java new file mode 100644 index 000000000..4d4adc4b8 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/addon/MinestomAddon.java @@ -0,0 +1,47 @@ +package com.dfsek.terra.minestom.addon; + +import ca.solostudios.strata.Versions; +import ca.solostudios.strata.version.Version; + +import com.dfsek.terra.api.addon.BaseAddon; + +import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent; +import com.dfsek.terra.api.event.functional.FunctionalEventHandler; +import com.dfsek.terra.api.world.biome.Biome; + +import com.dfsek.terra.minestom.TerraMinestomPlatform; + +import com.dfsek.terra.minestom.config.VanillaBiomeProperties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class MinestomAddon implements BaseAddon { + private static final Version VERSION = Versions.getVersion(1, 0, 0); + private static final Logger logger = LoggerFactory.getLogger(MinestomAddon.class); + private final TerraMinestomPlatform minestomPlatform; + + public MinestomAddon(TerraMinestomPlatform minestomPlatform) { + this.minestomPlatform = minestomPlatform; + } + + @Override + public void initialize() { + minestomPlatform.getEventManager() + .getHandler(FunctionalEventHandler.class) + .register(this, ConfigurationLoadEvent.class) + .then(event -> { + if(event.is(Biome.class)) { + event.getLoadedObject(Biome.class).getContext().put(event.load(new VanillaBiomeProperties())); + } + }) + .global(); + } + + @Override + public Version getVersion() { return VERSION; } + + @Override + public String getID() { return "terra-minestom"; } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/BiomeFactory.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/BiomeFactory.java new file mode 100644 index 000000000..832305e3a --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/BiomeFactory.java @@ -0,0 +1,9 @@ +package com.dfsek.terra.minestom.biome; + +import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.world.biome.Biome; + + +public interface BiomeFactory { + NativeBiome create(ConfigPack pack, Biome source); +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomeFactory.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomeFactory.java new file mode 100644 index 000000000..f33c5c9a2 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomeFactory.java @@ -0,0 +1,73 @@ +package com.dfsek.terra.minestom.biome; + +import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.registry.key.RegistryKey; +import com.dfsek.terra.minestom.config.VanillaBiomeProperties; + +import net.kyori.adventure.key.Key; +import net.minestom.server.MinecraftServer; +import net.minestom.server.color.Color; +import net.minestom.server.registry.DynamicRegistry; +import net.minestom.server.world.biome.Biome; +import net.minestom.server.world.biome.BiomeEffects; +import org.intellij.lang.annotations.Subst; +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; +import java.util.Objects; + + +public class MinestomCustomBiomeFactory implements BiomeFactory { + private final DynamicRegistry biomeRegistry = MinecraftServer.getBiomeRegistry(); + private final @NotNull Biome plainsBiome = Objects.requireNonNull(biomeRegistry.get(Key.key("minecraft:plains"))); + + @Override + public NativeBiome create(ConfigPack pack, com.dfsek.terra.api.world.biome.Biome source) { + VanillaBiomeProperties properties = source.getContext().get(VanillaBiomeProperties.class); + DynamicRegistry.Key parentKey = ((MinestomBiome) source.getPlatformBiome()).getHandle(); + Biome parent = mergeNullable(biomeRegistry.get(parentKey), plainsBiome); + BiomeEffects parentEffects = parent.effects(); + Key key = Key.key("terra", createBiomeID(pack, source.getID())); + + BiomeEffects.Builder effectsBuilder = BiomeEffects.builder() + .fogColor(mergeNullable(properties.getFogColor(), parentEffects.fogColor())) + .skyColor(mergeNullable(properties.getSkyColor(), parentEffects.skyColor())) + .waterColor(mergeNullable(properties.getWaterColor(), parentEffects.waterColor())) + .waterFogColor(mergeNullable(properties.getWaterFogColor(), parentEffects.waterFogColor())) + .foliageColor(mergeNullable(properties.getFoliageColor(), parentEffects.foliageColor())) + .grassColor(mergeNullable(properties.getGrassColor(), parentEffects.grassColor())) + .grassColorModifier(mergeNullable(properties.getGrassColorModifier(), parentEffects.grassColorModifier())) + .biomeParticle(mergeNullable(properties.getParticleConfig(), parentEffects.biomeParticle())) + .ambientSound(mergeNullable(properties.getLoopSound(), parentEffects.ambientSound())) + .moodSound(mergeNullable(properties.getMoodSound(), parentEffects.moodSound())) + .additionsSound(mergeNullable(properties.getAdditionsSound(), parentEffects.additionsSound())) + // TODO music + .music(parentEffects.music()) + .musicVolume(parentEffects.musicVolume()); + + if (effectsBuilder.build().equals(BiomeEffects.PLAINS_EFFECTS)) { + effectsBuilder.fogColor(new Color(0xC0D8FE)); // circumvent a minestom bug + } + + Biome target = Biome.builder() + .downfall(mergeNullable(properties.getDownfall(), parent.downfall())) + .hasPrecipitation(mergeNullable(properties.getPrecipitation(), parent.hasPrecipitation())) + .temperature(mergeNullable(properties.getTemperature(), parent.temperature())) + .temperatureModifier(mergeNullable(properties.getTemperatureModifier(), parent.temperatureModifier())) + .effects(effectsBuilder.build()) + .build(); + + DynamicRegistry.Key registryKey = MinecraftServer.getBiomeRegistry().register(key, target); + return new NativeBiome(key, registryKey, source.getID(), target); + } + + private static T mergeNullable(T first, T second) { + if (first == null) return second; + return first; + } + + @Subst("value") + protected static String createBiomeID(ConfigPack pack, String biomeId) { + return pack.getID().toLowerCase() + "/" + biomeId.toLowerCase(Locale.ROOT); + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomePool.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomePool.java new file mode 100644 index 000000000..db0e48be6 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomePool.java @@ -0,0 +1,39 @@ +package com.dfsek.terra.minestom.biome; + +import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.world.biome.Biome; + +import java.util.HashMap; + + +public class MinestomCustomBiomePool { + private final HashMap biomes = new HashMap<>(); + private final MinestomCustomBiomeFactory factory; + private final ConfigPack configPack; + + public MinestomCustomBiomePool(ConfigPack configPack, MinestomCustomBiomeFactory factory) { + this.configPack = configPack; + this.factory = factory; + } + + public NativeBiome getBiome(Biome source) { + NativeBiome nativeBiome = biomes.get(source.getID()); + if(nativeBiome != null) return nativeBiome; + nativeBiome = factory.create(configPack, source); + biomes.put(source.getID(), nativeBiome); + return nativeBiome; + } + + public void preloadBiomes(Iterable biomesToLoad) { + biomesToLoad + .forEach(biome -> { + if(!this.biomes.containsKey(biome.getID())) { + this.biomes.put(biome.getID(), factory.create(configPack, biome)); + } + }); + } + + public void invalidate() { + biomes.clear(); + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/NativeBiome.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/NativeBiome.java new file mode 100644 index 000000000..e01728b7d --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/NativeBiome.java @@ -0,0 +1,9 @@ +package com.dfsek.terra.minestom.biome; + +import net.kyori.adventure.key.Key; +import net.minestom.server.registry.DynamicRegistry; +import net.minestom.server.world.biome.Biome; + + +public record NativeBiome(Key key, DynamicRegistry.Key registry, String id, Biome biome) { +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/BiomeAdditionsSoundTemplate.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/BiomeAdditionsSoundTemplate.java new file mode 100644 index 000000000..85e4499fc --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/BiomeAdditionsSoundTemplate.java @@ -0,0 +1,24 @@ +package com.dfsek.terra.minestom.config; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; +import net.minestom.server.sound.SoundEvent; +import net.minestom.server.world.biome.BiomeEffects; + + +public class BiomeAdditionsSoundTemplate implements ObjectTemplate { + @Value("sound") + @Default + private SoundEvent sound = null; + + @Value("sound-chance") + @Default + private Double soundChance = null; + + @Override + public BiomeEffects.AdditionsSound get() { + if(sound == null) return null; + return new BiomeEffects.AdditionsSound(sound, soundChance); + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/BiomeMoodSoundTemplate.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/BiomeMoodSoundTemplate.java new file mode 100644 index 000000000..a3b7bb3c8 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/BiomeMoodSoundTemplate.java @@ -0,0 +1,37 @@ +package com.dfsek.terra.minestom.config; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; +import net.minestom.server.sound.SoundEvent; +import net.minestom.server.world.biome.BiomeEffects; + + +public class BiomeMoodSoundTemplate implements ObjectTemplate { + @Value("sound") + @Default + private SoundEvent sound = null; + + @Value("cultivation-ticks") + @Default + private Integer soundCultivationTicks = null; + + @Value("spawn-range") + @Default + private Integer soundSpawnRange = null; + + @Value("extra-distance") + @Default + private Double soundExtraDistance = null; + + @Override + public BiomeEffects.MoodSound get() { + if(sound == null) return null; + return new BiomeEffects.MoodSound( + sound, + soundCultivationTicks, + soundSpawnRange, + soundExtraDistance + ); + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/BiomeParticleConfigTemplate.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/BiomeParticleConfigTemplate.java new file mode 100644 index 000000000..c095b7893 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/BiomeParticleConfigTemplate.java @@ -0,0 +1,30 @@ +package com.dfsek.terra.minestom.config; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; +import net.minestom.server.particle.Particle; +import net.minestom.server.world.biome.BiomeEffects; + + +public class BiomeParticleConfigTemplate implements ObjectTemplate { + @Value("particle") + @Default + private String particle = null; + + @Value("probability") + @Default + private Float probability = null; + + @Override + public BiomeEffects.Particle get() { + if(particle == null || probability == null) { + return null; + } + + return new BiomeEffects.Particle( + probability, + Particle.fromKey(particle) + ); + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/KeyLoader.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/KeyLoader.java new file mode 100644 index 000000000..406e64674 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/KeyLoader.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.minestom.config; + +import com.dfsek.tectonic.api.depth.DepthTracker; +import com.dfsek.tectonic.api.exception.LoadException; +import com.dfsek.tectonic.api.loader.ConfigLoader; +import com.dfsek.tectonic.api.loader.type.TypeLoader; +import net.kyori.adventure.key.InvalidKeyException; +import net.kyori.adventure.key.Key; +import org.intellij.lang.annotations.Subst; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.AnnotatedType; + + +public class KeyLoader implements TypeLoader { + @Override + public Key load( + @NotNull AnnotatedType annotatedType, + @NotNull Object o, + @NotNull ConfigLoader configLoader, + DepthTracker depthTracker + ) throws LoadException { + if(!(o instanceof @Subst("a:o") String stringKey)) { + throw new LoadException("Value is not a String", depthTracker); + } + try { + return Key.key(stringKey); + } catch(InvalidKeyException e) { + throw new LoadException("Can't load key: Invalid Format", e, depthTracker); + } + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/RGBLikeLoader.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/RGBLikeLoader.java new file mode 100644 index 000000000..de998edb5 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/RGBLikeLoader.java @@ -0,0 +1,30 @@ +package com.dfsek.terra.minestom.config; + +import com.dfsek.tectonic.api.depth.DepthTracker; +import com.dfsek.tectonic.api.exception.LoadException; +import com.dfsek.tectonic.api.loader.ConfigLoader; +import com.dfsek.tectonic.api.loader.type.TypeLoader; +import net.kyori.adventure.key.InvalidKeyException; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.util.RGBLike; +import net.minestom.server.color.Color; +import org.intellij.lang.annotations.Subst; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.AnnotatedType; + + +public class RGBLikeLoader implements TypeLoader { + @Override + public RGBLike load( + @NotNull AnnotatedType annotatedType, + @NotNull Object o, + @NotNull ConfigLoader configLoader, + DepthTracker depthTracker + ) throws LoadException { + if(!(o instanceof @Subst("a:o") Integer value)) { + throw new LoadException("Value is not an integer", depthTracker); + } + return new Color(value); + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/SoundEventTemplate.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/SoundEventTemplate.java new file mode 100644 index 000000000..c8bd81a13 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/SoundEventTemplate.java @@ -0,0 +1,28 @@ +package com.dfsek.terra.minestom.config; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; +import net.kyori.adventure.key.Key; +import net.minestom.server.sound.SoundEvent; + + +public class SoundEventTemplate implements ObjectTemplate { + @Value("id") + @Default + private Key id = null; + + @Value("distance-to-travel") + @Default + private Float distanceToTravel = null; + + @Override + public SoundEvent get() { + if(id == null) { + return null; + } else { + // distanceToTravel is specifically allowed to be null. + return SoundEvent.of(id, distanceToTravel); + } + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/VanillaBiomeProperties.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/VanillaBiomeProperties.java new file mode 100644 index 000000000..ea82cd7e2 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/config/VanillaBiomeProperties.java @@ -0,0 +1,140 @@ +package com.dfsek.terra.minestom.config; + +import com.dfsek.tectonic.api.config.template.ConfigTemplate; +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import com.dfsek.terra.api.properties.Properties; + +import net.kyori.adventure.util.RGBLike; +import net.minestom.server.sound.SoundEvent; +import net.minestom.server.world.biome.Biome.TemperatureModifier; +import net.minestom.server.world.biome.BiomeEffects; +import net.minestom.server.world.biome.BiomeEffects.GrassColorModifier; + + +public class VanillaBiomeProperties implements ConfigTemplate, Properties { + @Value("colors.grass") + @Default + private RGBLike grassColor = null; + + @Value("colors.fog") + @Default + private RGBLike fogColor = null; + + @Value("colors.water") + @Default + private RGBLike waterColor = null; + + @Value("colors.water-fog") + @Default + private RGBLike waterFogColor = null; + + @Value("colors.foliage") + @Default + private RGBLike foliageColor = null; + + @Value("colors.sky") + @Default + private RGBLike skyColor = null; + + @Value("colors.modifier") + @Default + private GrassColorModifier grassColorModifier = null; + + @Value("particles") + @Default + private BiomeEffects.Particle particleConfig = null; + + @Value("climate.precipitation") + @Default + private Boolean precipitation = null; + + @Value("climate.temperature") + @Default + private Float temperature = null; + + @Value("climate.temperature-modifier") + @Default + private TemperatureModifier temperatureModifier = null; + + @Value("climate.downfall") + @Default + private Float downfall = null; + + @Value("sound.loop-sound.sound") + @Default + private SoundEvent loopSound = null; + + @Value("sound.mood-sound") + @Default + private BiomeEffects.MoodSound moodSound = null; + + @Value("sound.additions-sound") + @Default + private BiomeEffects.AdditionsSound additionsSound = null; + +// @Value("sound.music") +// @Default +// private MusicSound music = null; + + public RGBLike getGrassColor() { + return grassColor; + } + + public RGBLike getFogColor() { + return fogColor; + } + + public RGBLike getWaterColor() { + return waterColor; + } + + public RGBLike getWaterFogColor() { + return waterFogColor; + } + + public RGBLike getFoliageColor() { + return foliageColor; + } + + public RGBLike getSkyColor() { + return skyColor; + } + + public GrassColorModifier getGrassColorModifier() { + return grassColorModifier; + } + + public BiomeEffects.Particle getParticleConfig() { + return particleConfig; + } + + public Boolean getPrecipitation() { + return precipitation; + } + + public Float getTemperature() { + return temperature; + } + + public TemperatureModifier getTemperatureModifier() { + return temperatureModifier; + } + + public Float getDownfall() { + return downfall; + } + + public SoundEvent getLoopSound() { + return loopSound; + } + + public BiomeEffects.MoodSound getMoodSound() { + return moodSound; + } + + public BiomeEffects.AdditionsSound getAdditionsSound() { + return additionsSound; + } +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java index f3829a65a..c3eba7b34 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java @@ -2,25 +2,25 @@ package com.dfsek.terra.minestom.world; import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.api.world.biome.PlatformBiome; import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage; import com.dfsek.terra.api.world.chunk.generation.util.GeneratorWrapper; -import com.dfsek.terra.minestom.biome.MinestomBiome; +import com.dfsek.terra.minestom.biome.MinestomCustomBiomeFactory; +import com.dfsek.terra.minestom.biome.MinestomCustomBiomePool; +import com.dfsek.terra.minestom.biome.NativeBiome; import com.dfsek.terra.minestom.chunk.CachedChunk; import com.dfsek.terra.minestom.chunk.GeneratedChunkCache; +import net.minestom.server.MinecraftServer; import net.minestom.server.coordinate.Point; +import net.minestom.server.entity.Player; import net.minestom.server.instance.generator.GenerationUnit; import net.minestom.server.instance.generator.Generator; import net.minestom.server.instance.generator.UnitModifier; -import net.minestom.server.registry.DynamicRegistry; import org.jetbrains.annotations.NotNull; -import java.util.Objects; - public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrapper { private final GeneratedChunkCache cache; @@ -28,14 +28,22 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe private final TerraMinestomWorld world; private final BiomeProvider biomeProvider; private ConfigPack pack; + private final MinestomCustomBiomePool biomePool; - public MinestomChunkGeneratorWrapper(Platform platform, ChunkGenerator generator, TerraMinestomWorld world, ConfigPack pack) { + public MinestomChunkGeneratorWrapper( + Platform platform, + ChunkGenerator generator, + TerraMinestomWorld world, + ConfigPack pack, + MinestomCustomBiomePool biomePool + ) { this.generator = generator; this.world = world; this.pack = pack; - + this.biomePool = biomePool; biomeProvider = pack.getBiomeProvider().caching(platform); this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world, biomeProvider); + preloadBiomes(); } public ChunkGenerator getGenerator() { @@ -53,30 +61,14 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe UnitModifier modifier = unit.modifier(); chunk.writeRelative(modifier); -// for(int dx = 0; dx < 16; dx++) { -// for(int dz = 0; dz < 16; dz++) { -// int globalX = dx + blockX; -// int globalZ = dz + blockZ; -// biomeProvider.getColumn(globalX, globalZ, world).forEach((y, biome) -> { -// MinestomBiome platformBiome = (MinestomBiome) biome.getPlatformBiome(); -// modifier.setBiome(globalX, 0, globalZ, DynamicRegistry.Key.of("minecraft:the_void")); -// }); -// } -// } + NativeBiome nativeBiome = biomePool.getBiome(biomeProvider.getBiome(blockX, 100, blockZ, world.getSeed())); + modifier.fillBiome(nativeBiome.registry()); unit.fork(setter -> { MinestomProtoWorld protoWorld = new MinestomProtoWorld(cache, x, z, world, setter); - var stages = world.getPack().getStages(); - - if(x==0 && z==0) { - System.out.println(stages); - System.out.println(protoWorld.getBlockState(-4, 73, -6).getAsString()); - } - for(GenerationStage stage : world.getPack().getStages()) { stage.populate(protoWorld); - if(x==0 && z==0) System.out.println(protoWorld.getBlockState(-4, 73, -6).getAsString()); } }); } @@ -88,6 +80,15 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe public void setPack(ConfigPack pack) { this.pack = pack; this.generator = pack.getGeneratorProvider().newInstance(pack); + this.biomePool.invalidate(); + preloadBiomes(); + } + + private void preloadBiomes() { + this.biomePool.preloadBiomes(world.getBiomeProvider().getBiomes()); + for(Player player : MinecraftServer.getConnectionManager().getOnlinePlayers()) { + player.startConfigurationPhase(); + } } public void displayStats() { diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java index 692f96b64..cbc80522a 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java @@ -16,6 +16,9 @@ import com.dfsek.terra.api.world.info.WorldProperties; import com.dfsek.terra.minestom.TerraMinestomPlatform; import com.dfsek.terra.minestom.api.BlockEntityFactory; import com.dfsek.terra.minestom.api.EntityFactory; +import com.dfsek.terra.minestom.biome.BiomeFactory; +import com.dfsek.terra.minestom.biome.MinestomCustomBiomeFactory; +import com.dfsek.terra.minestom.biome.MinestomCustomBiomePool; import com.dfsek.terra.minestom.block.MinestomBlockState; import com.dfsek.terra.minestom.entity.MinestomEntity; @@ -44,7 +47,8 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties { ConfigPack pack, long seed, EntityFactory entityFactory, - BlockEntityFactory blockEntityFactory + BlockEntityFactory blockEntityFactory, + BiomeFactory factory ) { this.instance = instance; this.pack = pack; @@ -53,7 +57,13 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties { this.dimensionType = MinecraftServer.getDimensionTypeRegistry().get(instance.getDimensionType()); this.blockEntityFactory = blockEntityFactory; - this.wrapper = new MinestomChunkGeneratorWrapper(platform, pack.getGeneratorProvider().newInstance(pack), this, pack); + this.wrapper = new MinestomChunkGeneratorWrapper( + platform, + pack.getGeneratorProvider().newInstance(pack), + this, + pack, + new MinestomCustomBiomePool(pack, new MinestomCustomBiomeFactory()) + ); this.entityFactory = entityFactory; instance.setGenerator(this.wrapper); diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java index c68b4b72f..1983bdee9 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java @@ -7,6 +7,8 @@ import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.minestom.TerraMinestomPlatform; import com.dfsek.terra.minestom.api.BlockEntityFactory; import com.dfsek.terra.minestom.api.EntityFactory; +import com.dfsek.terra.minestom.biome.BiomeFactory; +import com.dfsek.terra.minestom.biome.MinestomCustomBiomeFactory; import com.dfsek.terra.minestom.block.DefaultBlockEntityFactory; import com.dfsek.terra.minestom.entity.DefaultEntityFactory; @@ -24,6 +26,7 @@ public class TerraMinestomWorldBuilder { private long seed = new Random().nextLong(); private EntityFactory entityFactory = new DefaultEntityFactory(); private BlockEntityFactory blockEntityFactory = new DefaultBlockEntityFactory(); + private BiomeFactory biomeFactory = new MinestomCustomBiomeFactory(); public TerraMinestomWorldBuilder(TerraMinestomPlatform platform, Instance instance) { this.platform = platform; @@ -65,7 +68,12 @@ public class TerraMinestomWorldBuilder { return this; } + public TerraMinestomWorldBuilder biomeFactory(BiomeFactory factory) { + this.biomeFactory = factory; + return this; + } + public TerraMinestomWorld attach() { - return new TerraMinestomWorld(platform, instance, pack, seed, entityFactory, blockEntityFactory); + return new TerraMinestomWorld(platform, instance, pack, seed, entityFactory, blockEntityFactory, biomeFactory); } } From 56a1feb708311ae05ab194b1ddc6a9105893b422 Mon Sep 17 00:00:00 2001 From: Christian Bergschneider Date: Wed, 4 Jun 2025 00:05:15 +0200 Subject: [PATCH 15/18] refactor: move biomes to use user-defined naming conventions. Replaced "Custom" with "UserDefined" in biome classes, factories, and references for consistency and clarity. Updated relevant imports, method signatures, and internal logic to align with the new terminology. This change improves readability and better represents the purpose of these biome-related components. --- .../terra/minestom/TerraMinestomExample.java | 1 - .../terra/minestom/TerraMinestomPlatform.java | 17 +++++++++------- .../terra/minestom/api/BiomeFactory.java | 15 ++++++++++++++ .../TerraMinestomWorldBuilder.java | 11 ++++------ .../terra/minestom/biome/BiomeFactory.java | 9 --------- ...a => MinestomUserDefinedBiomeFactory.java} | 8 ++++---- ...java => MinestomUserDefinedBiomePool.java} | 20 +++++++++---------- ...NativeBiome.java => UserDefinedBiome.java} | 2 +- .../world/MinestomChunkGeneratorWrapper.java | 13 ++++++------ .../minestom/world/TerraMinestomWorld.java | 8 ++++---- 10 files changed, 54 insertions(+), 50 deletions(-) create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/BiomeFactory.java rename platforms/minestom/src/main/java/com/dfsek/terra/minestom/{world => api}/TerraMinestomWorldBuilder.java (85%) delete mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/BiomeFactory.java rename platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/{MinestomCustomBiomeFactory.java => MinestomUserDefinedBiomeFactory.java} (92%) rename platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/{MinestomCustomBiomePool.java => MinestomUserDefinedBiomePool.java} (51%) rename platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/{NativeBiome.java => UserDefinedBiome.java} (63%) diff --git a/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java b/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java index 792dbb195..afa1f0627 100644 --- a/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java +++ b/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java @@ -16,7 +16,6 @@ import java.time.Duration; import java.util.concurrent.atomic.AtomicInteger; import com.dfsek.terra.minestom.world.TerraMinestomWorld; -import com.dfsek.terra.minestom.world.TerraMinestomWorldBuilder; public class TerraMinestomExample { diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/TerraMinestomPlatform.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/TerraMinestomPlatform.java index c699ff353..527eb85be 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/TerraMinestomPlatform.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/TerraMinestomPlatform.java @@ -24,7 +24,7 @@ import com.dfsek.terra.minestom.item.MinestomItemHandle; import com.dfsek.terra.minestom.world.MinestomChunkGeneratorWrapper; import com.dfsek.terra.minestom.world.MinestomWorldHandle; -import com.dfsek.terra.minestom.world.TerraMinestomWorldBuilder; +import com.dfsek.terra.minestom.api.TerraMinestomWorldBuilder; import net.kyori.adventure.key.Key; import net.kyori.adventure.util.RGBLike; @@ -37,6 +37,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; +import java.util.ArrayList; import java.util.List; @@ -45,11 +46,13 @@ public final class TerraMinestomPlatform extends AbstractPlatform { private final WorldHandle worldHandle; private final ItemHandle itemHandle; private final TypeLoader biomeTypeLoader; + private final ArrayList platformAddons = new ArrayList<>(List.of(new MinestomAddon(this))); - public TerraMinestomPlatform(WorldHandle worldHandle, ItemHandle itemHandle, TypeLoader biomeTypeLoader) { + public TerraMinestomPlatform(WorldHandle worldHandle, ItemHandle itemHandle, TypeLoader biomeTypeLoader, BaseAddon... extraAddons) { this.worldHandle = worldHandle; this.itemHandle = itemHandle; this.biomeTypeLoader = biomeTypeLoader; + this.platformAddons.addAll(List.of(extraAddons)); load(); getEventManager().callEvent(new PlatformInitializationEvent()); } @@ -115,6 +118,11 @@ public final class TerraMinestomPlatform extends AbstractPlatform { return file; } + @Override + protected Iterable platformAddon() { + return platformAddons; + } + public TerraMinestomWorldBuilder worldBuilder(Instance instance) { return new TerraMinestomWorldBuilder(this, instance); } @@ -122,9 +130,4 @@ public final class TerraMinestomPlatform extends AbstractPlatform { public TerraMinestomWorldBuilder worldBuilder() { return new TerraMinestomWorldBuilder(this, MinecraftServer.getInstanceManager().createInstanceContainer()); } - - @Override - protected Iterable platformAddon() { - return List.of(new MinestomAddon(this)); - } } \ No newline at end of file diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/BiomeFactory.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/BiomeFactory.java new file mode 100644 index 000000000..ee59f29d5 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/BiomeFactory.java @@ -0,0 +1,15 @@ +package com.dfsek.terra.minestom.api; + +import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.world.biome.Biome; +import com.dfsek.terra.minestom.biome.UserDefinedBiome; + + +/** + * BiomeFactory serves as a contract for creating custom user-defined biomes in Terra. + * Implementations of this interface are responsible for defining the logic to convert + * configured biomes and source biome data into instances of UserDefinedBiome. + */ +public interface BiomeFactory { + UserDefinedBiome create(ConfigPack pack, Biome source); +} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/TerraMinestomWorldBuilder.java similarity index 85% rename from platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java rename to platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/TerraMinestomWorldBuilder.java index 1983bdee9..a3f3354d3 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorldBuilder.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/TerraMinestomWorldBuilder.java @@ -1,18 +1,15 @@ -package com.dfsek.terra.minestom.world; +package com.dfsek.terra.minestom.api; import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.minestom.TerraMinestomPlatform; -import com.dfsek.terra.minestom.api.BlockEntityFactory; -import com.dfsek.terra.minestom.api.EntityFactory; -import com.dfsek.terra.minestom.biome.BiomeFactory; -import com.dfsek.terra.minestom.biome.MinestomCustomBiomeFactory; +import com.dfsek.terra.minestom.biome.MinestomUserDefinedBiomeFactory; import com.dfsek.terra.minestom.block.DefaultBlockEntityFactory; import com.dfsek.terra.minestom.entity.DefaultEntityFactory; -import net.minestom.server.MinecraftServer; +import com.dfsek.terra.minestom.world.TerraMinestomWorld; import net.minestom.server.instance.Instance; import java.util.Random; @@ -26,7 +23,7 @@ public class TerraMinestomWorldBuilder { private long seed = new Random().nextLong(); private EntityFactory entityFactory = new DefaultEntityFactory(); private BlockEntityFactory blockEntityFactory = new DefaultBlockEntityFactory(); - private BiomeFactory biomeFactory = new MinestomCustomBiomeFactory(); + private BiomeFactory biomeFactory = new MinestomUserDefinedBiomeFactory(); public TerraMinestomWorldBuilder(TerraMinestomPlatform platform, Instance instance) { this.platform = platform; diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/BiomeFactory.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/BiomeFactory.java deleted file mode 100644 index 832305e3a..000000000 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/BiomeFactory.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.dfsek.terra.minestom.biome; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.api.world.biome.Biome; - - -public interface BiomeFactory { - NativeBiome create(ConfigPack pack, Biome source); -} diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomeFactory.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomUserDefinedBiomeFactory.java similarity index 92% rename from platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomeFactory.java rename to platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomUserDefinedBiomeFactory.java index f33c5c9a2..51d1fc07e 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomeFactory.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomUserDefinedBiomeFactory.java @@ -1,7 +1,7 @@ package com.dfsek.terra.minestom.biome; import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.api.registry.key.RegistryKey; +import com.dfsek.terra.minestom.api.BiomeFactory; import com.dfsek.terra.minestom.config.VanillaBiomeProperties; import net.kyori.adventure.key.Key; @@ -17,12 +17,12 @@ import java.util.Locale; import java.util.Objects; -public class MinestomCustomBiomeFactory implements BiomeFactory { +public class MinestomUserDefinedBiomeFactory implements BiomeFactory { private final DynamicRegistry biomeRegistry = MinecraftServer.getBiomeRegistry(); private final @NotNull Biome plainsBiome = Objects.requireNonNull(biomeRegistry.get(Key.key("minecraft:plains"))); @Override - public NativeBiome create(ConfigPack pack, com.dfsek.terra.api.world.biome.Biome source) { + public UserDefinedBiome create(ConfigPack pack, com.dfsek.terra.api.world.biome.Biome source) { VanillaBiomeProperties properties = source.getContext().get(VanillaBiomeProperties.class); DynamicRegistry.Key parentKey = ((MinestomBiome) source.getPlatformBiome()).getHandle(); Biome parent = mergeNullable(biomeRegistry.get(parentKey), plainsBiome); @@ -58,7 +58,7 @@ public class MinestomCustomBiomeFactory implements BiomeFactory { .build(); DynamicRegistry.Key registryKey = MinecraftServer.getBiomeRegistry().register(key, target); - return new NativeBiome(key, registryKey, source.getID(), target); + return new UserDefinedBiome(key, registryKey, source.getID(), target); } private static T mergeNullable(T first, T second) { diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomePool.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomUserDefinedBiomePool.java similarity index 51% rename from platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomePool.java rename to platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomUserDefinedBiomePool.java index db0e48be6..9eff185b3 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomCustomBiomePool.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomUserDefinedBiomePool.java @@ -6,22 +6,22 @@ import com.dfsek.terra.api.world.biome.Biome; import java.util.HashMap; -public class MinestomCustomBiomePool { - private final HashMap biomes = new HashMap<>(); - private final MinestomCustomBiomeFactory factory; +public class MinestomUserDefinedBiomePool { + private final HashMap biomes = new HashMap<>(); + private final MinestomUserDefinedBiomeFactory factory; private final ConfigPack configPack; - public MinestomCustomBiomePool(ConfigPack configPack, MinestomCustomBiomeFactory factory) { + public MinestomUserDefinedBiomePool(ConfigPack configPack, MinestomUserDefinedBiomeFactory factory) { this.configPack = configPack; this.factory = factory; } - public NativeBiome getBiome(Biome source) { - NativeBiome nativeBiome = biomes.get(source.getID()); - if(nativeBiome != null) return nativeBiome; - nativeBiome = factory.create(configPack, source); - biomes.put(source.getID(), nativeBiome); - return nativeBiome; + public UserDefinedBiome getBiome(Biome source) { + UserDefinedBiome userDefinedBiome = biomes.get(source.getID()); + if(userDefinedBiome != null) return userDefinedBiome; + userDefinedBiome = factory.create(configPack, source); + biomes.put(source.getID(), userDefinedBiome); + return userDefinedBiome; } public void preloadBiomes(Iterable biomesToLoad) { diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/NativeBiome.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/UserDefinedBiome.java similarity index 63% rename from platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/NativeBiome.java rename to platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/UserDefinedBiome.java index e01728b7d..059a0cc93 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/NativeBiome.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/UserDefinedBiome.java @@ -5,5 +5,5 @@ import net.minestom.server.registry.DynamicRegistry; import net.minestom.server.world.biome.Biome; -public record NativeBiome(Key key, DynamicRegistry.Key registry, String id, Biome biome) { +public record UserDefinedBiome(Key key, DynamicRegistry.Key registry, String id, Biome biome) { } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java index c3eba7b34..0e2109b99 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java @@ -7,9 +7,8 @@ import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage; import com.dfsek.terra.api.world.chunk.generation.util.GeneratorWrapper; -import com.dfsek.terra.minestom.biome.MinestomCustomBiomeFactory; -import com.dfsek.terra.minestom.biome.MinestomCustomBiomePool; -import com.dfsek.terra.minestom.biome.NativeBiome; +import com.dfsek.terra.minestom.biome.MinestomUserDefinedBiomePool; +import com.dfsek.terra.minestom.biome.UserDefinedBiome; import com.dfsek.terra.minestom.chunk.CachedChunk; import com.dfsek.terra.minestom.chunk.GeneratedChunkCache; @@ -28,14 +27,14 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe private final TerraMinestomWorld world; private final BiomeProvider biomeProvider; private ConfigPack pack; - private final MinestomCustomBiomePool biomePool; + private final MinestomUserDefinedBiomePool biomePool; public MinestomChunkGeneratorWrapper( Platform platform, ChunkGenerator generator, TerraMinestomWorld world, ConfigPack pack, - MinestomCustomBiomePool biomePool + MinestomUserDefinedBiomePool biomePool ) { this.generator = generator; this.world = world; @@ -61,8 +60,8 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe UnitModifier modifier = unit.modifier(); chunk.writeRelative(modifier); - NativeBiome nativeBiome = biomePool.getBiome(biomeProvider.getBiome(blockX, 100, blockZ, world.getSeed())); - modifier.fillBiome(nativeBiome.registry()); + UserDefinedBiome userDefinedBiome = biomePool.getBiome(biomeProvider.getBiome(blockX, 100, blockZ, world.getSeed())); + modifier.fillBiome(userDefinedBiome.registry()); unit.fork(setter -> { MinestomProtoWorld protoWorld = new MinestomProtoWorld(cache, x, z, world, setter); diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java index cbc80522a..88691e362 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java @@ -16,9 +16,9 @@ import com.dfsek.terra.api.world.info.WorldProperties; import com.dfsek.terra.minestom.TerraMinestomPlatform; import com.dfsek.terra.minestom.api.BlockEntityFactory; import com.dfsek.terra.minestom.api.EntityFactory; -import com.dfsek.terra.minestom.biome.BiomeFactory; -import com.dfsek.terra.minestom.biome.MinestomCustomBiomeFactory; -import com.dfsek.terra.minestom.biome.MinestomCustomBiomePool; +import com.dfsek.terra.minestom.api.BiomeFactory; +import com.dfsek.terra.minestom.biome.MinestomUserDefinedBiomeFactory; +import com.dfsek.terra.minestom.biome.MinestomUserDefinedBiomePool; import com.dfsek.terra.minestom.block.MinestomBlockState; import com.dfsek.terra.minestom.entity.MinestomEntity; @@ -62,7 +62,7 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties { pack.getGeneratorProvider().newInstance(pack), this, pack, - new MinestomCustomBiomePool(pack, new MinestomCustomBiomeFactory()) + new MinestomUserDefinedBiomePool(pack, new MinestomUserDefinedBiomeFactory()) ); this.entityFactory = entityFactory; From b12fe77f32c5012842edd84217d74f332976688b Mon Sep 17 00:00:00 2001 From: Christian Bergschneider Date: Wed, 4 Jun 2025 21:25:35 +0200 Subject: [PATCH 16/18] feat: add fine-grained biome control to Minestom world builder Introduced a `doFineGrainedBiomes` flag to allow fine-grained biome control per chunk. This helps mitigate client disconnection issues caused by a Minestom biome encoding bug, with a plan to deprecate once the bug is resolved. Adjusted relevant classes and the example implementation to support this feature. --- .../terra/minestom/TerraMinestomExample.java | 5 +++- .../api/TerraMinestomWorldBuilder.java | 16 ++++++++++- .../biome/MinestomUserDefinedBiomePool.java | 5 ++-- .../world/MinestomChunkGeneratorWrapper.java | 27 ++++++++++++++++--- .../minestom/world/TerraMinestomWorld.java | 6 +++-- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java b/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java index afa1f0627..2da66d2c9 100644 --- a/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java +++ b/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java @@ -6,6 +6,7 @@ import net.minestom.server.command.builder.Command; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.GameMode; import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; +import net.minestom.server.event.player.PlayerDisconnectEvent; import net.minestom.server.event.player.PlayerSpawnEvent; import net.minestom.server.instance.Instance; import net.minestom.server.instance.LightingChunk; @@ -23,6 +24,7 @@ public class TerraMinestomExample { private final MinecraftServer server = MinecraftServer.init(); private Instance instance; private TerraMinestomWorld world; + private final TerraMinestomPlatform platform = new TerraMinestomPlatform(); public void createNewInstance() { instance = MinecraftServer.getInstanceManager().createInstanceContainer(); @@ -30,9 +32,9 @@ public class TerraMinestomExample { } public void attachTerra() { - TerraMinestomPlatform platform = new TerraMinestomPlatform(); world = platform.worldBuilder(instance) .defaultPack() + .doFineGrainedBiomes(false) .attach(); } @@ -122,6 +124,7 @@ public class TerraMinestomExample { private void regenerate() { instance.sendMessage(Component.text("Regenerating world")); Instance oldInstance = instance; + platform.reload(); createNewInstance(); attachTerra(); preloadWorldAndMeasure(); diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/TerraMinestomWorldBuilder.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/TerraMinestomWorldBuilder.java index a3f3354d3..c572458b7 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/TerraMinestomWorldBuilder.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/TerraMinestomWorldBuilder.java @@ -24,6 +24,7 @@ public class TerraMinestomWorldBuilder { private EntityFactory entityFactory = new DefaultEntityFactory(); private BlockEntityFactory blockEntityFactory = new DefaultBlockEntityFactory(); private BiomeFactory biomeFactory = new MinestomUserDefinedBiomeFactory(); + private boolean doFineGrainedBiomes = true; public TerraMinestomWorldBuilder(TerraMinestomPlatform platform, Instance instance) { this.platform = platform; @@ -70,7 +71,20 @@ public class TerraMinestomWorldBuilder { return this; } + /** + * Due to a current bug with the minestom biome encoder, sometimes, the client gets kicked when decoding a chunk + * packet with more than one biome. Until this is fixed in minestom, one can disable fine-grained biomes to prevent + * this issue. + * + * @deprecated Scheduled for removal once Minestom rolls out a fix + */ + @Deprecated + public TerraMinestomWorldBuilder doFineGrainedBiomes(boolean doFineGrainedBiomes) { + this.doFineGrainedBiomes = doFineGrainedBiomes; + return this; + } + public TerraMinestomWorld attach() { - return new TerraMinestomWorld(platform, instance, pack, seed, entityFactory, blockEntityFactory, biomeFactory); + return new TerraMinestomWorld(platform, instance, pack, seed, entityFactory, blockEntityFactory, biomeFactory, doFineGrainedBiomes); } } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomUserDefinedBiomePool.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomUserDefinedBiomePool.java index 9eff185b3..138d98887 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomUserDefinedBiomePool.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/biome/MinestomUserDefinedBiomePool.java @@ -2,16 +2,17 @@ package com.dfsek.terra.minestom.biome; import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.world.biome.Biome; +import com.dfsek.terra.minestom.api.BiomeFactory; import java.util.HashMap; public class MinestomUserDefinedBiomePool { private final HashMap biomes = new HashMap<>(); - private final MinestomUserDefinedBiomeFactory factory; + private final BiomeFactory factory; private final ConfigPack configPack; - public MinestomUserDefinedBiomePool(ConfigPack configPack, MinestomUserDefinedBiomeFactory factory) { + public MinestomUserDefinedBiomePool(ConfigPack configPack, BiomeFactory factory) { this.configPack = configPack; this.factory = factory; } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java index 0e2109b99..6c72a3326 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/MinestomChunkGeneratorWrapper.java @@ -26,6 +26,7 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe private ChunkGenerator generator; private final TerraMinestomWorld world; private final BiomeProvider biomeProvider; + private final boolean doFineGrainedBiomes; private ConfigPack pack; private final MinestomUserDefinedBiomePool biomePool; @@ -34,13 +35,15 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe ChunkGenerator generator, TerraMinestomWorld world, ConfigPack pack, - MinestomUserDefinedBiomePool biomePool + MinestomUserDefinedBiomePool biomePool, + boolean doFineGrainedBiomes ) { this.generator = generator; this.world = world; this.pack = pack; this.biomePool = biomePool; - biomeProvider = pack.getBiomeProvider().caching(platform); + this.biomeProvider = pack.getBiomeProvider(); + this.doFineGrainedBiomes = doFineGrainedBiomes; this.cache = new GeneratedChunkCache(world.getDimensionType(), generator, world, biomeProvider); preloadBiomes(); } @@ -56,12 +59,28 @@ public class MinestomChunkGeneratorWrapper implements Generator, GeneratorWrappe int z = start.chunkZ(); int blockX = start.blockX(); int blockZ = start.blockZ(); + int minY = world.getMinHeight(); + int maxY = world.getMaxHeight(); CachedChunk chunk = cache.at(x, z); UnitModifier modifier = unit.modifier(); chunk.writeRelative(modifier); - UserDefinedBiome userDefinedBiome = biomePool.getBiome(biomeProvider.getBiome(blockX, 100, blockZ, world.getSeed())); - modifier.fillBiome(userDefinedBiome.registry()); + if(doFineGrainedBiomes) { + for(int y = minY; y < maxY; y++) { + for(int absoluteX = blockX; absoluteX < blockX + 16; absoluteX++) { + for(int absoluteZ = blockZ; absoluteZ < blockZ + 16; absoluteZ++) { + UserDefinedBiome userDefinedBiome = biomePool.getBiome( + biomeProvider.getBiome(absoluteX, y, absoluteZ, world.getSeed()) + ); + modifier.setBiome(absoluteX, y, absoluteZ, userDefinedBiome.registry()); + } + } + } + } else { + // TODO: remove with feature flag once minestom fixed biome encoding + UserDefinedBiome userDefinedBiome = biomePool.getBiome(biomeProvider.getBiome(blockX, 100, blockZ, world.getSeed())); + modifier.fillBiome(userDefinedBiome.registry()); + } unit.fork(setter -> { MinestomProtoWorld protoWorld = new MinestomProtoWorld(cache, x, z, world, setter); diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java index 88691e362..df38b5dd2 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/world/TerraMinestomWorld.java @@ -48,7 +48,8 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties { long seed, EntityFactory entityFactory, BlockEntityFactory blockEntityFactory, - BiomeFactory factory + BiomeFactory factory, + boolean doFineGrainedBiomes ) { this.instance = instance; this.pack = pack; @@ -62,7 +63,8 @@ public final class TerraMinestomWorld implements ServerWorld, WorldProperties { pack.getGeneratorProvider().newInstance(pack), this, pack, - new MinestomUserDefinedBiomePool(pack, new MinestomUserDefinedBiomeFactory()) + new MinestomUserDefinedBiomePool(pack, factory), + doFineGrainedBiomes ); this.entityFactory = entityFactory; From c08e973e3e24c24e2078691f4e9eb032d5d8bd15 Mon Sep 17 00:00:00 2001 From: Christian Bergschneider Date: Wed, 4 Jun 2025 21:34:04 +0200 Subject: [PATCH 17/18] feat: provide default MinestomBlockEntity implementation Introduce the `MinestomBlockEntity` class to represent block entities and hook into the block system. Update `DefaultBlockEntityFactory` to create `MinestomBlockEntity` instances and adjust `TerraMinestomWorldBuilder` initialization for factory injection. These changes improve extensibility and block entity management. --- .../minestom/api/BlockEntityFactory.java | 4 +- .../api/TerraMinestomWorldBuilder.java | 3 +- .../block/DefaultBlockEntityFactory.java | 9 ++- .../minestom/block/MinestomBlockEntity.java | 59 +++++++++++++++++++ 4 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/MinestomBlockEntity.java diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/BlockEntityFactory.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/BlockEntityFactory.java index c5fd33ca1..6ea403ddf 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/BlockEntityFactory.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/BlockEntityFactory.java @@ -8,8 +8,8 @@ import org.jetbrains.annotations.Nullable; /** * Represents a factory interface for creating instances of BlockEntity - * at a specified BlockVec position. This is not implemented directly because - * Minestom does not define a way to build block entities out of the box. + * at a specified BlockVec position. For more fine-grained control, users + * may supply their own version of this interface. */ public interface BlockEntityFactory { @Nullable BlockEntity createBlockEntity(BlockVec position); diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/TerraMinestomWorldBuilder.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/TerraMinestomWorldBuilder.java index c572458b7..30a04a172 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/TerraMinestomWorldBuilder.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/api/TerraMinestomWorldBuilder.java @@ -22,13 +22,14 @@ public class TerraMinestomWorldBuilder { private ConfigPack pack; private long seed = new Random().nextLong(); private EntityFactory entityFactory = new DefaultEntityFactory(); - private BlockEntityFactory blockEntityFactory = new DefaultBlockEntityFactory(); + private BlockEntityFactory blockEntityFactory; private BiomeFactory biomeFactory = new MinestomUserDefinedBiomeFactory(); private boolean doFineGrainedBiomes = true; public TerraMinestomWorldBuilder(TerraMinestomPlatform platform, Instance instance) { this.platform = platform; this.instance = instance; + this.blockEntityFactory = new DefaultBlockEntityFactory(instance); } public TerraMinestomWorldBuilder pack(ConfigPack pack) { diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/DefaultBlockEntityFactory.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/DefaultBlockEntityFactory.java index dbcbf2833..28712a4c0 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/DefaultBlockEntityFactory.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/DefaultBlockEntityFactory.java @@ -4,11 +4,18 @@ import com.dfsek.terra.api.block.entity.BlockEntity; import com.dfsek.terra.minestom.api.BlockEntityFactory; import net.minestom.server.coordinate.BlockVec; +import net.minestom.server.instance.Instance; public class DefaultBlockEntityFactory implements BlockEntityFactory { + private final Instance instance; + + public DefaultBlockEntityFactory(Instance instance) { + this.instance = instance; + } + @Override public BlockEntity createBlockEntity(BlockVec position) { - return null; + return new MinestomBlockEntity(instance, position); } } diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/MinestomBlockEntity.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/MinestomBlockEntity.java new file mode 100644 index 000000000..e96caf0d9 --- /dev/null +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/block/MinestomBlockEntity.java @@ -0,0 +1,59 @@ +package com.dfsek.terra.minestom.block; + +import com.dfsek.seismic.type.vector.Vector3; + +import com.dfsek.terra.api.block.entity.BlockEntity; + +import com.dfsek.terra.api.block.state.BlockState; + +import net.minestom.server.coordinate.BlockVec; +import net.minestom.server.instance.Instance; +import net.minestom.server.instance.block.Block; + + +public class MinestomBlockEntity implements BlockEntity { + private final Instance instance; + private final BlockVec position; + private final Vector3 positionVec; + + public MinestomBlockEntity(Instance instance, BlockVec position) { + this.instance = instance; + this.position = position; + this.positionVec = Vector3.of(position.blockX(), position.blockY(), position.blockZ()); + } + + @Override + public boolean update(boolean applyPhysics) { + return false; + } + + @Override + public Vector3 getPosition() { + return positionVec; + } + + @Override + public int getX() { + return position.blockX(); + } + + @Override + public int getY() { + return position.blockY(); + } + + @Override + public int getZ() { + return position.blockZ(); + } + + @Override + public BlockState getBlockState() { + return new MinestomBlockState(instance.getBlock(position)); + } + + @Override + public Block getHandle() { + return instance.getBlock(position); + } +} From a061660e460af86c921df5a848329f43c15bd613 Mon Sep 17 00:00:00 2001 From: Christian Bergschneider Date: Wed, 4 Jun 2025 21:52:46 +0200 Subject: [PATCH 18/18] chore: Update Minestom version to 1_21_5-4d91778331 This commit updates the Minestom dependency to the latest tagged version. Ensures compatibility with new features and fixes in the updated Minestom release. --- buildSrc/src/main/kotlin/Versions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 2ad818b61..10309b05b 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -87,6 +87,6 @@ object Versions { } object Minestom { - const val minestom = "187931e50b" + const val minestom = "1_21_5-4d91778331" } }