As mentioned in the last blog post, I've made mistakes whilst implementing the Wave Function Collapse algorithm. Within the system I detailed in the post "The Initial Wave Function Collapse Code", ideas of how stuff will work have changed over time. For example, tiles were going to use a sockets based system, before I decided to have adjacency rules listed on them instead from the input model. Here are a few errors I created and fixed before this point:
1. Calculating entropy (division by 0):
When searching through the grid for the tile with the least amount of entropy (calculated using Shannon's Entropy) they were NaN (Not a Number). This will always return false when compared with the float values, causing problems with choosing tiles. The reason the entropy was becoming 0, was because during the calculation I would divide by 0, since that's the tile's frequency. It was 0 because was not in my Input Model at the time, so in the future I will make sure not to add tiles that weren't in the input model used.
2. Propagation woes:
To get the initial output grid to generate I made a simpler method of propagation I called the "Brute Force" method (based on this idea of a similar name). The process is to go through the grid and apply constraints to the tile based on it's neighbours. If it did have to apply any constraints, start from the beginning and start checking the grid again. But I did try what the more correct and efficient method too, which would create infinite loops. In fact this happened for more than 1 reason.
One infinite loop was due to a mistake on my part when passing the neighbours through... not null checking them. At the time, I had it be an array and didn't mind passing through the null cells. This was a mistake since it meant that I could forget to check them in other parts. In more recent times I've made it a list of cells and it only contains known cells. Another infinite loop was due to not popping off completed cells from the stack. The first neighbours are added separately and may already have collapsed (which at the time I had forgotten to check).
3. Adjacency rules mistake:
Testing propagation became harder due to an error in the method which applied the constraints. I compared all the theoretical possibilities of all the neighbours, which means that all the possibilities which weren't compatible with all other possibilities were being removed. This left my level only putting down dirt tiles after the first collapsed tile.
Combining these issues can create some very bland maps... if it hadn't crashed from an infinite loop accidentally created. But breakpointing and stepping through the code let me realise what was happening when the issues cropped up. Since it had taken me some time to put the systems in place and setup the input model correctly, I had done much of the algorithm without checking some code.
Also I used a few online examples of code for logical help when looking at my algorithm, although none of the code can be applied directly.
These include:
Boris the Brave's repository and connected article
A Rust tutorial by BracketProductions
It became clear to me that type of Wave Function Collapse model I am programming is the simple tiled model. It evolved this way due to the simplicity and practicality in getting the project to function. This is also what made me realise that the scope of the project may be ambitious for a short term project like I was hoping it would be.
A longer introspection and evaluation of the project will be needed when it's complete for the short term I had planned on working on it in. It may return to be finished at a future date.
Comments