Yes, this devlog is late. I posted it on Itch a while back but had issues with my webhosting service so couldn't actually update anything on the website.
I swore I wasn't going to touch the chunk gen code again since it's just not nice to work with while being so fundamental to the gameplay that I really did not want to risk breaking it. However, in testing there was a very noticable delay sometimes upto a full second between breaking/placing a block and the change being updated on my screen. As they say, perfection is the enemy of good enough, so I put it off for a while, before remembering I had an entire playable class planned who was built around rapidly digging tunnels. So, not only was this far from perfection, it was certainly not good enough.
When profiling the game to try to get some more speed out of chunk generation, I noticed that every time a chunk was generated an amount of memory measuring in the killobytes was being allocated. Not good! That much work on the garbage collector was undoubtedly what was causing my issues with sluggish-feeling world manipulation. To solve this, I busted open the raw chunk generation algorithm. That is where I realised my mistake: thinking too abstract. In my attempt to write 'clean' code, I had abstracted much of the mesh data into its own different classes including utilities and things to make the process easier to code for. Super clean! However, to do this I was in the background using a lot of different dictionaries and lists, and creating new ones every time I wanted to generate a chunk. Not good!
The fix was simple: just get rid of it? At this point I have enough of an understanding of mesh gen to be able to work more-or-less directly at the vertex, triangle, and UV level. I did have to use a list to represent these which had to be converted to an array, so some data still had to be allocated. However, in the end the difference in performance is massive. I hope that when you check out the build you can feel it! See below, clean VS quick
I also looked into implementing texture atlassing to improve performance. I did get a version of it working, which did have a performance improvement - though nothing major. However, there was very noticable bleeding on the edges of blocks due to mipmapping. To fix this, I'd have to create a proper texture atlas where each texture has a border dynamically assigned based on its edge colours. The effort required to do this would just not be worth it, so instead each block has its own material and every chunk is essentially seperated into a number of sub-meshes consisting of one type of block. If this becomes a performance issue then I will of course have to find a solution, but for now it isn't an issue.
On the positive side, each block having its own material lets me do cool shader work like this. This is false dirt (block #5 if you want to build it). It looks identical to regular dirt, but fades away when you get close using a shader. Later, this will be used to disguise tunnel entrances by having no collision. For now, it works as a test of different block materials.
So that's it for devlog #6! It's not what I had wanted to work on, but it's a necessary improvement. Next time, I want to finally start implementing a weapons system. With this, I will take destroying blocks away from just being a magic instant change, to weapons which do damage to blocks which eventually break. The challenge of each block instance having its own data (even if its only one HP value for now) stored and sent over the network seems a little daunting, we'll see how that goes! See you soon :)
peterkirkcaldy@gmail.com