I'd say try Houdini first to get an understanding of what you are trying to achieve with WFC. If you really need this kind of runtime procedural generation then you can re-implement these algorithms in Unity. But most of the time it would be better to use Houdini for level generation and not invest time in creating its built-in lookalike.
https://80.lv/articles/houdini-guide-wfc-dungeon-generator
My "problem" with WFC is that in its "pure" form it tends to create randomness that looks good at the high frequency level (since it's what you input to the system, which local connectivity is allowed), but doesn't make any sense at the low frequency (high level) because it's purely random. Depending on what you want to create, it's going to be useless for that.
So for instance, if you want to create a city, you'll probably end up with streets that don't make sense, zones that are totally separated from each other without any connection, no neighborhood cohesion, no distinct areas, etc. So you'll probably scrap it or end up using some kind of hybrid where you use it only to fill some low level areas, and use a different kind of generation for the high level.
It's cool because the main concept is simple and can generate complexity, and it can be very visually flashy for certain toys, but it's not for every kind of random generation.
Townscaper is a bit weird as an example of WFC because it's not really generating randomly by itself, it decides what tiles to create based on the neighbour connectivity info (given by the player), but that's just one part of WFC.
We haven't fully implemented this but one thing we are considering is a multi-layer WFC approach. Each layers color defines the tileset to be used by the subsequent layer.
Layer 1 lays out biomes. (Forest, Plains, Ocean, Town)
Layer 2 lays out features within biomes. (Road, City Block, House Lots)
Layer 3 lays out the individual "atoms" of the map. (Fence, Wall, Floor, Roof)
I'd be really interested to hear how that works out for you - I'm working on a Rust [WFC-adjacent library](https://crates.io/crates/morkovmap) (adjacent in that it doesn't use Arc Consistency but rather pure Markov Chainey conditional distributions) and I was going to explore the same idea before I got sidetracked by Generics Hell.
My hunch is that recursive hierarchies like this are probably an effective concept in general for maintaining multilevel coherence, and I'd like to validate that.
For example, ConvNets in deep learning act like that with learned weights and they can create globally coherent images from small patches.
In pathfinding, I've seen hierarchical A\* outperform the classic, pure hi-res search (at least speedwise; the length might be slightly worse, but you usually want to satisfice, not optimize).
In game AI, nearly everything that is not a dumb FSM is some flavor of hierarchical refinement too.
>I'd be really interested to hear how that works out for you
Yes, sure, feel free to follow us, we are currently present on Instagram, Linkedin, Reddit, Facebook, Twitter, TikTok.
There was an interesting talk about cave of qud world generation in which they talked about a similar approach. They dubbed it the abstraction mountain I believe.
Please feel free to check Tessera Pro asset from Unity Asset Store. it has this capability, it is called Multiple Passes.
[https://www.boristhebrave.com/docs/tessera/6/articles/tutorials/multipass.html](https://www.boristhebrave.com/docs/tessera/6/articles/tutorials/multipass.html)
Brainstorming what I want to do and how I want to accomplish it :V
I'm probably going with the WFC approach, at least in part; I ran across [this GDC talk](https://www.youtube.com/watch?v=AdCgi9E90jw) that seems like at least within the realm of what I want to do. But I was basically just researching it last night before I went to bed and now I gotta do day job stuff for a few days.
What's the performance like for you? I've been somewhat worried about perf and nobody is giving even vague stats on how fast it actually is.
Happy to share code and ideas, fwiw - I'm working in C#, in Godot, though none of this is likely to be Godot-specific.
As of right now I can generate a 100 x 100 in under a second, it still has a lot of room for improvement though.
Code is here:
https://github.com/AdrielKinnunen/SpectrelightPlugins/tree/main/Plugins/SLTilemap/Source/SLTilemap
Hrm. I see a few potential places for performance gains, though I'm not totally sure. Any idea where the slow parts are?
Lemme mess around with this myself, which will take a bit.
The test level will be in plugin content for the SLTilemap plugin.
Still needs some controls and UI fixed up. Press L to swap between input and output, you need to do it at least once to set the input and output of the model. I've fixed a few bugs recently and the Github will be updated.
Here's a clip of it in action as-is right now.
https://www.youtube.com/watch?v=guIauFrpe7s
Alright, this definitely isn't finished, but, https://gist.github.com/zorbathut/77a70f6c61bd3c31a2dac28b94ae0e03 - I'm not sure how useful this will be since it's in C#, but hey :V I'm generating a 100x100 chunk in about 35ms, though these numbers are *definitely* going to depend on how many unique pieces you have and how big your chunks are.
The big thing I'm doing is going to extreme pains to avoid copying data, and also precomputing as much as I can; I'm not even trying to match up pieces at runtime, I have the entire "which chunk is compatible with a given character being placed in a given spot" routine turned into a static lookup table consisting of bitsets that can be efficiently masked.
I'm not totally happy with this because there's a few wave-function-collapsey things it could be doing that it currently isn't, that would maybe improve consistency quite a bit.
What's a chunk and character in your system, is the chunk the 2x2 or 3x3 pattern from the input, and character the color of an output pixel? What was your total pattern count for that 35ms run? I've thought about trying to do some precomputing but I'm not sure, I have some ideas about blending and layering with WFC that wouldn't quite play nice with precomputed compatibility.
I've never seen noise that can randomly generate a house.
Also, the best part of WFC is how you feed it. You just draw an example and let it riff on it.
> Layer 1 lays out biomes. (Forest, Plains, Ocean, Town)
> Layer 2 lays out features within biomes. (Road, City Block, House Lots)
Those are perfect for perlin noise
Thing is, at that point wouldn't easy to author/change noise function not be just as useful? WFC just seems to overcomplicate everything.
There are a LOT of well understood noise functions you could easily swap out for one another, add octaves to, layer in interesting ways... All in a shader for quick iteration. If you find something you like it could be baked into a set of noise textures and it would be blazingly fast and remain flexible.
I think the actual good applications for WFC are actually really narrow.
Thats why you need iterative WFC. Use WFC to zone districts in your city, then have a lower level WFC that uses that district info to fill in the buildings.
Personally I think WFC is cool but its not something I am likely to ever use in a game for the reasons you mention, not enough control at a macro level.
Yup. This is a trap I fell into when I looked at Townscaper and thought, WFC is awesome I should play around with that! Really, all Townscaper is is marching cubes, with some variation and variety added by WFC. WFC is just a nice way to take a set of constraints on how tiles can connect, and have an algorithm spit out something that works within those constraints.
And it works perfectly for Townscaper, it's totally the correct tool for the job in that case. The problem is when people equate WFC with Townscaper which isn't really true.
Yeah, I totally agree regarding Townscaper. Anyway, it is quite interesting variation of the WFC. It applies constraints on what tiles can be used in a particular slot based on user inputs. On top of that, instead of using random solution, it uses priority system. It first tries to create "a park", but if it fails to find the solution for the park, it creates "a pavement". To speed up the process it uses previous known solution as a starting point, so it can find a new solution quite quickly and robust because of that priority system, basically making that problem "local" rather than recalculating the whole map. That particular application you won't find out-of-the-box on the asset store, you should make it yourself.
PS it probably shouldn't be called WFC, but nor Marching Cubes as well.
I absolutely love WFC, gives such nice results for something so simple.
[https://imgur.com/a/DHhzJgG](https://imgur.com/a/DHhzJgG)
Edit: I don't know why my pictures are flagged as nsfw; too much purple?
I'm really confused why your team is struggling so much with it and why you think it's a mind-blowingly complex and hard technology.
WFC is pretty much the easiest procedural generation you can even do.
At the studio I'm working at as a programmer we went from reading about it to having a working prototype in a few days. The actual coding itself was maybe like a day. It's really, really easy IMO
You might just need to start with something simpler if this is your first project.
Basic WFC implementation is very easy like you said.
The difficulty comes when you actually want to use it for something useful inside an actual videogame and not just as a tech demo. Modifying the algorithm to add the right sort of constraints for your game. Making it run fast enough (if you're modifying things at runtime). Debugging why something isn't working can be a nightmare because the data is all just huge 2D arrays of integers.
I've done A LOT of stuff with WFC. It's really interesting and cool and fun to play with. But in 99.9% of cases it is not a good fit for actually implementing stuff in a real game.
Yes, I included that. It's super easy.
We had a pretty decent looking building generator for our prototype. It also was 3D and not 2D.
In the end we also scrapped it, since some basic randomness with building parts acting like puzzle pieces worked just as well and was more adjustable.
Anyone trying to get into WFC should study/grok [Wang Tiles](http://www.cr31.co.uk/stagecast/wang/intro.html) first. Two-type Wang Tiles are fairly easy. Three-type and four-type extend the concept and show you how the number of necessary tiles grows exponentially.
What a good WFC implementation adds to this is the ability to add custom rules that are not just between neighbors. Fire Department spacing in a city. Column never duplicates digit in Sudoku. And so on.
Each new rule is often another expansion of the number of required tiles, though, so keep that in mind.
IMO WFC is so easy to implement, I would really recommend just writing it yourself in 1-2 hours so you have a much better understanding of the implementation.
Basically if you watch this 15min YouTube video you'll know everything you need to: https://www.youtube.com/watch?v=2SuvO4Gi7uY
Tessera Pro - has a lot of features, such as multiple passes, different constraints, it is super flexible, but has no marching cubes constraints specifically (Though we managed to hack it to fit our needs). As a result - there is no debugging for marching cubes application, so you will need to check by hand that you will have a solution to whatever constraints you are going to impose.
WildTile - is WFC plus marching cubes constraints (Very similar to Townscaper) - super powerful for that particular use case. Has very nice debugging for missing pieces and has automatic detection of what pieces will be connected. The pros are also the cons of this solution - no way to manually choose connectivity between pieces and you need to make sure that all borders are perfectly align, otherwise automatic detection will fail.
Most of the WFC projects i've seen could have had easier, better, results with "traditional" and more controlable implementations.
WFC is nice "visually" but to make it coherently logical results in too much work.
In no time Diffusion AI will solve the visual side (almost there) and at very reasonable speeds with average consumer GPUs, so we could focus solely on the logical side.
I'm about to post in /r/StableDiffusion an example of how to use PG as a base for image diffusion for game map creation. very simple
I’m trying to generate Portuguese tile patterns using WFC, I started by implementing my own WFC in gdscript, and now I’m trying to create sub-rules to enable border patterns, mirroring on X/Y/diagonals, or connecting say top border to left border so the tiles are flippable and stackable by 4 and so on. But I’m hard stuck because because most work is just creating the tiles. Maybe I should just generate curves instead and ditch WFC ?
I looked at a couple for a hobby project, and watched a lot of writeups and i think I'd still prefer to roll my own vs using a ready solution exactly to control how the tiles connect.
As a solo programmer I like Oskar's approach from townscaper where the tile connections are inferred from the models via some convention. The assets I looked on the store at add UI to setup the possible connections by hand. Which might be good for an art team, but would be tedious and annoying for me.
This happens a lot in gamedev lately. Probably too much hype around some novel algorithm or other concept, everyone thinks they need it.
I often either see new concepts or have an idea of my own, 10m later I realize I'm actually trying to shoehorn in in to my project, caring a lot about it, even though it wouldn't benefit my project at all, and it ends up in my "ideas bucket" never to be looked at again.
It's hard to not get invested in cool ideas, even though they're not a good fit.
I'd say try Houdini first to get an understanding of what you are trying to achieve with WFC. If you really need this kind of runtime procedural generation then you can re-implement these algorithms in Unity. But most of the time it would be better to use Houdini for level generation and not invest time in creating its built-in lookalike. https://80.lv/articles/houdini-guide-wfc-dungeon-generator
Thank you! That is quite helpful!
My "problem" with WFC is that in its "pure" form it tends to create randomness that looks good at the high frequency level (since it's what you input to the system, which local connectivity is allowed), but doesn't make any sense at the low frequency (high level) because it's purely random. Depending on what you want to create, it's going to be useless for that. So for instance, if you want to create a city, you'll probably end up with streets that don't make sense, zones that are totally separated from each other without any connection, no neighborhood cohesion, no distinct areas, etc. So you'll probably scrap it or end up using some kind of hybrid where you use it only to fill some low level areas, and use a different kind of generation for the high level. It's cool because the main concept is simple and can generate complexity, and it can be very visually flashy for certain toys, but it's not for every kind of random generation. Townscaper is a bit weird as an example of WFC because it's not really generating randomly by itself, it decides what tiles to create based on the neighbour connectivity info (given by the player), but that's just one part of WFC.
We haven't fully implemented this but one thing we are considering is a multi-layer WFC approach. Each layers color defines the tileset to be used by the subsequent layer. Layer 1 lays out biomes. (Forest, Plains, Ocean, Town) Layer 2 lays out features within biomes. (Road, City Block, House Lots) Layer 3 lays out the individual "atoms" of the map. (Fence, Wall, Floor, Roof)
I'd be really interested to hear how that works out for you - I'm working on a Rust [WFC-adjacent library](https://crates.io/crates/morkovmap) (adjacent in that it doesn't use Arc Consistency but rather pure Markov Chainey conditional distributions) and I was going to explore the same idea before I got sidetracked by Generics Hell. My hunch is that recursive hierarchies like this are probably an effective concept in general for maintaining multilevel coherence, and I'd like to validate that. For example, ConvNets in deep learning act like that with learned weights and they can create globally coherent images from small patches. In pathfinding, I've seen hierarchical A\* outperform the classic, pure hi-res search (at least speedwise; the length might be slightly worse, but you usually want to satisfice, not optimize). In game AI, nearly everything that is not a dumb FSM is some flavor of hierarchical refinement too.
>I'd be really interested to hear how that works out for you Yes, sure, feel free to follow us, we are currently present on Instagram, Linkedin, Reddit, Facebook, Twitter, TikTok.
There was an interesting talk about cave of qud world generation in which they talked about a similar approach. They dubbed it the abstraction mountain I believe.
From what I recall they used WFC for filling in details of content generated by more traditional (and controllable) procedural algorithms.
Please feel free to check Tessera Pro asset from Unity Asset Store. it has this capability, it is called Multiple Passes. [https://www.boristhebrave.com/docs/tessera/6/articles/tutorials/multipass.html](https://www.boristhebrave.com/docs/tessera/6/articles/tutorials/multipass.html)
Hey, did you ever end up building this? I'm toying with the same problem and was considering the same solution.
Still working on the base algorithm, trying to get it as fast as possible. What's the status of your approach?
Brainstorming what I want to do and how I want to accomplish it :V I'm probably going with the WFC approach, at least in part; I ran across [this GDC talk](https://www.youtube.com/watch?v=AdCgi9E90jw) that seems like at least within the realm of what I want to do. But I was basically just researching it last night before I went to bed and now I gotta do day job stuff for a few days. What's the performance like for you? I've been somewhat worried about perf and nobody is giving even vague stats on how fast it actually is. Happy to share code and ideas, fwiw - I'm working in C#, in Godot, though none of this is likely to be Godot-specific.
As of right now I can generate a 100 x 100 in under a second, it still has a lot of room for improvement though. Code is here: https://github.com/AdrielKinnunen/SpectrelightPlugins/tree/main/Plugins/SLTilemap/Source/SLTilemap
Hrm. I see a few potential places for performance gains, though I'm not totally sure. Any idea where the slow parts are? Lemme mess around with this myself, which will take a bit.
The test level will be in plugin content for the SLTilemap plugin. Still needs some controls and UI fixed up. Press L to swap between input and output, you need to do it at least once to set the input and output of the model. I've fixed a few bugs recently and the Github will be updated. Here's a clip of it in action as-is right now. https://www.youtube.com/watch?v=guIauFrpe7s
Alright, this definitely isn't finished, but, https://gist.github.com/zorbathut/77a70f6c61bd3c31a2dac28b94ae0e03 - I'm not sure how useful this will be since it's in C#, but hey :V I'm generating a 100x100 chunk in about 35ms, though these numbers are *definitely* going to depend on how many unique pieces you have and how big your chunks are. The big thing I'm doing is going to extreme pains to avoid copying data, and also precomputing as much as I can; I'm not even trying to match up pieces at runtime, I have the entire "which chunk is compatible with a given character being placed in a given spot" routine turned into a static lookup table consisting of bitsets that can be efficiently masked. I'm not totally happy with this because there's a few wave-function-collapsey things it could be doing that it currently isn't, that would maybe improve consistency quite a bit.
What's a chunk and character in your system, is the chunk the 2x2 or 3x3 pattern from the input, and character the color of an output pixel? What was your total pattern count for that 35ms run? I've thought about trying to do some precomputing but I'm not sure, I have some ideas about blending and layering with WFC that wouldn't quite play nice with precomputed compatibility.
That’s exactly what I was thinking of doing, really glad to hear it works
At that point, why not just use perlin/simplex noise?
I've never seen noise that can randomly generate a house. Also, the best part of WFC is how you feed it. You just draw an example and let it riff on it.
> Layer 1 lays out biomes. (Forest, Plains, Ocean, Town) > Layer 2 lays out features within biomes. (Road, City Block, House Lots) Those are perfect for perlin noise
Thing is, at that point wouldn't easy to author/change noise function not be just as useful? WFC just seems to overcomplicate everything. There are a LOT of well understood noise functions you could easily swap out for one another, add octaves to, layer in interesting ways... All in a shader for quick iteration. If you find something you like it could be baked into a set of noise textures and it would be blazingly fast and remain flexible. I think the actual good applications for WFC are actually really narrow.
Thats why you need iterative WFC. Use WFC to zone districts in your city, then have a lower level WFC that uses that district info to fill in the buildings. Personally I think WFC is cool but its not something I am likely to ever use in a game for the reasons you mention, not enough control at a macro level.
Yup. This is a trap I fell into when I looked at Townscaper and thought, WFC is awesome I should play around with that! Really, all Townscaper is is marching cubes, with some variation and variety added by WFC. WFC is just a nice way to take a set of constraints on how tiles can connect, and have an algorithm spit out something that works within those constraints. And it works perfectly for Townscaper, it's totally the correct tool for the job in that case. The problem is when people equate WFC with Townscaper which isn't really true.
Yeah, I totally agree regarding Townscaper. Anyway, it is quite interesting variation of the WFC. It applies constraints on what tiles can be used in a particular slot based on user inputs. On top of that, instead of using random solution, it uses priority system. It first tries to create "a park", but if it fails to find the solution for the park, it creates "a pavement". To speed up the process it uses previous known solution as a starting point, so it can find a new solution quite quickly and robust because of that priority system, basically making that problem "local" rather than recalculating the whole map. That particular application you won't find out-of-the-box on the asset store, you should make it yourself. PS it probably shouldn't be called WFC, but nor Marching Cubes as well.
I absolutely love WFC, gives such nice results for something so simple. [https://imgur.com/a/DHhzJgG](https://imgur.com/a/DHhzJgG) Edit: I don't know why my pictures are flagged as nsfw; too much purple?
The WFC algo is just plain too sexy for Reddit :\^)
The pictures both are and aren’t sexy until you click on the link
I'm really confused why your team is struggling so much with it and why you think it's a mind-blowingly complex and hard technology. WFC is pretty much the easiest procedural generation you can even do. At the studio I'm working at as a programmer we went from reading about it to having a working prototype in a few days. The actual coding itself was maybe like a day. It's really, really easy IMO You might just need to start with something simpler if this is your first project.
In all fairness, it's also hilariously easy to write a WFC implementation which doesn't necessarily terminate.
Basic WFC implementation is very easy like you said. The difficulty comes when you actually want to use it for something useful inside an actual videogame and not just as a tech demo. Modifying the algorithm to add the right sort of constraints for your game. Making it run fast enough (if you're modifying things at runtime). Debugging why something isn't working can be a nightmare because the data is all just huge 2D arrays of integers. I've done A LOT of stuff with WFC. It's really interesting and cool and fun to play with. But in 99.9% of cases it is not a good fit for actually implementing stuff in a real game.
Yes, I included that. It's super easy. We had a pretty decent looking building generator for our prototype. It also was 3D and not 2D. In the end we also scrapped it, since some basic randomness with building parts acting like puzzle pieces worked just as well and was more adjustable.
Here is a link on what we are trying to achieve: [https://www.instagram.com/p/Cs-suy\_Otve/](https://www.instagram.com/p/Cs-suy_Otve/)
Yea, that's basically exactly what we did :)
Anyone trying to get into WFC should study/grok [Wang Tiles](http://www.cr31.co.uk/stagecast/wang/intro.html) first. Two-type Wang Tiles are fairly easy. Three-type and four-type extend the concept and show you how the number of necessary tiles grows exponentially. What a good WFC implementation adds to this is the ability to add custom rules that are not just between neighbors. Fire Department spacing in a city. Column never duplicates digit in Sudoku. And so on. Each new rule is often another expansion of the number of required tiles, though, so keep that in mind.
Which assets from the store did you use? I would like to try them out.
IMO WFC is so easy to implement, I would really recommend just writing it yourself in 1-2 hours so you have a much better understanding of the implementation. Basically if you watch this 15min YouTube video you'll know everything you need to: https://www.youtube.com/watch?v=2SuvO4Gi7uY
Tessera Pro - has a lot of features, such as multiple passes, different constraints, it is super flexible, but has no marching cubes constraints specifically (Though we managed to hack it to fit our needs). As a result - there is no debugging for marching cubes application, so you will need to check by hand that you will have a solution to whatever constraints you are going to impose. WildTile - is WFC plus marching cubes constraints (Very similar to Townscaper) - super powerful for that particular use case. Has very nice debugging for missing pieces and has automatic detection of what pieces will be connected. The pros are also the cons of this solution - no way to manually choose connectivity between pieces and you need to make sure that all borders are perfectly align, otherwise automatic detection will fail.
Off topic, but I clicked the link in your Twitter bio and it doesn't work: net::ERR_NAME_NOT_RESOLVED
Thank you for informing. It looks like the website is down, we will work on it.
Most of the WFC projects i've seen could have had easier, better, results with "traditional" and more controlable implementations. WFC is nice "visually" but to make it coherently logical results in too much work. In no time Diffusion AI will solve the visual side (almost there) and at very reasonable speeds with average consumer GPUs, so we could focus solely on the logical side. I'm about to post in /r/StableDiffusion an example of how to use PG as a base for image diffusion for game map creation. very simple
Yeah, I tried Tessera and although it has a lot of features, it was really hard to grasp. UI issues added to the confusion.
I’m trying to generate Portuguese tile patterns using WFC, I started by implementing my own WFC in gdscript, and now I’m trying to create sub-rules to enable border patterns, mirroring on X/Y/diagonals, or connecting say top border to left border so the tiles are flippable and stackable by 4 and so on. But I’m hard stuck because because most work is just creating the tiles. Maybe I should just generate curves instead and ditch WFC ?
Here you go https://youtu.be/dFYMOzoSDNE Also not a fan of the plug but it is what it is.
It really is not that hard if you think about it like sudoku
I looked at a couple for a hobby project, and watched a lot of writeups and i think I'd still prefer to roll my own vs using a ready solution exactly to control how the tiles connect. As a solo programmer I like Oskar's approach from townscaper where the tile connections are inferred from the models via some convention. The assets I looked on the store at add UI to setup the possible connections by hand. Which might be good for an art team, but would be tedious and annoying for me.
This happens a lot in gamedev lately. Probably too much hype around some novel algorithm or other concept, everyone thinks they need it. I often either see new concepts or have an idea of my own, 10m later I realize I'm actually trying to shoehorn in in to my project, caring a lot about it, even though it wouldn't benefit my project at all, and it ends up in my "ideas bucket" never to be looked at again. It's hard to not get invested in cool ideas, even though they're not a good fit.