This game engine is an early prototype, expect things to break, if they’re not already broken!
OSUVE is my take on a voxel engine, made open-source to the world t̶o̶ ̶p̶u̶t̶ ̶t̶o̶ ̶s̶h̶a̶m̶e̶ ̶a̶l̶l̶ ̶p̶a̶i̶d̶ ̶v̶o̶x̶e̶l̶ ̶e̶n̶g̶i̶n̶e̶s so that others may benefit from the knowledge that is accumulated here, and perhaps contribute some of their own. I will be continually working on this until it becomes a working product. (After all, I have plans to make a game with it!)
All the code is open-sourced on GitHub, and is licensed under GPL-3.0.
Anyways, time for some (prolly outdated) eye candy…
That aside, I’ve come across a particular issue with my current refactor where I enforced proper block generation, storage, and retrieval, but it now conflicts with the above grass CTM in particular inter-chunk boundaries. I’ll be in a bit of a sticker until I figure out how to manage around that.
I’ve pushed what work I’ve made thus far, but it’s unstable and will have chunk errors.
(Thankfully exceptions are now caught from the thread and protected with a try/catch!)
I’ve also put up a Discord link to my server that I’ve been vying on whether to make public or not, but heck, I’ll just get on with it finally.
Hi, nice work! I’m not very good at the reading code of other people, can you explain how you implemented connected textures, and also why do you using int3 when unity have Vector3int?
Wait, there’s a built-in Vector3int? .w.
I couldn’t find something like that online before I made my own Int3 struct…
Anyways…connected textures is as simple as choosing what texture to UV map too the mesh. The Cube methods in Chunks is where you’ll want to look.
For a certain direction and given block id, the method checks if there is a particular block in a particular position, where it then returns the grass side texture or the grass top texture.
This is also where my issue now lies, as this can attempt to access blocks from a diagonal chunk, something that I had not accounted for. I may need to come up with a more flexible yet robust system to handle this.
The Vector3Int was nice, but I realized later on that it would be better to separate and make some things that used that be explicit but convertible, particularly chunk, column, and block positions. (Vector3Int also lacks forward and backward static properties)
Originally chunk positions were stored using Int3/Vector3Int, whereas blocks were referenced using separate x, y, and z variables; I had some issues with converting, for example, local and world block positions, and some areas of code are ambiguous with which one they are referring to. (the World.GenerateBlock methods take world block coordinates, whereas DataChunk methods take local block coordinates)
To remedy this, I’ve been thinking over and then making ChunkPos and BlockPos structs. (ColumnPos is just a top-down 2D variant of ChunkPos for DataColumns) The most important aspect of these three is BlockPos in particular; it takes both a ChunkPos and local block coordinate, or a world block coordinate that gets converted internally into a ChunkPos and local block coordinate. BlockPos also has methods that return world block coordinates instead.
Hmm, fair point, though I’m holding out on that for now mostly because I break things with every commit thanks to refactoring as I’m left to my own devices of figuring things out ^_^;
I’ll make one such zip exe build once I get to a functional and stable state.
After some ramshackling and extensive time, I have internally documented most methods and properties, as well as put up an online documentation using the very nice Read the Docs :3
(It wasn’t easy given the lack of interest and documentation for putting C# API docs on RTD)