Hello everyone, and sorry for keeping you waiting! I've been working on Quark Storm's inner workings for quite a while, and I finally feel like I've made enough progress to warrant a news update. The stuff I'll be covering this time around will be a bit more technical than the previous updates, though, so please take that in mind. Without further ado...
The rebuild initiative
It was a while ago that I noticed a flaw with the way I was creating Quark Storm's levels: There were many unneeded draw calls, the way I handled level geometry sometimes messed with the physics, and levels were all built by hand, including the geometry and the colored borders, which meant creating new levels or iterating on current ones took me way, way longer than it should have.
The solution was simple, if a bit time-consuming: overhaul the graphics system and migrate game physics to 2D to take advantage of edge colliders, which could be edited fairly easily by extending Unity editor's inspector.
The first issue I tackled had to do with the way I handled the graphics. Quark Storm's levels were all made out of 3D geometry, which wasn't even worth it since the camera's set to orthographic mode (meaning no perspective, so you only see the front of the 3D models), and the script I had created to tile the level textures modified each individual object's material, making each one of them take up a draw call all by itself, since a modified material becomes an instance of the original one; most of the time, I'd be getting anywhere from forty to ninety draw calls, depending on how many level bits were onscreen. That just had to go.
The solution required two actions: First, I made all level graphics into 2D objects (a square and a triangle), which removed lots of polygons I wasn't even using while also making texturing them way easier; second, I created the tiling effect by actually modifying the level bit's mesh's UVs, which instances the mesh but still results in a single draw call. The result was going from an unpredictable 40-90 draw calls per frame to about twenty, which means things will work faster and be a lot more stable from now on.
The level textures get automatically tweaked as soon as it's loaded,
just like before, but now the resulting objects use a single material
so static batching can work its magic and minimize draw calls
The second graphics issue were the edges. Before, I was using a complicated system where each level bit came with three or four line colliders, and used raycasting while in the editor to see whether they had to be active or not. That meant there were places where two edges wouldn't overlap, forcing me to patch those places up using circle gradients. All that process took lots of time since it had to be done by hand... and yes, it bumped up the draw calls as well.
Fixing this really took me a while. I had already migrated the physics to 2D by then (more about that on the next section), so I had a bunch of vertexes that, when conected, made up the level's collision edges; the obvious solution was to create a mesh using those vertexes, but the algorithm I had to come up with absolutely had to keep the edge with a constant width.
It took lots of brainstorming and drawing geometry diagrams with my cousin (who's also into programming, only applied to biology) to come up with the right solution, and even then it took the help of a fellow from an indie game development community to fix some stuff that we had gotten wrong. Without going much more into detail, we ended up combining trigonometric functions as well as vector math to get things just right. Doing all that complicated math is fine since it's only run once, and having a fully automated system is a whole lot better than spending hours upon hours hand-tweaking stuff.
Decreasing draw calls for the edges from N to two, all while
completely removing the need for hand-placed stuff - efficiency at work!
Quark Storm used to have a glaring bug due to the way I was using Unity's 3D physics: If you were touching two level bits as you got pushed by an explosion (for example, when you're touching both the floor and a wall), both objects would apply friction to you, resulting in an extremely low jump that'd probably throw you off and lead to screwing up; there also was the issue of having lots and lots of collision meshes, even if their shapes were really simple.
Unity 4.3 introduced a 2D physics engine, and with it something called Edge Collider. Like I've explained a while ago, edge colliders have a list of vertexes that make up the collideable surface, all while being a single collider. That's exactly what would fix the collision bug I used to have, and it also meant I'd minimize the number of colliders for the levels as well - all upside!
Inputting vertex coordinates is boring
(AKA: let's make a level editor tool)
While I had everything neatly wrapped by taking advantage of edge colliders, there was still an issue: to create an edge collider for any given level, I had to manually redimension the edge collider's vertex array's length and then input each vertex's coordinates by hand. Not only did that make creating the levels in the first place take a lot of time, but it also made it nearly impossible to edit the collider if I had to add or remove any vertexes in the middle!
The solution for this issue was way simpler than the rest: Come up with a custom interface for Unity's editor that'd allow me to arrange vertexes in the scene view, navigate them and create or remove them in no time. All it took was a level vertex class that's linked to its neighboring vertexes (previous and next) and the custom inspector class that could change focus from one vertex to another, add new vertexes in between them or take the resulting vertex list and feed it to an edge collider. Once I read up on how to do custom inspectors and set the editor's focus to a given object, it took me less than two or three hours to complete.
Here's the new node system in action. Notice the custom GUI for the node's inspector,
which is what allows me to seamlessly naviagte and modify level geometry
I really wish I could show you some new levels or exciting new game elements now, but that'll have to wait for the next update. While what I've been working on hasn't advanced new developments by itself, it'll lead to lots of improvements in the long run, so I'm really happy with what has come out of it.
Now, with most of the coding-related things out of the way, I'll finally get back to working on levels. I hope you'll be looking forward to the next update!