Compat Issue since last Update with Easierworldcreator
suerion opened this issue ยท 18 comments
Describe the bug
Had an Issue with Easierworldcreator Compat
McMellonTeam/easierworldcreator#17
To Reproduce
Update to the latest from easierworldcreator an c2me
Expected behavior
Should not throu an EOF Exception
Runtime info (please complete the following information):
- OS: Windows 11
- Minecraft version: 1.21.1
- Mod version: latest
Crash reports / logs
See in the issue with easierworldcreator
Other mods
In logfile
Checklist
- I am using the official version of the mod.
- I tried the latest development version but the issue persists.
- I searched for similar open issues and could not find an existing bug report on this.
Mods should not operate on region files directly since it is in use by the server, and nothing is guaranteed to be written to disk immediately. This is an easierworldcreator issue.
Hey, yeah i had created both issues to resolve it, if it happens on there side, will be close the issue here after work.
Thanks
I apologize for misinterpreting the ChunkUtil class for modifying region files.
If that's the case, then ChunkUtil isn't ready to be used in multi-threaded context. C2ME 1.21.1 currently have allowThreadedFeatures switch removed and have threaded worldgen being effectively always enabled.
From a brief look at that class, it seems that the problem can also occur if you decided to pre-generate on overworld, the nether and the end at the same time. It very much look like a bad design overall.
But if your intention is to avoid spawning features on existing chunks, vanilla have already done that for you. All generated chunks are read-only during world generation process, and write attempts are ignored. You can alternatively check if the Chunk instance is a WrapperProtoChunk to determine that.
well, I use a custom file that allow me to create features on multiple chunks. I don't modify the region file. The file store every chunks already generated so that the features doesn't try to spawn on already generated chunks. The part of the code that is responsible for the issue is just a binary search function. I can't find a bug in the search algorithm. And since that this only happend in 1.21.1 with c2me (every other versions availible, with or without c2me doesn't have this issue), I don't understand what's happening.
I considered this problem and solved it. My first approach was using ChunkRegion.getChunk() but it would often freeze thread, I wasn't able to solve it. that's why I came with my new solution.
ChunkRegion.getChunk() is nonblocking. The only way that can happen is that you accidentally used ServerWorld. Please provide the stacktrace with it freezing the thread.
well the features are placed during the ChunkStatus.FEATURES, when the status is changed to ChunkStatus.LIGHT, or anything else, it is too late. So what can happend I believe is that the chunk generation can sometimes not be finished but the features being already placed. It can make so that the feature isn't placed entirely onto every chunks. But I think I might have find the problem. When adding chunks, I was rewritting my file entirely (Yes that's dumb). But now I only add the chunk at the good place.
after testing, this error doesn't appear anymore. But I think that it can in some rare case have some problems with multi threading.
So what can happend I believe is that the chunk generation can sometimes not be finished but the features being already placed. It can make so that the feature isn't placed entirely onto every chunks
The chunk system isn't dumb. Feature generation won't be done twice for a single chunk. It ensures every chunk to go through every single status (including features) exactly once.
yeah, what I mean is that, if the features of a chunk got generated and that I don't verify if a chunk was generated, it can result in something like this :

The feature generation are always done once, I don't modify it. I just verify if my features can be placed on every chunks it covers. If yes, it is placed. If not, I add an offset, I move my feature before generating it to make so that every chunks that is covered by my structure are not generated. Wich result in a clean shape without hole for example:

It is considered a user error if they have generated chunks without the mod in-between non-generated chunks. That's not really a problem to consider.
But even if you do care about this, if a new user add the mod to a existing world, you will assume it is not generated with your current approach.
You should just check whether a chunk is already generated with the provided ChunkRegion (or FeatureContext#getWorld)
Hey, thanks for all your work, :) hope you will find an good way, if i could help, ping me here or in the other issue
sorry, I'm a little bit busy at the moment. I'll explain what my mod does so you understand everything.
My mod allow mod to generate shapes(sphere, circles, torus...) based on mathematical equations. I calculated the coordinates of the shape and then I assign the block to place for each coordinate. I generated a sphere with a radius of 150 I beleive and ask to assign a redstone block to every BlockPos

One thing that the user can do is generate those shapes during world-gen like any other feature.
One of the thing that is possible to do in my mod is to have huge features (shapes that are larger than a chunk).
To do that I divide the coordinates by chunk. Every chunk of the shape is saved and will be placed chen the related chunk is generated in the generateFeatures() method.

This allow you to create huge shapes but also have some drabacks: The coordinate calculation is started when the feature is starting to be placed. Some of the chunks calculated covers some chunks already generated. So the chunks of the shape won't be able to be placed.
To avoid the problem, I check if every chunks that the shape covers aren't generated. If yes, nothing is changed, If no (and that's always the case), I add an offset to the chunks. so that every chunks covered by the shape is able to be placed.
I need to know if every chunks of the shape covers ungenerated chunks. That's why I use a custom binary file that list every generated chunks. I'm not able for the moment to provide stacktrace, should be able this week end, but here is an old clip of the issue when using the following method:
public static boolean isChunkGenerated(StructureWorldAccess world, ChunkPos chunkPos) {
return world.getChunkManager().getChunk(chunkPos.x, chunkPos.z, ChunkStatus.FULL, false) != null;
}here is the log that showed me. The verify chunk and the chunk : [x,z] was put before the call of the method. The chunk: null was put after. I waited like 5 mins and nothing more showed up:
[18:37:02] [Worker-Main-10/INFO] (easierworldcreator) chunk : [40, -34]
[18:37:02] [Worker-Main-10/INFO] (easierworldcreator) verifying chunk
[18:37:02] [Worker-Main-10/INFO] (easierworldcreator) chunk : null
[18:37:02] [Worker-Main-10/INFO] (easierworldcreator) chunk : [38, -32]
[18:37:02] [Worker-Main-10/INFO] (easierworldcreator) verifying chunk20240826-1644-21.5883882.mp4
Sorry for the long message. I hope this helps to understand the choices that I've made (that may not be the better way of doing it but that's the only way to make it work entirelly for the moment)
@ishland did you seen the message?
hopefully it would be fixed, for not spamming the log anymore
public static boolean isChunkGenerated(StructureWorldAccess world, ChunkPos chunkPos) { return world.getChunkManager().getChunk(chunkPos.x, chunkPos.z, ChunkStatus.FULL, false) != null; }
You should never use ChunkRegion#getChunkManager but use ChunkRegion#getChunk with EMPTY status directly. Then check whether the instance is a WrapperProtoChunk. Using ChunkManager#getChunk on world generation threads can result in deadlocks in many cases.