I am so glad I found this. I have been struggling so bad with how to implement everything I wanted to accomplish. I have gone through so many PG algo's to get what this does. Now I just need to work on some advanced pathfinding and smart placement of prefabs/scenes.
Procedural generation is quite difficult if you don't have a lot of experience with it. It's essentially always the same concept; wrangling noise into something coherent. This video is on wave function collapse, but I also have another that goes over cellular automata to make a terraria style map with auto updating neighbours. Hope you find the content useful and thanks for watching!
@@hamsterbyte I'm going to go and look for that right now. Cellular automata is what I'm using right now for my maze game. I got the first part figured out. Now I need to do the pathfinding and backtracing etc. But I'm loving the idea of having the code randomize the maze so you don't have the same one twice!
@@shanefoster5305 obviously for pathfinding you will want to use some variation of Dykstra's or A*. The main thing to remember is if you are generating the maps procedurally, you will also need to populate the data for the algorithm after the generation is completed to calculate the nav mesh and weights/values
@@hamsterbyte Thanks I'll look into that. I was just going to modify Wilson's maze algorithm to 3d and then at dead ends place a door that teleports them to the rooms that would be elsewhere. Wilson's maze has pathfinding in it while generating the maze. But your recommendations might be more appropriate and possibly easier.
Working on another video right now actually. Most of my stuff is relatively advanced, and the next video is quite advanced as well, but I am considering some simpler topics. Also, to address your second comment, there are some minor limitations that I have experienced. These limitations are few and not likely to affect most developers. The two that I experience most often is difficulty in creating C# plugins, and the inability to use generic classes.
@@hamsterbyte that's fantastic, a mix of simple and advanced is a good strategy. I'm starting my own Gamedev journey and wanted a viable C# engine or framework so I appreciate your answer. Best of luck with everything!
I have the requirements and I am able to load the project without errors. However, the plugin will not enable and it doesn't throw an error when I try to enable it. I'll keep banging on it to see if there's something in godot's config that is incorrect. I am using Godot 4.1.3 with .net
Hello @hamsterbyte , I am messsing around with the WFC Editor and am having issues dragging scenes(tilesets) into the column on the left and having it update. in your video the column is clear so it works, but i have already imported the .tres then rules json and it just stays there. is there a way i can clear the editor or something?
Unfortunately I did not implement a method for easily clearing the list once it has been populated. Closing the editor or disabling/reenabling the plugin will clear the list though.
In all of the wave function collapse demos I have watched or read, never have I seen an entropy function as complex as that. The entropy is more commonly just the number of possible tiles for that cell. I'm not a math person, so when you start using log and similar, I'm lost. What benefit does the more complex entropy calculation give, and is the extra complexity worth it?
TLDR: Entropy cannot be treated as just the number of possible tiles in WFC, and those demos are not really WFC because they do that. Those demos eliminate the frequency constraints entirely which gives equal probability to all possible tiles from the input data. Entropy, in the context of WFC, refers to Shannon Entropy. It's calculated as a function of the number of possible tiles as well as how frequently they should occur in the map. The calculations in this lesson are for Shannon Entropy, and they have actually been simplified a lot. The way those demos you are describing implement this algorithm will result in far more contradiction failures and produce far more random results as it is not a proper implementation. Say you wanted a larger open area with a few trees and rocks, so you paint up a template map and create the constraints for a large open area with a few trees and rocks. You run it through this implementation and you get.... a large open area with a few trees and rocks. You run it through an implementation that disregards frequency constraints and you get a random assortment of any tiles that can fit next to each other and it's incredibly unlikely that the generated map would look anything like a large open area...with a few trees and rocks.
I actually use Jetbrains Rider and it's the Rider Dark theme. Here's a link to a VS Code compatible version marketplace.visualstudio.com/items?itemName=EdwinSulaiman.jetbrains-rider-dark-theme Thanks for watching!
@hamsterbyte hello, just wondering, if i were to update the coordinates of a grids cells on the tilemap(as in to shift them to the right), do i have to update the entropy coordinates in sync, getting some out of bounds errors WFCGrid Observe(atleast thats where the problem may lie, it could be somewhere inside as well)
You should not modify the positions or bounds of the grid or it's cells at runtime. This system calculates that information when the application initializes. You would need to give me more information in order for me to supply a more suitable answer. An out of bounds error in the Observe method indicates that you have modified the bounds of the grid after the system has initialized those values; the system is not designed to handle this behaviour. You can identify the exact location of the error by following the stack trace. Without more information on exactly what you are trying to achieve I am unable to assist you further.
Ive encapsulated each grid into a class called a wfcregion. i have a wfcregionmanager class that organizes each region. It could be argued that i could have just made a grid manager, because a region is basically just a WFCGrid but im a few hundred lines of modifcation in so its staying :) my reasoning for doing this is that ive noticed on larger grid sizes the algorithm fails to collapse, so im breaking them down into separate "regions"(customizable sizes but ill probably stick around 16x16) so far their success rate is much higher. each region will generate and down the line take information from the bordering regions to update its possible tiles before generation.(however right now im just implementing independent regions before i start making the regions interact) in the constructor of the WFCRegion(remember one grid per region), i offset the coordinates of its grid's cells. So region 1's cells[0,0] should be (0,0) while region 2's cells[0,0] would be (16,0)(region 2 is to the right of region 1) I feel bad as i feel i may have jumped the gun asking the question, as my issue currently lies in WFCGrid Observe() at if(!cells[coords.Coordinates.X, coords.Coordinates.Y].Collapsed){ return coords;} I believe that even though i offset the grids cell coordinates in the constructor im not properly handling or updating the entropycoordinates since when i pass EntropyCoordinates coords into the cells 2d array i get out of bounds. again, i feel like i jumped the gun asking you and learned a bit more about the entropy coordinates after I asked you. I havent found the solution but I think im understanding it all a bit more. I appreciate the help! @@hamsterbyte
Hello, one question. I have a version of the project that I got from the repo, and i am still able to run it with the proto and dungeon rule sets even though the WFCCell and WFCGrid .cs scripts appear empty apart from the imports at the top. Can you explain this? Ive been looking at Test.cs to see how its magically generating tilesets without those function implemented even though it seems like its making calls to objects of the grid and cell class. Thank you!
You downloaded the wrong branch. the main branch is complete and the code has been moved away from those files. You need the Lesson-Start branch to follow along with the video.
Hello, it wont let me enable the plugin on disables itself after using it giving me error about there being and issue with plugins code? Any idea why? Im using the mono godot version and tested bunch of 4.1 versions just to make sure
Unable to load addon script from path: 'res://addons/Wave Function Collapse/WFCEditor.cs'. This might be due to a code error in that script. Disabling the addon at 'res://addons/Wave Function Collapse/plugin.cfg' to prevent further errors.
There's over 700 lines of code in that file so it's not something that can be easily debugged remotely. It does work on my end, but I will recommit the project later and let you know. Editor plugins are a little tricky to debug as you don't get the stack trace printout in Godot for the error preventing the file from opening. It could be anything, but in my experience it's often just a filename mismatch. Did you try it on a fresh project or did you try to import it into an existing project?
@@jashum8554 this tool is built on top of 2D tilemaps. Making this work for 3D is going to require quite a few changes. The plugin itself doesn't handle any of the WFC. It only handles displaying the rule data which will be completely different for 3D
@@hamsterbyte I know :) I want it to be able to create height map and than project info from the tiles into the 3d grid. It could be a fun experiment, but I dont have too much time so I’d love to skip some steps 😅
I have no immediate plans to release my tools or plugins on assetlib. I'm looking into releasing some assets on Itch though. I'll keep you in the loop!
This is helpful, but implementation is rather complicated I would like to see abstraction over wfc algorithm in one class and all Godot specifics in another class
I am so glad I found this. I have been struggling so bad with how to implement everything I wanted to accomplish. I have gone through so many PG algo's to get what this does. Now I just need to work on some advanced pathfinding and smart placement of prefabs/scenes.
Procedural generation is quite difficult if you don't have a lot of experience with it. It's essentially always the same concept; wrangling noise into something coherent. This video is on wave function collapse, but I also have another that goes over cellular automata to make a terraria style map with auto updating neighbours. Hope you find the content useful and thanks for watching!
@@hamsterbyte I'm going to go and look for that right now. Cellular automata is what I'm using right now for my maze game. I got the first part figured out. Now I need to do the pathfinding and backtracing etc. But I'm loving the idea of having the code randomize the maze so you don't have the same one twice!
@@shanefoster5305 obviously for pathfinding you will want to use some variation of Dykstra's or A*. The main thing to remember is if you are generating the maps procedurally, you will also need to populate the data for the algorithm after the generation is completed to calculate the nav mesh and weights/values
@@hamsterbyte Thanks I'll look into that. I was just going to modify Wilson's maze algorithm to 3d and then at dead ends place a door that teleports them to the rooms that would be elsewhere. Wilson's maze has pathfinding in it while generating the maze. But your recommendations might be more appropriate and possibly easier.
Would that I had more than one LIKE to give. Excellent work, very helpful and useful!
Wow, thanks! I really appreciate that!
Hey man, excellent videos, just getting into them. I really like the longform 30m+ content for Godot, appreciate your hard work on these.
Thanks a lot. I work pretty hard on these videos so It's nice to know that the community appreciates them! Thanks for watching!
Please continue with C# ❤
Working on another video right now actually. Most of my stuff is relatively advanced, and the next video is quite advanced as well, but I am considering some simpler topics. Also, to address your second comment, there are some minor limitations that I have experienced. These limitations are few and not likely to affect most developers. The two that I experience most often is difficulty in creating C# plugins, and the inability to use generic classes.
@@hamsterbyte that's fantastic, a mix of simple and advanced is a good strategy. I'm starting my own Gamedev journey and wanted a viable C# engine or framework so I appreciate your answer. Best of luck with everything!
This is perfect for helping me implement the system I want to make. Thank you so much for making this!!
You're very welcome I hope it helps!
I have the requirements and I am able to load the project without errors. However, the plugin will not enable and it doesn't throw an error when I try to enable it. I'll keep banging on it to see if there's something in godot's config that is incorrect. I am using Godot 4.1.3 with .net
Hello @hamsterbyte , I am messsing around with the WFC Editor and am having issues dragging scenes(tilesets) into the column on the left and having it update. in your video the column is clear so it works, but i have already imported the .tres then rules json and it just stays there. is there a way i can clear the editor or something?
Unfortunately I did not implement a method for easily clearing the list once it has been populated. Closing the editor or disabling/reenabling the plugin will clear the list though.
i see! great thank you, im having alot of fun with this@@hamsterbyte
In all of the wave function collapse demos I have watched or read, never have I seen an entropy function as complex as that. The entropy is more commonly just the number of possible tiles for that cell. I'm not a math person, so when you start using log and similar, I'm lost. What benefit does the more complex entropy calculation give, and is the extra complexity worth it?
TLDR: Entropy cannot be treated as just the number of possible tiles in WFC, and those demos are not really WFC because they do that.
Those demos eliminate the frequency constraints entirely which gives equal probability to all possible tiles from the input data. Entropy, in the context of WFC, refers to Shannon Entropy. It's calculated as a function of the number of possible tiles as well as how frequently they should occur in the map. The calculations in this lesson are for Shannon Entropy, and they have actually been simplified a lot. The way those demos you are describing implement this algorithm will result in far more contradiction failures and produce far more random results as it is not a proper implementation. Say you wanted a larger open area with a few trees and rocks, so you paint up a template map and create the constraints for a large open area with a few trees and rocks. You run it through this implementation and you get.... a large open area with a few trees and rocks. You run it through an implementation that disregards frequency constraints and you get a random assortment of any tiles that can fit next to each other and it's incredibly unlikely that the generated map would look anything like a large open area...with a few trees and rocks.
Great video! What's the theme you are using in vs code btw?
I actually use Jetbrains Rider and it's the Rider Dark theme. Here's a link to a VS Code compatible version marketplace.visualstudio.com/items?itemName=EdwinSulaiman.jetbrains-rider-dark-theme
Thanks for watching!
@hamsterbyte hello, just wondering, if i were to update the coordinates of a grids cells on the tilemap(as in to shift them to the right), do i have to update the entropy coordinates in sync, getting some out of bounds errors WFCGrid Observe(atleast thats where the problem may lie, it could be somewhere inside as well)
You should not modify the positions or bounds of the grid or it's cells at runtime. This system calculates that information when the application initializes. You would need to give me more information in order for me to supply a more suitable answer. An out of bounds error in the Observe method indicates that you have modified the bounds of the grid after the system has initialized those values; the system is not designed to handle this behaviour. You can identify the exact location of the error by following the stack trace. Without more information on exactly what you are trying to achieve I am unable to assist you further.
Ive encapsulated each grid into a class called a wfcregion. i have a wfcregionmanager class that organizes each region. It could be argued that i could have just made a grid manager, because a region is basically just a WFCGrid but im a few hundred lines of modifcation in so its staying :)
my reasoning for doing this is that ive noticed on larger grid sizes the algorithm fails to collapse, so im breaking them down into separate "regions"(customizable sizes but ill probably stick around 16x16) so far their success rate is much higher. each region will generate and down the line take information from the bordering regions to update its possible tiles before generation.(however right now im just implementing independent regions before i start making the regions interact)
in the constructor of the WFCRegion(remember one grid per region), i offset the coordinates of its grid's cells.
So region 1's cells[0,0] should be (0,0) while region 2's cells[0,0] would be (16,0)(region 2 is to the right of region 1)
I feel bad as i feel i may have jumped the gun asking the question, as my issue currently lies in WFCGrid Observe() at
if(!cells[coords.Coordinates.X, coords.Coordinates.Y].Collapsed){
return coords;}
I believe that even though i offset the grids cell coordinates in the constructor im not properly handling or updating the entropycoordinates since when i pass EntropyCoordinates coords into the cells 2d array i get out of bounds.
again, i feel like i jumped the gun asking you and learned a bit more about the entropy coordinates after I asked you. I havent found the solution but I think im understanding it all a bit more. I appreciate the help!
@@hamsterbyte
Hello, one question. I have a version of the project that I got from the repo, and i am still able to run it with the proto and dungeon rule sets even though the WFCCell and WFCGrid .cs scripts appear empty apart from the imports at the top. Can you explain this? Ive been looking at Test.cs to see how its magically generating tilesets without those function implemented even though it seems like its making calls to objects of the grid and cell class. Thank you!
You downloaded the wrong branch. the main branch is complete and the code has been moved away from those files. You need the Lesson-Start branch to follow along with the video.
sounds good, i appreciate it
Cool, I did similar thing but in GDScript :)
Is it on Git? I'd be very interested in having a look at the source code!
I'd love to see it too
I'm generating negative entropy values which seems wrong... but its still working, just seems like something could be working better...
I'm not sure why the code itself would be generating negative entropy values. I did not experience this issue in my testing.
Hello, it wont let me enable the plugin on disables itself after using it giving me error about there being and issue with plugins code?
Any idea why?
Im using the mono godot version and tested bunch of 4.1 versions just to make sure
Unable to load addon script from path: 'res://addons/Wave Function Collapse/WFCEditor.cs'. This might be due to a code error in that script.
Disabling the addon at 'res://addons/Wave Function Collapse/plugin.cfg' to prevent further errors.
There's over 700 lines of code in that file so it's not something that can be easily debugged remotely. It does work on my end, but I will recommit the project later and let you know. Editor plugins are a little tricky to debug as you don't get the stack trace printout in Godot for the error preventing the file from opening. It could be anything, but in my experience it's often just a filename mismatch. Did you try it on a fresh project or did you try to import it into an existing project?
@@hamsterbyte on multiple new ones :,) but thank you very much! Was hoping to use this for multiple layer generation for 3d map
@@jashum8554 this tool is built on top of 2D tilemaps. Making this work for 3D is going to require quite a few changes. The plugin itself doesn't handle any of the WFC. It only handles displaying the rule data which will be completely different for 3D
@@hamsterbyte I know :) I want it to be able to create height map and than project info from the tiles into the 3d grid. It could be a fun experiment, but I dont have too much time so I’d love to skip some steps 😅
Planning on creating this as a plugin on asetlib?
I have no immediate plans to release my tools or plugins on assetlib. I'm looking into releasing some assets on Itch though. I'll keep you in the loop!
This is helpful, but implementation is rather complicated
I would like to see abstraction over wfc algorithm in one class and all Godot specifics in another class
Exactly what do you mean by abstraction?