I had to delay this post last time, but if you are reading this it should now be fully published and done and I am back to my previous schedule.
Let’s talk about clicker and idle/incremental games, shall we?
I think at their core, most – if not all – clicker / idle games are strategy games or at the very least closely related. This can be directly observed by comparing idle games to older browser games such as OGame (see screenshot). Where technical limitations reduce a strategy game to its core functionalities where all information is reduced to numbers and time.
Even though I use them quite interchangebly, they actually arent; A “true” clicker would focus solely on the active part of clicking while a “true” idle game uses clicks only to navigate or select/upgrade, not to actually play.
That said it’s fair enough to lump these two subgenre together as most games are a hybrid of these two and more than often also an incremental game.
Both have become quite popular, so dozens of new ones hit stores/sites like Steam and Kongregate every week.
So just for the sake of staying sane, unless otherwise stated I shall refer to all three subgenre, being idle, incremental and clicker game, to just “idle game”.
I’ve been intruiged by idle games for a few years now and played a bunch of them, some almost to the “end” of their content, some not far at all. Mostly to have something to play inbetween other tasks or to enjoy a bunch of crazy multipliers take my understanding of numbers to a whole new exponential level.
And I think some of these games have a mechanic or design that is worth pointing out; One thing right off the bat is the naming scheme, most games of these genres tend to be quite… upfront about their games core premise.
Naming usually includes some form of reference to the genre: Clicker, Grind, Idle, Incremental and so on.
Let’s go over some of these games and see what makes them special.
The first and probably one of the most famous idle games that I have ever played, created by Orteil (https://orteil.dashnet.org/)
It’s really intriguing since it ticks all boxes so well; It starts off very click-heavy while transitioning slowly but surely into a more afk style of play where all the upgrades provide much more substantial boosts in CPS (Cookies per second).
I think this is pretty well done from a design perspective, the initial cookie clicking is enticing enough to keep you playing until you get your first upgrades, all the while showering you with achievements. This quickly turns into a spiral where you get obsessed with getting more of everything: more upgrades, more achievements, more prestige, more buildings, MORE COOKIES.
This was the second proper idle game and another one that shot up in popularity soon after and for good reason(s):
Clicker Heroes looks a lot more like an actual game, not just a number simulator, it’s a lot more colorful has much more visual variety from the characters you can buy and upgrade to the enemies, bosses and their habitats.
It also features more meaningful decisions and choices for the player depending on their style of play. Compared to cookie clicker where you can technically calculate (and there is addons for that!) the best value building or upgrade to buy.
Clicker Heroes has Ancients that can be bought and upgraded to either server active gameplay (clicking) or passively (idle) gameplay, some also give you a chain for either, so the longer you idle or the longer you keep clicking the higher that bonus.
Which creates interesting ways to strategize, it’s also possible to respec but it’s not free and will set you back a bit, and I really like those choices.
I have neglected to talk about it, but I feel now is the time to talk about: Reset mechanics.
By Reset mechanics I mean those partial resets that those games offer in order to progress further by way of locking certain upgrades behind resetting at least once.
The idea is to stretch gameplay by making the player sacrifice most of their progress while rewarding them with ways of regaining it faster and going beyond.
Some games go so far and even add another more strict reset, these are often a milestone to reach and a vital part of progression later down the line, Clicker Heroes has “Ascension” and “Transcension” respectively.
Realm Grinder encorporates this in a very interesting way. It actually features three types of resets (by my last count): Abdication, Reincarnation and Ascensions. You can abdicate as much as you like, similar to other games, but Realm Grinder handles the tier two and three resets differently, they are fairly limited and rather unique in the way that they create interesting strategy opportunities for the player since they unlock a lot of different upgrades that can completely change the best build to use.
Also, should you be interested in Realm Grinder, this is it’s Steam page.
Also also, it has a great fansite created by G00FBALL that is worth checking out for strategies, builds and general information on the game.
And finally we have NGU to talk about, in case you are asking it’s literally: Numbers Go Up Idle.
And the game is just as zero f* given as the title suggests.
NGU got quite popular recently and even released on steam. And while it certainly looks and feels a bit crappy, it certainly isn’t under the hood.
It borrows most of it’s core UI design and some of it’s mechanics from another Idle game called “Idling to rule the gods”. Which I don’t think is a good UX but it gets the job mostly done and could certainly be worse, especially considering that most these games are done by a single person that is probably more a programmer and less of an artist.
But to be completely fair: this is the quintessence of a lot of idle games, yes it’s about the fun you can have when numbers go up, no need to hide that. Also these games are simple enough that they can be easily done by a sole developer eager and creative enough to whip up something interesting for others to enjoy without having to rely on pretty assets or a well thought out story and characters, but retaining complexity and a sincere feeling of progression that some games just can’t offer the way incremental games do.
Speaking of developing Idle Games…
In theory, developing an idle game should be rather easy; since most of the game is very repetitive by design and there is no need for sophisticated approaches to visual fidelity or sound design.
The more I played idle games, the more I noticed that this isn’t as simple as I thought, there are some technical and design challenges and limitations that are quite unique to the genre(s).
Oh the dread.. for the unaffiliated: 1.8e+308 refers to the highest number possible in most programming languages: 2^1024 which is precisely 1.7976931348623157e+308 a number with 308 digits.
For most cases no software has a reason to go anywhere near this number, but incremental games, by their very nature, have a tendency to do so.
There also isn’t really a lot that can be done about this, most developers either limit numbers to somewhere around 1e+300 or design their game around it. Let’s look at the examples from above:
Having thought about this issue, I believe there is no perfect solution, I think out of the examples I would prefer the method Clicker Heroes’ developer have come up with, but it’s far from perfect. Ideally I think a dual approach could work where the underlying system can handle larger numbers where necessary (for example the main currency/resource) but secondary stuff is handled with careful design decisions so you don’t end up with a screen full of numbers so ludicrously large that they lose all meaning.
And there is a second problem that is quite unique to incremental games: time. All these games are designed to be played for several days, weeks or months even, so not something you spend an evening or a weekend on and be done with it.
This results in two things players will most likely do:
The former (Tab out) scenario can be a bit annoying, not an unsolvable issue but one that usually doesn’t really come up when designing or coding a game. I have created little test project that I called “Idle Souls”, where I tried to tackle this problem like this:
// Core game tickrate
function Tick()
{
var time_new = new Date().getTime();
var time_diff = time_new - last_tick;
last_tick = time_new;
resource_souls += time_diff / 1000 * test_per_second;
$('#resource-souls').text(Math.round(resource_souls));
window.setTimeout(Tick, tickrate - (time_diff - tickrate + 1));
}
My fix is pretty straight forward: I simply calculate the resource based on time passed instead of once per tick (because I can’t be certain that the tick rate is constant). It’s by no means a perfect solution but I can freely switch tabs on my browser without it impacting the rate at which the resource accumulates, so I call it a job done.
A bit less technical but just as important is balancing these games. As I mentioned before this genre is by definition very unappealing so the game has to be well designed and balanced for it to still draw interest.
A huge factor in this is progress, if an idle game is poorly paced it might lead to a player not feeling any substantial gains for long enough to quit the game completely.
This is especially crucial since these games have to rely almost entirely on their layered mechanics, progression and depth to provide entertainment. So there is no story, no unfinished campaign or anything else to tow the player back into the game, should the mechanics fail to stay interesting.
Some games do have a nice community or steam achievements that might get some players to power through, but I reckon most players won’t care that much.
I think overall Idle games can be pretty fun and they definitely have a place for gamers, either because it’s something to enjoy passively while doing other things like watching videos or because it’s light entertainment/strategy and doesn’t require a lot of brainpower or attention, these games play themselves by design after all.
Especially nowadays where hundreds of games are released every month and nearly every new game has to be bigger, better and more exciting; A break from that pace without missing out on new experiences can be very welcome.
Over the past few years I have used quite a wide range of tools, be it Web Applications, Desktop Software or even “just” Forums/Communities to help me in some shape or form. Most of these are widely known, but I wanted to share my personal experience with them and why I think they are worth taking a look at.
Just to clarify right away: these recommendations are subjective and biased based on my own personal experience. This also means that there is probably a plethora of stuff I did not mention, but these are the ones that had the biggest impacted on me personally.
GitHub or rather Version/Source Control is such an important backbone of any bigger project, that I can only hope everyone knows of it’s power.
In case you aren’t quite sure what Version Control is, it is used to manage projects that are very iterative, complex and/or created by multiple people. Especially with a team, you inevitably run into issues if you stick to sending all files, that get created, changed or deleted, between one another manually. Version Control solves this by recording a history of all changes and showing you all changes (including deletions) whenever you want to accept a new commit (version) – this can get a bit more complex with forks, pull requests, merging and so on, but the important part is; nothing is ever lost when dealing with version control. That means even if you delete a script and commit that as a new version, you will still be able to revert that.
Github is just one of many Platforms for version control (Atlassian has one called BitBucket as well) – and It’s mostly reliable and easy to work with, yeah sure Microsoft technically owns it now but that shouldn’t stop anyone from using version control (which can be done outside of SaaS). Especially since GitHub is getting more and more lenient with their private repositories, so people that don’t want their source code public can (finally) use GitHub as well. I can personally recommend it to most developers even though I have been using BitBucket (to host) mostly myself, I have now switched back to GitHub and I use some form of version control for almost every project.
Oh boy, this is a big one… I stumbled over some products only to later realize they were all by the same company (sort of). There’s just a lot of awesome things that I need to list under the “Atlassian” umbrella, so I am going to do this very brief:
There’s also Jira and Confluence that I personally never used but heard good things of. Jira is a project management and issue tracking application and Confluence is basically a collaborative document creation tool, similar to the Google suite but a bit more specific with it’s feature set and less MS Office like.
Also.. all of the Atlassian stuff is mostly free with some premium options for advanced features, but all essential functionality is completely free.
I love Visual Studio itself and Microsoft’s slim variant has completely replaced the long used notepad++, it’s quite fast while having a lot of customizability through extensions. It also features embedded git, code refactoring and really most other decent all-round features of Visual Studio itself.
A bit surprising to me was the fact that it’s completely written in JavaScript, CSS and TypeScript and completely open source on top of that. And while I think Microsoft did stumble a bit in the past few years, they can still do awesome stuff if they want to. I really think VS Code is some good piece of software that most – if not all – developers should consider using. I have been “only” using it for like a year now for everything from PHP to editting .XML files.
I have always been the type of hypocrit, that can recommend things I barely scratched the surface of, so here goes:
Blender is awesome, BUT it has not always been, I can remember years back when the software was – especially for new users – just cluttered, unclear and an overall bad UX. BUT BUT I gotta give it to them, Blender has improved a lot and their UX is so much better now, especially with one of their latest releases (2.80). It’s finally a software that can not just compete with other 3D modelling software solely because it’s free, but because of it’s features and accessibility. And while it’s undoubtedly improved it’s not flawless… yet. Check out this video if you want to laugh at some absurdities of a slightly older version (literally 2.79):
That said, as I mentioned, I’ve barely scratched the surface of what blender can do, but it’s become an awesome (not just “good ’cause free”) tool to create and edit 3D models. A few years back I would never have even considered booting up Blender to fix some normals on a model, but I do that now without hesitation.
I sincerely hope that the Blender foundation keeps up the good work, tools like this should not cost money, not even professional grade. And while I use Blender only barely, it’s becoming more and more frequent and I can easily recommend it to people interested in 3D modelling.
This is a tad bit different from the rest and more a resource hub than actual software or service. Nevertheless Material Design is quite an interesting style guide that Google has published. They really go into details there and generally do an amazing job at explaining why stuff is the way it is, this is honestly worth a lot, considering this is usually information that is well hidden or expensive to get, but immensely crucial for creating UI that feels native to Android like a PWA. Or really just as a guideline to follow to avoid pitfalls when designing UX.
Since I really hate just copying entire styles, I have only cautiously adopted things from this, but it’s interesting to know why certain things should or shouldn’t be done in a specific way.
They also have quite a nice Icon set that looks real slick as well as a color palette creation tool with live preview of it’s look and accessibility uncreatively appropiately called color tool.
Here’s probably something not everyone already knows and it’s a bit more specific too, as it’s main focus is about game development assets.
During prototyping or rather during the “I have a rad idea I want to implement and turn into a project”-phase, which I always call prototyping to sound more professional, it can be really helpful to be able to get some nice assets to mess around. OGA has some really solid stuff on there, a lot of it is even CC0 and while it can be hard to find everything a project needs, I still find it immensely helpful, especially as placeholders.
There’s plenty of different Assets, from Sounds, Music, 3D Art, 2D Art and so on. Granted not all of it is top notch high quality, but for a small indie dev this can be worth gold. But this does not replace proper art and asset creation, as it is extremely unlikely to find all assets your specific game is going to need without mixing styles or compromising on content.
Really the only two bad things about OGA is it’s admittedly outdated look/implementation and it’s small and seemingly declining userbase, which might be caused by the former. I really hope people come back to it and share or use the awesome art that is being collected there.
Stuff that is cool and free, but not (currently) worth for me going into detail about.
To be honest I could’ve done this in 5 minutes with a simple bullet list and called it a day, but I went overboard with it, as per usual.
I hope you enjoyed it nonetheless and maybe even got some amazing new software/tool/resource to check out and/or try!
Cheers!
Oh and besides: The next post is going to be about Shaders, though a lot less math heavy compared to the Surface Nets post… hopefully.
Know that this is certainly going to be a more technical post, but should still be interesting for people that are curious about how games are created, even with little to no knowledge on the subject.
This post is going to focus on my delves into the depths that is mesh generation for a 3D terrain, note that I am not going into much details outside the actual mesh generation, there is certainly a lot that can be said about Normals, Shader and other minutia, but not today.
To be completely fair, I started this whole affair knowing pretty much nothing about this myself, sure I know how voxels work and have done a minecraft-esque implementation of a voxel mesh myself, but that was following tutorials and it’s concept is way simpler than actually creating a more organic looking terrain.
If you want to create a terrain in any type of game or simulation, you will need to figure out how to turn the terrain data into polygons or: How do we turn numbers into a landscape?
Sure we can just fire up Blender and model some nice terrain there, we can even texture it and give it some advanced details. But we want to be able to change the terrain at runtime, i.e. dig into the ground or have an explosion create a crater, so just modelling it is out of the question.
By far the easiest and quickest solution would be a heightmap based terrain.
Such terrains are generated from two dimensional information, this is usually done with either a perlin noise, often layered, or a handcrafted greyscale texture like on the image shown.
If we take the shown image as an example, every dark pixel would be a lower part of the terrain with black being the absolute bottom, usually sea floor, while the brighter pixel will end up as the higher parts with the brightest pixels being the mountain peaks.
While this can result in a very decent looking terrain that is very lightweight, it’s not without it’s caveats.
Heightmap based terrains have quite some downsides, you can’t have overhangs or caves unless you remove parts of the mesh which leaves an ugly hole that is hard to mask. There is also a substantial loss of detail on vertical parts of the terrain like cliffs or steep mountains.
So we collectively decided that we did not want to use a mere heightmap for our game since we want to have interesting caves and mines and want to allow more sophisticated terraforming since heightmaps would limit us to raising and lowering the terrain due to it’s two dimensional nature.
There is very few other ways of handling terrain, the most popular being “Voxels”.
Voxels or volumetric (3D) pixels are building blocks of a lot of games, especially sandbox games, from No Man’s Sky, Space Engineers, Minecraft and many more, basically every time you find yourself in a game where you can freely dig or manipulate the terrain it’s very likely some form of voxels.
But Voxels are far harder to handle and have a lot more complexity, which in turn impacts calculations/render times and network load. But we wouldn’t have gone for voxels if we weren’t sure we really needed them, especially considering this isn’t exactly an easy or small topic for any game, it’s quite literally the foundation of the game’s world.
But just knowing that we want or need to use Voxels is not enough so I began researching on the topic, to see what others are doing with voxels and what we can do to avoid the blocky look as that would not quite fit with the semi-realistic style we want to aim for.
While we want to utilize Voxels to create an interesting looking terrain with caves, overhangs and nice cliffs, they have much more potential than that. It’s really impressive to see that people are able to have voxels fully dynamic and physically interacting with everything and even volumetric smoke using Voxels.
Suffice to say there is lots that can be achieved with Voxels and while I don’t think I will be experimenting with Voxels outside of the terrain it’s still going to be a very important part and hopefully merges well with the rest of the gameplay we have planned.
The first step is to create a three dimensional world filled with voxels according to some form of noise.
Now there is one question that remains, how do we create a terrain from this that looks realistic and organic?
Wikipedia: “An isosurface is a three-dimensional analog of an isoline. It is a surface that represents points of a constant value (e.g. pressure, temperature, velocity, density) within a volume of space; in other words, it is a level set of a continuous function whose domain is 3D-space.“
A bit convoluted I admit, but an Isosurface describes the surface of specific values in a three dimensional area – in our case this would be our voxels. For example to describe the shape or rather surface of clouds, depending – among other things – on moisture/density (determining the “edge” of the cloud). Another use case are medical scans, like CT scan, which produces layers of two dimensional data that represent human tissue, this can be represented three dimensionally using Isosurfaces, which is actually where a lot of the research leads to, because really knowing how a fractured bone looks or some damaged organs can help finding the correct treatment and understanding these types of injuries tremendously.
But it can be a little difficult to understand how Isosurfaces are meant to work without visual aid, so here are some examples:
Take this 10 by 10 grid of values (fig. 1), represented by shades of grey (NO, just don’t.)
Depending on what you are looking for you will need to determine the threshold value.
This can be rather arbitrary for most cases, but it depends what you are trying to create a surface for and what your data looks like, ours are just random greyscale values from 0 to 1.
Now the threshold is used to determine at which point our data or noise is to be interpreted as part of the object or not. Only once we know which voxels are “solid” can we continue and actually create a surface for it.
If we set the threshold too low, we end up with too much surface and might lose details, since it will take more values into account. (fig. 2)
On the other hand, if we overtune the threshold, we might end up with the opposite: too little left, leaving the remaining surface fractured or even torn apart. (fig. 3)
Generally I did not have to worry about the threshold, so it is quite arbitrary at some value ~0.7, but really depends on the type of data and the way it is generated.
As a sidenote: Minecraft does this too, it determines what blocks are actual “solid” terrain like Stone, Dirt and Ore – and the rest is just considered to be “air”.
Once we are certain what blocks are actual part of the terrain, we can move on and generate the surface and preferably smooth it to get rid of terracing artefacts and jagged edges where the original data does not intend such.
There are a couple of ways of going about it, but I want to keep things at least somewhat simple and it would be nice to retain the ability of looping through every block so here are our best candidates:
Note that these are only some options that I looked into and that were halfway decently explained on the internet.
Needless to say, as the title is a bit of a spoiler, we picked Surface Nets, but I will briefly go over all three of them.
The first I heard about Marching Cubes and really the catalyst that led me down this rabbit hole of surface constructing, was this video on it:
The general idea is to march (loop) through every position of the world and depending on surrounding blocks, where our threshold and noise comes into play, construct the mesh according to (usually) predetermined shapes via a lookup.
This has the tremendous advantage of having barely no calculations for the mesh construction, as you are just checking neighboring blocks and lookup the corresponding arrangement of vertices and faces to put in. Though the logic on that can get a bit headache inducing, so I won’t cover that here.
Marchin Tetrahedra works similarly but the resulting mesh will end up having quite a lot more vertices and faces, which can be nice, but it also is a lot less GPU friendly, due to it’s massively more complex mesh.
But Marching Cubes itself (Marching Tetrahedra certainly not) is pretty lightweight in terms of the result, the amount of faces and vertices created is pretty low, further increasing the efficiency potential of the algorithm.
But if Marching Cubes is so good how come we did not pick it over Surface Nets? To be completely honest: Looks. Granted it sounds superficial, but if we weren’t bothered with looks we might as well just use a heightmap and call it a day.
Creating a voxel terrain from cubes is actually pretty easy with tons of guides and tutorials out there. Ideally we could just use that and just smooth it a bit; This is where Surface Nets comes into play, it takes a regular cube-like voxel world and just: Smoothes all corners iteratively.
This sounds really great and easy to implement, but it’s not quite as easy…
For a regular Minecraft-like voxel world in all its cube-y glory you loop through all positions of the world and generate a cube whereever you encounter a so-called “solid” voxel that has non-solid voxels adjacent to it, plus points for only creating the faces and their vertices that can be seen.
The only thing left to do is move the vertices – the corners of each cube – toward some smoother position as much or as little as we like and pat ourselves on the back, but how do we move the vertices and how do we get this “smooth position”?
Instead of focussing on one voxel at a time, we need to shift gears and only focus one intersection – one vertex – at a time. First we need to define the Surface Net:
We loop through every position.
We check the neighboring voxels but only in positive direction (to avoid duplicate entries)
If all neighbors and the current voxel are the same, they are either ALL inside or ALL outside of the terrain, so skip to the next and repeat.
Should any of the surrounding voxels differ from the currently observed we add the current voxel to the list as it is considered a surface (net) voxel.
After we have looped through every voxel we have our complete list of vertices. We also need a list of all neighbors for each vertex.
// Start at x, y and z = -1 to account for the fact
// that we only check neighbors and create mesh in positive direction
for (int x = -1; x < world.worldSize; x++)
{
for (int y = -1; y < world.worldSize; y++)
{
for (int z = -1; z < world.worldSize; z++)
{
// check 8 neighboring voxels
int sum = 0;
for (int dx = x; dx <= x + 1; dx++)
{
for (int dy = y; dy <= y + 1; dy++)
{
for (int dz = z; dz <= z + 1; dz++)
{
// If a voxel exists, add one to our (check-)sum
if (voxels[new Vector3Int(dx, dy, dz)])
sum++;
}
}
}
// The sum is only 0 or 8 if all checked blocks are the same
if (sum % 8 != 0)
{
// Surface Cube found, add Vertex
surfaceNet.Add(new Vector3Int(x, y, z), new Vector3(x, y, z));
}
}
}
}
The resulting list of vertices describes our terrain surface:
Progress!
Now we can loop through every one of those vertices (substantially less than every possible position of the world) and apply some… math.
The “Naive” approach is to simply average all adjacent vertices current position and move the current vertex toward that position. So basically just linear interpolating between those points. Then repeat the process with the new positions as often as you like and voilà:
… eh?
Is it just me or did it shrink? Yes, yes it did. And for good reason!
Unless we have infinite time and an infinite terrain, the average position of the voxels will converge in the center of the mesh. This effect is stronger the closer a voxel is to the border and the more iterations we do.
And there are more problems. Firstly we had cases where the mesh would fold in on itself after too many iterations and the second was a problem where the terrain was turning too smooth after the first few iterations.
The first problem is a bit tricky, but Sarah F. Frisken Gibson already had this problem back in 1999 and described a solution to it in her paper:
…to remain faithful to the original segmentation, a constraint is applied that keeps each node inside its original surface cube…
So that is exactly what we will be doing: restricting a vertex’s position to be always inside it’s origin “cube”.
The latter issue can be solved surprisingly easy, just by making sure the effect of each iteration is always a little bit weaker than the last. This way we can have a handful of iterations without the terrain getting too smooth at places where it really shouldn’t.
But I won’t go into detail on these problems and solutions because that would easily double or triple this already long post.
Now instead of just interpolating every corner (vertex) position with one another, say we could mathemagically calculate a relation table, as a matrix, for every vertex in the whole system / terrain.
This means that we know all forces every vertex is subjected to (pushing and pulling from their neighbors). With this we can take the current, future and previous positions into account for an explicit calculation. So it’s similar to the original approach where we adjusted positions each iteration, only that we now take into account the final “optimal” position each vertex should try to aim for, as well as the previous position of that vertex.
Alternatively we can use an implicit approach that reverses our logic; It starts from the future position of each vertex and tells us exactly where we should move our vertices to, this depends on a few constants that we can control to adjust the final result to our liking.
I am obviously heavily simplifying here but for anyone interested, this is the formula used to calculate the explicit position:
While the implicit method is very precise and potentially the most accurate in terms of retaining features of the original terrain, it is also the most complex mathematically speaking and involves a lot of calculations with matrices.
This results in the worst performance out of all methods so far (though we haven’t done a terribly well job optimizing it). It is important to mention that all the heavy lifting is only done once at the beginning, to calculate the relation matrix and some inverse matrices that are needed to get the result.
Since we want to be able to interact and edit the terrain at runtime – i.e. digging, mining and so on – we opted to favor the explicit method, at least out of these two, even if it is a bit less stable.
I should probably go into what “less stable” means.
This is a visualization of what the explicit method does (simplified). Now we need to make sure that the position is never outside the boundaries. To achieve this, we may nudge the position back in the opposite direction, this can lead to overcorrecting and produces oscillation of the vertex position where we constantly overshoot the boundary and then move the vertex back too much, resulting in a very spiky terrain:
For now we have fixed it pretty simple with some spring constant to counteract an overshoot and a dampening constant that makes sure we don’t overdo that either. But even with those two constants it’s still a bit volatile sometimes (when we change any of the settings), hence: unstable.
And while I am extremely impressed that all of this matrix stuff actually works, since I never used anything as math heavy like this in calculations before, it hasn’t exactly been working right away…
But after we sorted out some bugs, simplified the source code and fine tuned the constants for the oscillations, the results of the explicit method were pretty satisfying as well.
All the calculations and formulas have been created by Paul, there is a file with the formulas and explanations (in german) at the end of this post.
When we take away the implicit matrix based method we end up with two ways of doing basically the same thing:
I added logs for time for both the smoothing and the generation of the surface net prior to it (to reduce bias).
The image above with a chunk size of 32³ had the following times:
Needless to say we dropped the implicit method, while it wasn’t anywhere near full optimization, it was so far worse than the rest that further work would have been a bit pointless for our use case.
Explicit actually got improved quite a bit from it’s initial >500ms and there still seems some room for improvement, especially with the option to have some it pre-calculated and hard code it in, but we leave that for another time.
It’s also important to note that while the linear interpolation yielded it’s results the fastest, it’s also scaling linearly with every iteration much like the explicit method does, but the bulk of calculation of the explicit method is done before the iterative part so more iterations will put the explicit method into a better ratio when we do lots of iterations, but from what we tested just 3-5 iterations was already enough to yield good results.
It was also interesting to see how well each method would stack up with something less smooth.
Aside from the aforementioned issue with the Surface Net “contracting” I also still have to find a way to stitch chunks together without making an obvious seam as well as thinking about an LOD system so terrain can be viewed from afar without melting the hardware.
But most of this is not as complicated and more a matter of making it look right, it’s also nothing exclusive to Surface Nets, so I am not too worried about solving that, yet.
Also I know that the performance would get quite the boost if I switched the smoothing calculations to run on multiple threads, but that’s another topic I really have to understand before implementing any of it, for now I am satisfied with the performance and keep multithreading on the back of my head for when I inevitably need to improve the performance.
That’s pretty much it, I will keep sharing progress on this as long as it’s interesting enough to write about. Since this is an inheritely complicated topic and I want to make this understandable, to help people like me who are trying to get behind stuff like this in the future, let me know if you feel something is unclear or not specific enough. I am also still uncertain if the length of this post is good or if I should split it into multiple posts next time, any constructive feedback is appreciated here as well.
Cheers!
Force.pdf – A breakdown of the calculations used in the explicit and implicit method, in german by Paul T.
Be careful, any of this could change at any time.