Ivelate / Kubex

Voxel game with cubic planets, and more. Java / LWJGL / OpenGL
27 stars 6 forks source link

Problem with the chunk and world dimensions #3

Open miek0tube opened 6 years ago

miek0tube commented 6 years ago

Hello Victor! I'm currently studying the world generation part of the engine. In my future game I will need static structures like Minecraft's mines, villages and dungeons, and it seems difficult to generate such things while using the default chunk size (32) and the world height (8 chunks). I mean that not only should I check that the chunk horizontal (X and Z) coordinates are within a structure but also intersect the inners of the structure with the vertical coordinate of the structure and 'draw' the resulting part of it within the chunk. I think it's the main reason why Minecraft uses non-uniform chunk size of 16x16x256. The problem could be solved by resizing the chunk to 128x128x128 or even 256x256x256 (64x64x64 is too small), but the latter simply causes the game to hang. With 128x128x128 it works for a while (world height is 1 chunk) but the landscape is empty and it hangs anyway after a while. I even tried to reduce the rendering distance but with no result. Could you please tell me -- is it a hard limitation of the engine? Is there a simple way to make the chunk size non-uniform, like in Minecraft? I'm not trying to ask you rewrite the enigne, but only to point me in the right direction.

Ivelate commented 6 years ago

Hello,

I thought a lot about this problem. Bear in mind that a chunk isn't drawn until all its neighbours have been added to the scene - this can be used to our advantage. This basically means that, by the time any part of any kind of structure is drawn, there is at least for the worst case 32 cubes already loaded in all directions, which means that by the time any part of a structure with size less than 32x32 is drawn it is already been loaded fully in memory.

As for the chunk size of 16x16x256 in minecraft, please note that in our case we are doing something similar: When loading chunks all vertical chunks are loaded together, from the topmost to the bottommost one. So, for the time the bottommost chunk loads, you can consider that all chunks sharing the x and z coordinates with it have been loaded, so you can do the structure generation when the bottommost chunk is loaded only, and modify the chunks above it when inserting the structure if needed.

In fact, trees are being generated this way! In the Chunk class, check the initcializedFlag - in line 1670 it checks if all the chunk neighbours have been added and if the flag is false, if this matches the flag is set to true and a method WF.getMapHandler().generateChunkObjects(this); is called, which generates the the trees and the grass now, but you could also generate any structure you desire! And, if you are planning to generate a big structure, you could add the check for the bottommost chunk we talked before - inside this if, checking if chunky is 0 and then adding a method to generate structures as tall as you desire.

The hanging is maybe being caused for three possible reasons:

Try both of them, and if the problem persists, i will take a look to it by myself.

Sorry for the late answer, i have started a new job and moved to a new city so this days are being a little crazy for me. From this weekend onwards i think i would be more settled and i could continue with the model loader i was working on!

Good luck and thanks for the interest in my engine! Victor

miek0tube commented 6 years ago

Hi Victor,

Thank you for taking a look on this. I've tested the large chunks again and found that there's something else that prevents the game from running. I've increased the JVM memory limits with Xms, Xmx and MaxDirectMemorySize raised to 2GB. Before this, the process shot this error:

Exception in thread "Thread-5" java.lang.OutOfMemoryError: Direct buffer memory at java.nio.Bits.reserveMemory(Unknown Source) at java.nio.DirectByteBuffer.(Unknown Source) at java.nio.ByteBuffer.allocateDirect(Unknown Source) at org.lwjgl.BufferUtils.createByteBuffer(BufferUtils.java:60) at org.lwjgl.BufferUtils.createFloatBuffer(BufferUtils.java:110) at kubex.storage.FloatBufferPool.getBuffer(FloatBufferPool.java:40) at kubex.gui.Chunk.genUpdateBuffer(Chunk.java:203) at kubex.gui.Chunk.genUpdateBuffer(Chunk.java:163) at kubex.gui.ChunkUpdater.run(ChunkUpdater.java:54)

After, it gives another error: Exception in thread "Thread-5" java.lang.ArrayIndexOutOfBoundsException: -128 at kubex.storage.ArrayCubeStorage.get(ArrayCubeStorage.java:21) at kubex.gui.Chunk.genUpdateBuffer(Chunk.java:236) at kubex.gui.Chunk.genUpdateBuffer(Chunk.java:163) at kubex.gui.ChunkUpdater.run(ChunkUpdater.java:54)

Anyway, all this is not needed with the clarifications you gave. Knowing it, I don't need to increase the chunk size above 32 or 64.

Good luck on the new place!