The Last 10 Days

Posted on 29/04/2017

Shortly after releasing Orchard as my first game written fully in JavaScript. I decided it was a good bet to use it as main main tool for 2D game development from then on. But then I thought, what about 3D development?

So I thought I'd give creating something in 3D in Javascript a go. I decided to stick to what I'm good at and started creating a brand new voxel engine. I figured, if I can do that in JS, then I can do anything.

It was slow going at first, or at least it felt like it. I am using the Three.js library for handling all my 3D needs rather than using WebGL directly. I set up the usual World > Chunks > Voxels system. I was using JS objects for everything down to the voxels themselves. And all I was trying to render was some flat terrain, and it looked like something right was happening:


I also learned about, and started using web workers, which are JavaScript's answer to multi-threading. And I thought I'd tackle the use of these early on. The first use for them was for the meshing of chunks. The voxel data (as a big nested JS object) had to be converted to JSON, so it's in string format now, and passed to the worker. The worker then handled the meshing and sent back a ThreeJS geometry object.

I then proceded to add shapes to the terrain, and normal data to the vertexes (we're dealing with cubes so the normal data is per-face). It was still loading in OK and with reasonable speed, I thought, despite there being no culling:


A thing ThreeJS does well is giving you cool and pretty easy to set up effects for shading and shadows, etc. So I pushed on with actually putting some terrain into this thing, with some of those effects thrown on it. It still had no culling, but still felt quick to load to me, even on a small map like this I thought it was handling things great:


I felt by now that this was actually a very viable thing. To be honest I didn't have high expectations or expect wonders. I thought this couldn't compete with my game Terrablox for speed or memory effeciency, as that was made for windows. But every new thing I was learning kept convincing me otherwise. I started to tidy up my code, as I was expecting to be spending a lot more time on this. I split things up into sensible classes and started adding userbilty features like moving the camera around.


I moved on to implementing textures. After some confusion due to WebGL using "upside down" UV coordinates compared to what I'm used to, I finally got it working. I also added a sky coloured background and some fog to blend it all in. And it was really starting to look quite good!


I finally got around to culling. It was starting to effect memory quite a lot the bigger maps I put in, having to render so many cubes. The culling process was slow, but it greatly improved the speed at which the meshing was done and also brought the memory usage down. Because the culling was so slow, and it was all done at the start of the program, I decided to put that into a web worker as well. While this meant I didn't have to wait for the culling for the rest of the program to run, it was actually now taking more time to do. I found out this was because I was using JS objects for everything down to the voxels, and that amount of data having to be copied and sent back and forth was choking it. So I had to start using ArrayBuffers, less flexible, but they have the ability to "transfer" between threads rather than being copied. This meant I could completely remove that overhead.


Many tweaks down the line, and I had managed to get huge maps of tens-of-millions of voxels fully generating in less than a second. Even though I done it, I still didn't think it was possible... In a web browser! So I plan to trudge along and see just how far I can take this thing.

Having made loads of voxel engines over more than 7 years, I plan to release this one as an open source project rather than leaving it to go nowhere in my back catalog.

So that was my last 10 days, from the begining of this project to now. I know it's been a very brief blog post, but I can't remember every detail! I will however create more detailed blog posts explaining certain parts of the project and how I went about doing things. Thanks for reading, if you got this far! :)