100 Day Challenge [Days 31-40]

40 Days complete, almost half way

Total dev time: 47h 30mins

dogeDIG:

Not a ton of progress this 10 days, I was aiming to get this voxel-system digging mechanic rework solidified, but didnt quite achieve that goal. A few more solid days of dev required to get that one done for now.

So this means no new pre-alpha tasks completed:

So a bit more time working on the voxel system and terrain editing with the hours I did get in. During the previous days (20-31) I implemented an efficient voxel-spawning queue I was pretty happy with, so I decided I could at least make the voxel checking a bit more efficient as well – a required function to finish off the basic implementation of this voxel system regardless.

Initial surface voxels, in a generic terrain chunk

Checking for already existing voxels was a pain and something Ive already implemented a few very tempory ways as this project has progressed, heres a breakdown and some ramblings/thoughts of how Ive implemented this ‘voxel check’, past, present and future:

What is this ‘voxel check’?: In its simplest form, this is the functions required to find and/or modify a voxel (or space where a voxel could exist) from the game world. Since this check deals with the potential of so many voxels in any given ‘chunk’ of terrain, it branches out to a few other areas like data storage and data lookups which all have a variety of efficiencies to take into consideration and issues to solve – all of which form the foundational architecture of a voxel-based system.

Oldest/Initial Approach: There was some old code lying around for the oldest way I used to check for voxels – just outright saving the voxel objects in their location in a massive 2D array. This is really bad though, as the array could technically be as large as 16,384 game objects per chunk (128×128 voxels currently), which increases/decreases by a power of 2 depending on how chunk sizes change. 16k is well within the C# limit for an array length of ~4 billion and is at least quick(ish) for voxel lookups since everything put into the 2D array is by nature indexed, but its some absurdly large data/arrays to work with. This approach is ok for data lookups but very bad for data storage.

Previous Approach: A more recent approach (as the game was using until this week) was to still save the generated objects into an unordered array/list and then just search that. Theres still the potential for 16k+ objects being stored per chunk, but most of the time (and under regular conditions running this game) there wont be that many voxels (hopefully). Its also a bit slower than the old approach (especially if there are a lot of voxels active in a chunk) but it was an ok enough approach to ‘get the job done’ at least for the pre-alpha version of the game. This approach is a bit slower for data lookups, but sometimes alright for data storage, both of which get worse as the array list increases in size.

New Approach: This is where I brainstormed a few new approaches, the initial winning idea was just to do a brute force ray check to see if any voxel existed in any given location before a voxel is created/destroyed. I got this setup and working well enough, most of the methods for casting rays from locations on the screen to points in-game were written ages ago and Ive refactored them recently – so they were easy to repurpose or reuse. But there was a slight spanner in the works when it just wouldnt seem to return the correct colliders/gameobjects. Eventually I found out that composite collider setup (which Im using for all the voxel colliders) dont have ‘individual’ colliders ‘per object’. Unity looks at a collection of composite colliders as one single collider. Duh… its a composite collider afterall! So this approach was implemented days ago, but failed to become a working solution at the very last step… -__-
Not the end of the world though, since I didnt really like it as a long-term solution anyway. But this approach *would* have been great for data lookups (no real data storage needed), and pretty fast ¯\_(ツ)_/¯

New-New Approach: Even more brainstorming and the obvious solution hit me, the absolute simplest approach would just be to name the voxel gameobjects as they generate (a unique name per-location per-chunk), then just search the collection of current voxels (a collection being limited to each chunk) to find out if one with the correct chunk-relative-location based name actually exists. Zero data/array storage needed and fast enough for a reasonable number of voxels in any given chunk.

Future Approach: With all of this done and working, I still have a future upgrades in mind. The new-new system is a lot better (especially in terms of simplicity and minimal-to-no data storage being required for voxels) – but it still wont handle hundreds of voxels very well which I’d at least like to aim to support with this voxel system. So things I have in mind for the future:

  1. Optimising active voxel count (ie a sub-system to manage unspawning /spawning voxels as required)
  2. Optimising the voxel objects to support large numbers – ie theyre individual voxel objects now, which is not ideal since hundreds of individual objects put a strain on a game engine and kill FPS. I have a plan to ‘batch’ them into just 1 object per chunk, but that will be something to work on later when the game is in Alpha
  3. Optimised lookups – Ive now got this system to the point where theres minimal data storage required, but searching for voxels is still far from ideal and so I have a future idea (which feeds into point 2.) on how to find voxels without searching large arrays or brute-force checking via unique voxel names, it could be as much as a single data lookup based on a simple equation – which would be very fast!
  4. Physics! I did some tests with voxel physics a year or so ago, and honestly I could quickly reuse that code with this refactored system and get it working again. But thats probably a feature best left for Alpha

Its still not perfect and theres a growing number of edge cases to take care of with a system like this, but its basically at the point where it works well enough to move on (for now) without any major issues!

Voxel drawning & erasing, with many edge-cases covered!

Only a bit of shader dev this 10 days as well so nothing completed or worth showing, I’m hoping to get a few more shaders done before this challenge is up!

/end