Jump to content

Recommended Posts

Posted

I want to create a block that changes chunk biome after player clicks on it. I've found some old tutorials (for Minecraft 1.10) on how to do this but when I tried to do the same, needed methods just aren't there anymore. Is it even possible on newer versions?
Thanks!

Posted (edited)

Thank you for your reply!
 

16 minutes ago, diesieben07 said:

However this might be null if the chunk is not fully generated yet - in that case Minecraft will fall back to simply using the world generation algorithm to find the biomes. If however it exists, you can use reflection to hack its internal biomes array. See BiomeContainer#getNoiseBiome to see how this array is used.

The block will be placed by a player, so, the chunk is generated. So, I need to create an access transformer to change biome array's signature from "private final" to "public", right?

18 minutes ago, diesieben07 said:

This however is the unzoomed biome. World#getBiomeManager applies an additional zoom on top of this.


What does it mean "unzoomed biome"? And how do I apply zoom with BiomeManager?

Edited by sasetz
Added quotes
Posted

Thank you for your replies!

8 hours ago, diesieben07 said:

Keep it final. But yes, you can AT it. But you could also use reflection.

I created an AT and checked what's inside of this array. Why is there 1024 Biome instances? Is it 4 instances for each block in a chunk or what? I inspected BiomeContainer#getNoiseBiome, but it didn't make much sense since I don't know what 3 int parameters supposed to mean (xyz? I thought biome stretches from y=0 to y=255. Maybe it's 16x16 and 4 layers vertically? idk)
I've tried changing stuff inside of the array (using BiomeMaker methods) but after I did that, when I checked again the array and the registry names of biomes inside are all null. After I restart the world it turns back to normal (minecraft:plains or more)

9 hours ago, diesieben07 said:

See BiomeManager#getBiome(BlockPos).

So I need to call this method on every block inside of chunk, so it gets zoomed? I don't think it's what you meant though...

Posted

Thanks for you reply!

1 hour ago, diesieben07 said:

So if you want to change the biome at a certain x, y, z coord, you have to use the zoomer as well (but in reverse) before accessing the biomes array.

Ok, I've figured it out that chunk is divided to cubes with 4 blocks side and each of the cubes has it's own biome. But still, I want to change biome in the whole chunk, so I change every element of the array to another biome and it doesn't change (registry name says it's null biome), and the changes don't save (when I reload the world, biomes are back to normal)

Posted
12 minutes ago, diesieben07 said:

Show your code.

if(!level.isClientSide()){
    Biome[] biomes = level.getChunkAt(worldPosition).getBiomes().biomes;
    sendToChat(BiomeMaker.desertBiome(.125f, .05f, false, false, false).toString());
    for (int i = 0, biomesLength = biomes.length; i < biomesLength; i++) {
        biomes[i] = BiomeMaker.desertBiome(.125f, .05f, false, false, false);
        sendToChat("" + i + ": " + biomes[i].getRegistryName());
    }
}

This is a piece of code is called when I right click on a block, it's inside of a TileEntity

Posted
5 minutes ago, diesieben07 said:

What does this method do?

It's method that returns Biome, there's a bunch of those for each biome inside BiomeMaker class

Posted
Just now, diesieben07 said:

Oh... well that would explain it then.

You can't create a new biome. You have to use the desert biome from the world's dynamic registries.

I've tried this, but how do I turn RegistryKey to Biome?

Posted
7 minutes ago, diesieben07 said:

World#registryAccess gives you the DynamicRegistries. From there you can get the biome registry and then look up the biomes.

And then what field or method should I call? I just couldn't find anything suitable

Posted
32 minutes ago, diesieben07 said:

DynamicRegistries#registry with the RegistryKey for biomes (Registry.BIOME_REGISTRY). Then you have the biome registry. Then Registry#get.

Now it's doing a NullPointerException... 
I just did this

level.registryAccess().registry(Registry.BIOME_REGISTRY).get().get(Biomes.DESERT.getRegistryName()).toString()

The second get method returns null

Posted
14 minutes ago, diesieben07 said:

Hm, that is curious. Use the debugger to see what the registry contains.

For some reason the code Biomes.DESERT.getRegistryName().toString() returns "minecraft:worldgen/biome"...
 

Posted (edited)

Instead of getting the desert biome I just typed new ResourceLocation("minecraft:desert") and it finally worked!

The final code is

public void changeBiome() {
    Biome[] biomes = level.getChunkAt(worldPosition).getBiomes().biomes;
    for (int i = 0, biomesLength = biomes.length; i < biomesLength; i++) {
        DynamicRegistries reg = level.registryAccess();
        MutableRegistry<Biome> a = reg.registry(Registry.BIOME_REGISTRY).get();
        Biome biome = a.get(new ResourceLocation("minecraft:desert"));
        biomes[i] = biome;
    }
}

 

But the only thing left is that the grass color doesn't change instantly, but when I click F3 + A (only if I click the combination twice) it looks how it should be (grass changes from plains green to yellow)
If I hit F3 + A only 1 time, the borders between biomes become sharp between the chunks
https://imgur.com/a/9qNBhxS (screenshot)

Is there a way to reload a chunk like F3 + A does?
And thank you for all of your replies!

Edited by sasetz
updated code
Posted
23 minutes ago, diesieben07 said:

Biomes.DESERT is a registry key. Calling getRegistryName gives you the name of the registry. RegistryKey#location gives you the name of the biome.

Biomes.DESERT.location() returns the correct ResourceLocation (minecraft:desert)

1 hour ago, diesieben07 said:

1) the client doesn't know that the biome has changed

No, the client knows about the biome change, since this method fires on both sides. If it works only on server side, the client needs to revisit a chunk, F3 + A is not enough

2 hours ago, diesieben07 said:

2) that the client doesn't re-render the chunk

Yes, that's basically what I need. Is SChunkDataPacket going to fix this issue? If so, how can I send this vanilla packet?

Posted
15 minutes ago, diesieben07 said:

You should really only do this server side if you can help it and then update the clients using the packet.

Ok, that makes sense

15 minutes ago, diesieben07 said:

Yes, but it's the brute-force approach because it re-sends the entire chunk data.

I understand that and still, how do I send this packet? I found info only about custom packets, not the vanilla ones

Posted

Thank you for your replies!

3 hours ago, diesieben07 said:

Look at what PacketDistributor#trackingChunk does.

I've done the same thing that this method does, but the problem on screenshot (https://imgur.com/a/9qNBhxS) remains. Sometimes everything changes ok but the rest of the times the result is the same as in the screenshot. Breaking/placing block inside the chunk fixes the problem

    public void changeBiome() {
        if(!level.isClientSide()){
            // Now this piece of code runs only on server side
            final Chunk chunk = level.getChunkAt(worldPosition);
            Biome[] biomes = chunk.getBiomes().biomes;
            for (int i = 0, biomesLength = biomes.length; i < biomesLength; i++) {
                DynamicRegistries reg = level.registryAccess();
                MutableRegistry<Biome> a = reg.registry(Registry.BIOME_REGISTRY).get();
                Biome biome = a.get(Biomes.DESERT.location());
                biomes[i] = biome;
            }
            // This line does basically the same that PacketDistributor#trackingChunk does
            ((ServerChunkProvider)level.getChunkSource()).chunkMap.getPlayers(chunk.getPos(), false)
                    .forEach(e -> e.connection.send(new SChunkDataPacket(chunk, 65535)));
        }
        else {
            // Update chunk?
        }
    }

I guess that the only thing remains is to update the chunk on client, how can I do that?

Posted
26 minutes ago, diesieben07 said:

I am sorry, but I don't know why it doesn't work. The client receives the chunk data packet and ithas the correct biomes in it. It then decides to re-render the chunk. I don't know why it renders with the wrong colors.

Well, still, thank you for your help! I will continue searching for what's happening, so if I find something, I'll post it here

So far I figured out that the update doesn't affect the whole chunk, several layers of grass or leaves can be different colors at the same time

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hello, i've tried to make a minecraft server for my friends on old laptop. But im getting this error   ---- Minecraft Crash Report ---- WARNING: coremods are present:   DCLoadingPlugin (DummyCoreUnofficial-2.4.112.3.jar)   HCASM (HammerLib-1.12.2-2.0.6.23.jar) Contact their authors BEFORE contacting forge // I feel sad now Time: 19.06.25 22:26 Description: Exception in server tick loop java.lang.NoClassDefFoundError: net/minecraft/client/Minecraft     at nukeduck.armorchroma.ArmorChroma.<clinit>(ArmorChroma.java:23)     at java.lang.Class.forName0(Native Method)     at java.lang.Class.forName(Class.java:348)     at net.minecraftforge.fml.common.FMLModContainer.constructMod(FMLModContainer.java:539)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     at java.lang.reflect.Method.invoke(Method.java:498)     at com.google.common.eventbus.Subscriber.invokeSubscriberMethod(Subscriber.java:91)     at com.google.common.eventbus.Subscriber$SynchronizedSubscriber.invokeSubscriberMethod(Subscriber.java:150)     at com.google.common.eventbus.Subscriber$1.run(Subscriber.java:76)     at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:399)     at com.google.common.eventbus.Subscriber.dispatchEvent(Subscriber.java:71)     at com.google.common.eventbus.Dispatcher$PerThreadQueuedDispatcher.dispatch(Dispatcher.java:116)     at com.google.common.eventbus.EventBus.post(EventBus.java:217)     at net.minecraftforge.fml.common.LoadController.sendEventToModContainer(LoadController.java:219)     at net.minecraftforge.fml.common.LoadController.propogateStateMessage(LoadController.java:197)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     at java.lang.reflect.Method.invoke(Method.java:498)     at com.google.common.eventbus.Subscriber.invokeSubscriberMethod(Subscriber.java:91)     at com.google.common.eventbus.Subscriber$SynchronizedSubscriber.invokeSubscriberMethod(Subscriber.java:150)     at com.google.common.eventbus.Subscriber$1.run(Subscriber.java:76)     at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:399)     at com.google.common.eventbus.Subscriber.dispatchEvent(Subscriber.java:71)     at com.google.common.eventbus.Dispatcher$PerThreadQueuedDispatcher.dispatch(Dispatcher.java:116)     at com.google.common.eventbus.EventBus.post(EventBus.java:217)     at net.minecraftforge.fml.common.LoadController.distributeStateMessage(LoadController.java:136)     at net.minecraftforge.fml.common.Loader.loadMods(Loader.java:595)     at net.minecraftforge.fml.server.FMLServerHandler.beginServerLoading(FMLServerHandler.java:98)     at net.minecraftforge.fml.common.FMLCommonHandler.onServerStart(FMLCommonHandler.java:333)     at net.minecraft.server.dedicated.DedicatedServer.func_71197_b(DedicatedServer.java:125)     at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:486)     at java.lang.Thread.run(Thread.java:750) Caused by: java.lang.ClassNotFoundException: net.minecraft.client.Minecraft     at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:191)     at java.lang.ClassLoader.loadClass(ClassLoader.java:418)     at java.lang.ClassLoader.loadClass(ClassLoader.java:351)     ... 35 more Caused by: net.minecraftforge.fml.common.asm.ASMTransformerWrapper$TransformerException: Exception in class transformer net.minecraftforge.fml.common.asm.transformers.SideTransformer@57fae983 from coremod FMLCorePlugin     at net.minecraftforge.fml.common.asm.ASMTransformerWrapper$TransformerWrapper.transform(ASMTransformerWrapper.java:260)     at net.minecraft.launchwrapper.LaunchClassLoader.runTransformers(LaunchClassLoader.java:279)     at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:176)     ... 37 more Caused by: java.lang.RuntimeException: Attempted to load class bib for invalid side SERVER     at net.minecraftforge.fml.common.asm.transformers.SideTransformer.transform(SideTransformer.java:62)     at net.minecraftforge.fml.common.asm.ASMTransformerWrapper$TransformerWrapper.transform(ASMTransformerWrapper.java:256)     ... 39 more A detailed walkthrough of the error, its code path and all known details is as follows: --------------------------------------------------------------------------------------- -- System Details -- Details:     Minecraft Version: 1.12.2     Operating System: Linux (amd64) version 6.8.0-51-generic     Java Version: 1.8.0_452, Private Build     Java VM Version: OpenJDK 64-Bit Server VM (mixed mode), Private Build     Memory: 1088926088 bytes (1038 MB) / 1634205696 bytes (1558 MB) up to 4194304000 bytes (4000 MB)     JVM Flags: 2 total; -Xms1024M -Xmx4500M     IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0     FML: MCP 9.42 Powered by Forge 14.23.5.2859 44 mods loaded, 44 mods active     States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored     | State | ID                       | Version            | Source                                        | Signature                                |     |:----- |:------------------------ |:------------------ |:--------------------------------------------- |:---------------------------------------- |     | LC    | minecraft                | 1.12.2             | minecraft.jar                                 | None                                     |     | LC    | mcp                      | 9.42               | minecraft.jar                                 | None                                     |     | LC    | FML                      | 8.0.99.99          | forge-1.12.2-14.23.5.2859.jar                 | e3c3d50c7c986df74c645c0ac54639741c90a557 |     | LC    | forge                    | 14.23.5.2859       | forge-1.12.2-14.23.5.2859.jar                 | e3c3d50c7c986df74c645c0ac54639741c90a557 |     | LC    | codechickenlib           | 3.2.3.358          | CodeChickenLib-1.12.2-3.2.3.358-universal.jar | f1850c39b2516232a2108a7bd84d1cb5df93b261 |     | LC    | ancientwarfare           | 1.12.2-2.7.0.1032  | ancientwarfare-1.12.2-2.7.0.1032.jar          | None                                     |     | LC    | ancientwarfareautomation | 1.12.2-2.7.0.1032  | ancientwarfare-1.12.2-2.7.0.1032.jar          | None                                     |     | LC    | ancientwarfarenpc        | 1.12.2-2.7.0.1032  | ancientwarfare-1.12.2-2.7.0.1032.jar          | None                                     |     | LC    | ancientwarfarestructure  | 1.12.2-2.7.0.1032  | ancientwarfare-1.12.2-2.7.0.1032.jar          | None                                     |     | LC    | ancientwarfarevehicle    | 1.12.2-2.7.0.1032  | ancientwarfare-1.12.2-2.7.0.1032.jar          | None                                     |     | L     | armorchroma              | 1.4-beta           | armorchroma-1.12.2-1.4.jar                    | None                                     |     | L     | baubles                  | 1.5.2              | Baubles-1.12-1.5.2.jar                        | None                                     |     | L     | betterburning            | 0.9.2              | BetterBurning-1.12.2-0.9.2.jar                | None                                     |     | L     | bettercaves              | 1.12.2             | bettercaves-1.12.2-2.0.4.jar                  | None                                     |     | L     | betterinvisibility       | 1.0.1              | betterinvisibility-1.0.1.jar                  | None                                     |     | L     | bettermineshafts         | 1.12.2-2.2         | BetterMineshaftsForge-1.12.2-2.2.jar          | None                                     |     | L     | bookshelf                | 2.3.590            | Bookshelf-1.12.2-2.3.590.jar                  | None                                     |     | L     | collective               | 2.11               | collective-1.12.2-2.11.jar                    | None                                     |     | L     | extendedrenderer         | v1.0               | coroutil-1.12.1-1.2.37.jar                    | None                                     |     | L     | coroutil                 | 1.12.1-1.2.37      | coroutil-1.12.1-1.2.37.jar                    | None                                     |     | L     | configmod                | v1.0               | coroutil-1.12.1-1.2.37.jar                    | None                                     |     | L     | dummycore                | 2.4.112.3.         | DummyCoreUnofficial-2.4.112.3.jar             | None                                     |     | L     | dynamictrees             | 1.12.2-0.9.22      | DynamicTrees-1.12.2-0.9.22.jar                | None                                     |     | L     | thaumcraft               | 6.1.BETA26         | Thaumcraft_1.12.2_6.1.BETA26.jar              | None                                     |     | L     | dynamictreestc           | 1.12.2-1.4.2       | DynamicTreesTC-1.12.2-1.4.2.jar               | None                                     |     | L     | hammercore               | 2.0.6.23           | HammerLib-1.12.2-2.0.6.23.jar                 | None                                     |     | L     | waila                    | 1.8.26             | Hwyla-1.8.26-B41_1.12.2.jar                   | None                                     |     | L     | jei                      | 4.16.1.302         | jei_1.12.2-4.16.1.302.jar                     | None                                     |     | L     | keepinginventory         | 2.4                | KeepingInventory-1.12.2-2.4.jar               | None                                     |     | L     | libraryex                | 1.2.1              | LibraryEx-1.12.2-1.2.1.jar                    | None                                     |     | L     | netherex                 | 2.2.4              | NetherEx-1.12.2-2.2.4.jar                     | None                                     |     | L     | recipehandler            | 0.13               | NoMoreRecipeConflict-0.13(1.12.2).jar         | None                                     |     | L     | nei                      | 2.4.3              | NotEnoughItems-1.12.2-2.4.3.245-universal.jar | None                                     |     | L     | thaumadditions           | 12.6.6             | ThaumicAdditions-1.12.2-12.6.6.jar            | None                                     |     | L     | thaumicbases             | 3.3.500.6r         | thaumicbases-3.3.500.6r.jar                   | None                                     |     | L     | thaumictinkerer          | 1.12.2-5.0-620a0c5 | thaumictinkerer-1.12.2-5.0-620a0c5.jar        | None                                     |     | L     | thaumicwaila             | 1.12.2-0.0.2       | ThaumicWaila-1.12.2-0.0.2.jar                 | None                                     |     | L     | tumbleweed               | 1.12-0.4.7         | tumbleweed-1.12-0.4.7.jar                     | None                                     |     | L     | villagespawnpoint        | 1.5                | villagespawnpoint_1.12.2-1.5.jar              | None                                     |     | L     | wawla                    | 2.6.275            | Wawla-1.12.2-2.6.275.jar                      | None                                     |     | L     | wooltostring             | 1.12.2             | WoolToString-1.12.2-1.0.0.jar                 | None                                     |     | L     | zombieawareness          | 1.12.1-1.11.16     | zombieawareness-1.12.1-1.11.16.jar            | None                                     |     | L     | betteranimalsplus        | 9.0.1              | betteranimalsplus-1.12.2-9.0.1.jar            | None                                     |     | L     | orelib                   | 3.6.0.1            | OreLib-1.12.2-3.6.0.1.jar                     | None                                     |     Loaded coremods (and transformers):  DCLoadingPlugin (DummyCoreUnofficial-2.4.112.3.jar)   DummyCore.ASM.DCASMManager HCASM (HammerLib-1.12.2-2.0.6.23.jar)   com.zeitheron.hammercore.asm.HammerCoreTransformer     Profiler Position: N/A (disabled)     Is Modded: Definitely; Server brand changed to 'fml,forge'     Type: Dedicated Server (map_server.txt)
    • Hey! I noticed you're trying to register your alexandrite item and possibly set its resource location manually with setId(...). I wanted to help clarify a few things that might simplify your code and avoid errors. ✅ The issue: You're using setId(...) inside the item registration like this:   public static final RegistryObject<Item> ALEXANDRITE = ITEMS.register("alexandrite", () -> new Item(new Item.Properties().useItemDescriptionPrefix() .setId(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(TutorialMod.MOD_ID, "alexandrite"))))); But: Item.Properties does not have a setId(...) method — this line will either fail or do nothing meaningful. useItemDescriptionPrefix() is mostly used for translation keys (like "item.modid.name") but isn't needed unless you have a very specific reason. 🛠 The fix: You only need to register your item like this:   public static final RegistryObject<Item> ALEXANDRITE = ITEMS.register("alexandrite", () -> new Item(new Item.Properties())); Forge automatically handles the ResourceLocation (modid:alexandrite) based on the name passed into .register(...), so there’s no need to manually assign it. 📝 For the texture: Make sure you have this file in your resources: src/main/resources/assets/tutorialmod/models/item/alexandrite.json { "parent": "item/generated", "textures": { "layer0": "tutorialmod:item/alexandrite" } } And your texture PNG goes here: src/main/resources/assets/tutorialmod/textures/item/alexandrite.png 🌍 For the name in-game: Add this to your en_us.json under: src/main/resources/assets/tutorialmod/lang/en_us.json { "item.tutorialmod.alexandrite": "Alexandrite" }   Note: if im wrong about the issues you are encountering, i apologize.
    • 🛠️ Fix for Transparent or Clipping Item Render Issues When Held in First Person (Forge 1.20+) Hey everyone! I recently ran into a frustrating bug while making a custom item (a rocket) for my Forge mod, and I’m sharing the fix because it’s a bit obscure — and it worked wonders. 💥 The Problem: My item rendered semi-transparent and see-through — but only in first person. It also clipped through nearby blocks when held, unlike default items like swords or leads. The texture file was confirmed to be fully opaque (alpha 255), so the issue wasn’t the PNG itself. Interestingly, when no texture was present and the default purple-black checkerboard appeared, the clipping issue disappeared. ✅ The Fix: I ended up resolving it by randomly trying something I found on a Forge forum post about block rendering. I added this property to my item's model JSON — even though it's typically only used for blocks: { "parent": "item/generated", "textures": { "layer0": "farbeyond:item/rocket_item" }, "render_type": "minecraft:cutout" } Boom. That single line forced the item to render using a proper opaque (cutout) layer, removing all the unwanted transparency and clipping behavior in first person. 🙌 Credit: I originally found the "render_type" trick mentioned here, in a block rendering context: 👉 https://forums.minecraftforge.net/topic/149644-1201-help-with-transparent-blocks/ Even though it was meant for blocks, I thought, why not try it on an item? And it worked! Big thanks to the poster — this fix wouldn’t have happened without that tip. Hopefully this helps anyone else stuck on a weird rendering bug like I was. This isn’t a common item solution, so feel free to share it further. I’d love to know if it works for you too.
    • Use Java 21 instead of Java 24   Also make a test without modernfix
    • Ive been on this world for 2 days now, my computer blue screens pretty often so maybe that has something to do with it. maybe just incompatible mods like a lot of people so im hoping someone more knowledgeable can help me find what i need to get rid of. thank you! paste bin
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.