Jump to content

nanorover59

Members
  • Posts

    21
  • Joined

  • Last visited

Everything posted by nanorover59

  1. I am currently working on an entirely server side mod that adds a new world type with its own unique chunk generator. So far the chunk generator works as expected when I load a world for the first time, but if I load the world after closing it, all new chunks are generated with the default overworld chunk generator. In addition, loading these worlds for a second time results in the experimental settings warning screen being displayed. I am not sure what is causing this behavior, but I suspect it has something to do with my chunk generator's codec (which I still do not fully understand the functionality of) due to this error that I get when loading a world for the first time: [23:22:20] [Render thread/ERROR] [minecraft/Minecraft]: Error reading worldgen settings after loading data packs: Unknown registry element RegistryLookupCodec[ResourceKey[minecraft:root / minecraft:worldgen/biome]][xmapped] [23:22:20] [Render thread/ERROR] [minecraft/ServerWorldInfo]: WorldGenSettings: Unknown registry element RegistryLookupCodec[ResourceKey[minecraft:root / minecraft:worldgen/biome]][xmapped] Here is my chunk provider class: package planetoids.world; import java.util.ArrayList; import com.mojang.serialization.Codec; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.RegistryLookupCodec; import net.minecraft.world.Blockreader; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorld; import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biomes; import net.minecraft.world.biome.provider.SingleBiomeProvider; import net.minecraft.world.chunk.IChunk; import net.minecraft.world.gen.ChunkGenerator; import net.minecraft.world.gen.Heightmap; import net.minecraft.world.gen.WorldGenRegion; import net.minecraft.world.gen.feature.structure.StructureManager; import net.minecraft.world.gen.settings.DimensionStructuresSettings; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import planetoids.util.Planetoid; import planetoids.util.PlanetoidsHandler; import planetoids.util.PlanetoidsUtil; public class PlanetoidsChunkGenerator extends ChunkGenerator { public static final Codec<PlanetoidsChunkGenerator> codec = RegistryLookupCodec.getLookUpCodec(Registry.BIOME_KEY).xmap(PlanetoidsChunkGenerator::new, PlanetoidsChunkGenerator::getMainBiome).stable().codec(); private final Registry<Biome> mainBiome; public PlanetoidsChunkGenerator(Registry<Biome> biome) { super(new SingleBiomeProvider(biome.getOrThrow(Biomes.THE_VOID)), new DimensionStructuresSettings(false)); mainBiome = biome; } public Registry<Biome> getMainBiome() { return this.mainBiome; } protected Codec<? extends ChunkGenerator> func_230347_a_() { return codec; } @OnlyIn(Dist.CLIENT) public ChunkGenerator func_230349_a_(long p_230349_1_) { return this; } public void generateSurface(WorldGenRegion p_225551_1_, IChunk p_225551_2_) { } public int getGroundHeight() { return 0; } /** * Generate the blocks in a chunk. */ public void func_230352_b_(IWorld world, StructureManager structureManager, IChunk chunk) { BlockPos.Mutable blockPos = new BlockPos.Mutable(); int chunkWorldX = chunk.getPos().getXStart(); int chunkWorldZ = chunk.getPos().getZStart(); if(chunkWorldX == 0 && chunkWorldZ == 0) { PlanetoidsHandler.getInstance().generateFirstSolarSystem(); } ArrayList<Planetoid> toGenerate = new ArrayList<Planetoid>(); for(Planetoid p : PlanetoidsHandler.getInstance().unloadedPlanetoids) { if(Math.sqrt(Math.pow(p.getPosition().x - chunkWorldX, 2) + Math.pow(p.getPosition().z - chunkWorldZ, 2)) < p.getRadius() * 4) toGenerate.add(p); } for(Planetoid p : PlanetoidsHandler.getInstance().loadedPlanetoids) { if(Math.sqrt(Math.pow(p.getPosition().x - chunkWorldX, 2) + Math.pow(p.getPosition().z - chunkWorldZ, 2)) < p.getRadius() * 4) toGenerate.add(p); } for(Planetoid p : toGenerate) { for(int i = 0; i < 256; i++) { if(Math.abs(i - p.getPosition().y) > p.getRadius()) continue; for(int j = 0; j < 16; j++) { for(int k = 0; k < 16; k++) { Vector3d v = new Vector3d(chunkWorldX + j, i, chunkWorldZ + k); if(PlanetoidsUtil.getDistance(p.getPosition(), v) < p.getRadius()) chunk.setBlockState(blockPos.setPos(j, i, k), p.getBlock(v), false); } } } } } public int getHeight(int x, int z, Heightmap.Type heightmapType) { return 0; } public IBlockReader func_230348_a_(int p_230348_1_, int p_230348_2_) { return new Blockreader(new BlockState[0]); } } Edit: Once again I underestimated my ability to solve this kind of problem. It turns out I just needed to rewrite the codec definition and then register it in my main mod file. Registry.register(Registry.CHUNK_GENERATOR_CODEC, new ResourceLocation(MOD_ID, "chunk_generator"), PlanetoidsChunkGenerator.CODEC);
  2. Update: I found out how to do this. /** * Return a registered biome using its resource location name. */ public static Biome getBiomeFromName(String name) { return ForgeRegistries.BIOMES.getValue(new ResourceLocation(name)); }
  3. Hello! 1.15.2 appears to be supported for now. I can confirm that tile entities in generated structures should populated with items using loot tables (.json files included in vanilla Minecraft and mods). However, I am unsure how a mod could be blocking data from other mod's loot tables. As you already expect, my recommendation is that you try leaving out mods that involve generated structures and loot one at a time.
  4. Hello, it has been a while since I last posted here for help. I am currently trying to get an instance of a vanilla biome from the Forge registry. However, I am getting the error "Registry Object not present". Can someone tell me what I am doing incorrectly here? Code: (assume the string "name" is set to "minecraft:the_void" for testing purposes. The output log indicates this biome is entered into the Forge registry.) /** * Return a registered biome using its resource location name. */ public static Biome getBiomeFromName(String name) { RegistryObject<Biome> biome = RegistryObject.of(new ResourceLocation(name), ForgeRegistries.BIOMES); return biome.get(); } Error: [23:28:06] [Server thread/ERROR] [ne.mi.ev.EventBus/EVENTBUS]: Exception caught during firing event: Registry Object not present: minecraft:the_void Index: 1 Listeners: 0: NORMAL 1: ASM: class planetoids.event.WorldEvents onWorldLoaded(Lnet/minecraftforge/event/world/WorldEvent$Load;)V java.lang.NullPointerException: Registry Object not present: minecraft:the_void at java.base/java.util.Objects.requireNonNull(Objects.java:348) at net.minecraftforge.fml.RegistryObject.get(RegistryObject.java:120) at planetoids.PlanetoidsUtil.getBiomeFromName(PlanetoidsUtil.java:25) at planetoids.PlanetoidType.<init>(PlanetoidType.java:31) at planetoids.PlanetoidType.initPlanetoidTypes(PlanetoidType.java:43) at planetoids.event.WorldEvents.onWorldLoaded(WorldEvents.java:24) at net.minecraftforge.eventbus.ASMEventHandler_1_WorldEvents_onWorldLoaded_Load.invoke(.dynamic) at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:85) at net.minecraftforge.eventbus.EventBus.post(EventBus.java:297) at net.minecraft.server.MinecraftServer.func_240787_a_(MinecraftServer.java:386) at net.minecraft.server.MinecraftServer.func_240800_l__(MinecraftServer.java:315) at net.minecraft.server.integrated.IntegratedServer.init(IntegratedServer.java:63) at net.minecraft.server.MinecraftServer.func_240802_v_(MinecraftServer.java:642) at net.minecraft.server.MinecraftServer.lambda$startServer$0(MinecraftServer.java:233) at java.base/java.lang.Thread.run(Thread.java:832) [23:28:06] [Server thread/ERROR] [minecraft/MinecraftServer]: Encountered an unexpected exception java.lang.NullPointerException: Registry Object not present: minecraft:the_void at java.util.Objects.requireNonNull(Objects.java:348) ~[?:?] {} at net.minecraftforge.fml.RegistryObject.get(RegistryObject.java:120) ~[forge-1.16.4-35.1.15_mapped_snapshot_20201028-1.16.3-recomp.jar:?] {re:classloading} at planetoids.PlanetoidsUtil.getBiomeFromName(PlanetoidsUtil.java:25) ~[main/:?] {re:classloading} at planetoids.PlanetoidType.<init>(PlanetoidType.java:31) ~[main/:?] {re:classloading} at planetoids.PlanetoidType.initPlanetoidTypes(PlanetoidType.java:43) ~[main/:?] {re:classloading} at planetoids.event.WorldEvents.onWorldLoaded(WorldEvents.java:24) ~[main/:?] {re:classloading} at net.minecraftforge.eventbus.ASMEventHandler_1_WorldEvents_onWorldLoaded_Load.invoke(.dynamic) ~[?:?] {} at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:85) ~[eventbus-3.0.5-service.jar:?] {} at net.minecraftforge.eventbus.EventBus.post(EventBus.java:297) ~[eventbus-3.0.5-service.jar:?] {} at net.minecraft.server.MinecraftServer.func_240787_a_(MinecraftServer.java:386) ~[forge:?] {re:classloading,pl:accesstransformer:B} at net.minecraft.server.MinecraftServer.func_240800_l__(MinecraftServer.java:315) ~[forge:?] {re:classloading,pl:accesstransformer:B} at net.minecraft.server.integrated.IntegratedServer.init(IntegratedServer.java:63) ~[forge:?] {re:classloading,pl:runtimedistcleaner:A} at net.minecraft.server.MinecraftServer.func_240802_v_(MinecraftServer.java:642) ~[forge:?] {re:classloading,pl:accesstransformer:B} at net.minecraft.server.MinecraftServer.lambda$startServer$0(MinecraftServer.java:233) ~[forge:?] {re:classloading,pl:accesstransformer:B} at java.lang.Thread.run(Thread.java:832) [?:?] {} [23:28:06] [Server thread/FATAL] [ne.mi.co.ForgeMod/]: Preparing crash report with UUID adb0f1bf-a81e-40a9-aeda-4bf55a6b0029
  5. The render code iterates through all of the layers to render blocks. I should also note that there have been no problems rendering translucent blocks that are part of sub-worlds, the problem is translucent blocks in the main world blocking sub-worlds from rendering. If there was an event very similar to RenderWorldLastEvent except it is called before renderBlockLayer (essentially a "RenderWorldFirstEvent") I would use that instead. After looking at the vanilla render code, I have not found any events that would allow me to run my render code before renderBlockLayer.
  6. Hello! While working on a mod that renders some blocks in the world using a render class called by a RenderWorldLastEvent (my "sub-world" project), I noticed that the objects I am rendering are not visible behind semi-transparent blocks. These include stained glass, water, nether portal blocks, etc... but not blocks with full transparency like regular glass blocks. My render code (posted below) does not activate or deactivate any effects to do with transparency, and I am wondering if that is what I need to add to make this work properly. Here is a screenshot of the rendering problem:
  7. It's been a while, but I am posting to say that tile entity rendering works fine now! It was was an issue with the vanilla TileEntityRendererDispatcher checking the distance between a tile entity's block position (in a sub-world) and the location of the player (in the main world).
  8. The sub-worlds already work by storing their contents in dimensions that are inaccessible to players. I did some research on how to use vanilla chunk renders to draw all of the blocks in those dimensions in the main world, but concluded it would be less work to create a new (non-chunk dependent) system for rendering the blocks. Although I could still try using vanilla style chunk rendering in the future, it shouldn't be necessary because for my purposes the sub-worlds are highly unlikely to contain anything that occupies more than several chunks. After recent testing I found that my render code posted yesterday can in fact render tile entities, but only on a super flat world of the void preset. This likely rules out a render buffer issue.
  9. I needed to be able to get an individual dimension's world instance from the client and that (quite surprisingly looking back now) worked. Although it may not work if the player is on a dedicated server, so I should look for a replacement later. (Edit: A quick search has lead me to the conclusion that I have made a huge mistake by referencing the world this way, and might have even caused the code I posted to not be taken seriously. Finding a replacement is now a high priority.) From what I have tested, the render code can render normal blocks and also detect tile entities in sub-worlds. The issue is actually rendering the tile entities.
  10. Only one line of error from a log usually isn't enough to find out what went wrong. You should post at least enough of the crash report that all lines about the error are visible. I also don't think this topic should be under "modder support" if what you are doing is setting up a server.
  11. As a sort of follow up to a past topic, I am working on a render class for mobile "sub-worlds" that is initially called from a RenderWorldLastEvent and involves rendering many blocks in the world. Because some blocks use a tile entity render instead of a normal block model, my next step is to be able to render tile entities in the world. However, the code I currently have is not able to render tile entities at all. I suspect it has something to do with the render type buffer I am trying to use. Here are the RenderWorldLastEvent and render classes:
  12. Thanks for pointing that out. I moved directly from 1.12.2 to 1.15.2 and somehow didn't find out that the rendering changes were as recent as 1.15.
  13. You should definitely be using one entity per ship (or perhaps some completely custom non-entity object). I admittedly made a system a few years ago using multiple entities per ship that just barely worked well enough for game play, and I was regularly finding and fixing problems. As someone who is currently working on a completely new mobile ship system, I recommend researching how to render blocks using the MatrixStack and IRenderTypeBuffer classes. (For some reason I assumed those were introduced before 1.15) If you want a more advanced system that performs block and tile entity updates on ships, then you should consider creating a dimension for each one to store its contents and find a way to keep a few chunks in in each dimension loaded.
  14. I was able to fix that final issue with lighting by iterating through all of the block render types. The "block" now looks exactly like a normal obsidian block in the world! From past experience, tile entities should be somewhat simpler to render because of their dedicated rendering functions that can be invoked. For anyone curious about rendering blocks this way, here is the final client event handler code: @Mod.EventBusSubscriber(Dist.CLIENT) public class ClientEvents { @SuppressWarnings({ "resource" }) @SubscribeEvent public static void renderWorldLastEvent(RenderWorldLastEvent event) { if(event.getPhase() != EventPriority.NORMAL) return; // Get instances of the classes required for a block render. MinecraftServer server = Minecraft.getInstance().getIntegratedServer(); World world = DimensionManager.getWorld(server, DimensionType.OVERWORLD, false, true); MatrixStack matrixStack = event.getMatrixStack(); // Get the projected view coordinates. Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView(); // Choose obsidian as the arbitrary block. BlockState blockState = Blocks.OBSIDIAN.getDefaultState(); // Begin rendering the block. Impl renderTypeBuffer = IRenderTypeBuffer.getImpl(Tessellator.getInstance().getBuffer()); renderBlock(matrixStack, renderTypeBuffer, world, blockState, new BlockPos(0, 128, 0), projectedView, new Vec3d(0.0, 128.0, 0.0)); renderTypeBuffer.finish(); } @SuppressWarnings("deprecation") public static void renderBlock(MatrixStack matrixStack, Impl renderTypeBuffer, World world, BlockState blockState, BlockPos logicPos, Vec3d projectedView, Vec3d renderCoordinates) { BlockRendererDispatcher blockRendererDispatcher = Minecraft.getInstance().getBlockRendererDispatcher(); int i = OverlayTexture.NO_OVERLAY; matrixStack.push(); matrixStack.translate(-projectedView.x + renderCoordinates.x, -projectedView.y + renderCoordinates.y, -projectedView.z + renderCoordinates.z); for(RenderType renderType : RenderType.getBlockRenderTypes()) { if(RenderTypeLookup.canRenderInLayer(blockState, renderType)) blockRendererDispatcher.getBlockModelRenderer().renderModel(world, blockRendererDispatcher.getModelForState(blockState), blockState, logicPos, matrixStack, renderTypeBuffer.getBuffer(renderType), true, new Random(), blockState.getPositionRandom(logicPos), i); } matrixStack.pop(); } } Thanks for all of the support on this somewhat complex topic!
  15. I tried the other way of getting view point coordinates and it works now! One issue still remains, which is that the east, west, and bottom sides of the block appear slightly darker than the other sides. This lighting behavior is not visible on normal obsidian blocks.
  16. Thanks for the help so far! I was able to render an obsidian block in the world. However, it moves around strangely whenever I stand on a block next to it and sneak or more noticeably if I view it from third person. The code for the RenderWorldLastEvent that renders the block: Two screenshots of the rendered block from first and third person perspectives (with a normal diamond block for reference):
  17. For my purposes (mobile "sub-worlds" or "meta-worlds"), rendering with a client event seems preferable and was used successfully in 1.12.2. My first idea for initializing a buffer has no compiler errors and is written as follows. IRenderTypeBuffer buffer = IRenderTypeBuffer.getImpl(Tessellator.getInstance().getBuffer()); Does this look correct so far?
  18. I am currently working on a world render event that draws blocks in the world. In order to do this in 1.15.2, it appears I need a buffer that implements IRenderTypeBuffer. Could someone please explain how I could get an instance of this kind of buffer from within a RenderWorldLastEvent function?
  19. What I am doing is creating a network packet that is sent from the server to all clients containing an instance of the DimensionType class. In Minecraft 1.12.2, the equivalent packet would send an integer dimension ID, however it appears this system of dimension handing is no longer used. Does anyone know if there is a forge or vanilla function to serialize a DimensionType instance for use with a packet buffer?
  20. Ok, thanks! I will try implementing something like that. Although it might be a while until I have fixed enough of my mod's code for it to run.
  21. So a bit of backstory here. A while ago I wrote an experimental mod for Minecraft 1.12.2 that could take a bunch of blocks from the world, put them in a dimension registered during runtime, and then render these blocks while they are in the new dimension as a non-entity object in the original world that can be moved around, rotated, or even scaled. I call these non-entity objects "sub-worlds". Yesterday I began updating this mod to work with Minecraft 1.15.2 and have encountered an immense amount of broken features. One critical component of the sub-world rendering class that I have not been able to find a replacement for, is a line of code that references another dimension's world instance from the client. Previously this was done as follows : int id = <The sub-world's dimension ID>; World subWorld = DimensionManager.getWorld(id); However, due to the way dimensions are handled now, this and many other internal mechanics of the mod no longer work. Does anyone know what the equivalent for the above code would be in Minecraft 1.15.2?
×
×
  • Create New...

Important Information

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