The Wave Function Collapse algorithm

  Рет қаралды 276,200

CodingQuest

CodingQuest

8 ай бұрын

Generating random worlds using the wave function collapse algorithm.
This video explains how the WFC algorithm works, and explains how to implement the WFC algorithm in python code.
☕️ ☕️ No coffee, no coding! 🔥 🔥
If you like to support my work with a small donation:
www.buymeacoffee.com/CodingQuest
Thank you!!
You can find the source code, and tile set here:
github.com/CodingQuest2023/Al...
Music: Imagine by Auixe is licensed under a Creative Commons License.
creativecommons.org/licenses/...
Support by RFM - NCM: bit.ly/2xGHypM
Music: Imagine by Auixe
Soundcloud: / auixe
KZfaq: / @auixemusic4618

Пікірлер: 229
@maple201
@maple201 8 ай бұрын
If you want to make sure your world is traversible, you could start by seeding the map with random meandering pathways of grass before running wavefunction collapse.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Interesting! I didn't think of seeding at all..... But I was wondering about how to do the next step, like roads and rivers. This could work I suppose!
@TehDuckOfDoom
@TehDuckOfDoom 7 ай бұрын
Nah, who needs that :D
@xCCflierx
@xCCflierx Ай бұрын
I'm curious if it's worth doing multiple wave function collapses to just add pathways and shift terrain to accommodate them with a specific rule set. Because a world generated around paths sounds much more artificial then paths that are adjusted to the world. We clear forests and build bridges. If a water body is long or wide we are more likely to cut through then go around
@Stratelier
@Stratelier 8 ай бұрын
A neat property of this generation method is that you can "seed" the map with fixed landmarks, and it will fill in the rest of the space on its own.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Nice way to make the world more diverse and interesting! Thanks!
@yellingintothewind
@yellingintothewind 8 ай бұрын
You can also make less noisy maps by dynamically weighting the valid terrain based on proximity to similar terrain. So if the lowest entropy tile can be grass, grass to forrest, or grass to water, instead of being 1:1:1 weights (or predefined weights for the whole map), it can be the number of grass, forrest, or water tiles within say 3 tiles from the current tile. This lets you generate larger lakes, for example, while still being mostly grassland.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Interesting solution!
@landsgevaer
@landsgevaer 8 ай бұрын
Or you simply decrease the probability of choosing the mixed-terrain tiles, then you don't have to look at neighbors when computing probabilities. If you penalize boundaries, you will get bigger connected regions too.
@yellingintothewind
@yellingintothewind 8 ай бұрын
@@landsgevaer True, although the effect will be slightly different. Just reducing the probability of borders means if you have a bit of grass with trees on one side, you are equally likely to get more trees or water on the other side (but most likely to get more grass). If you look at the nearby terrain, you are more likely to get trees than water, and possibly more likely to get trees than grass. Doing both, you could be more likely to get trees than water, but more likely to get grass than trees _or_ water.
@landsgevaer
@landsgevaer 8 ай бұрын
@@yellingintothewind Not sure I get exactly what you mean, but I certainly agree that it doesn't result in the same types of patterns. Both are ways to promote larger patches of the same terrain type.
@disdroid
@disdroid 8 ай бұрын
I would just give each grid position a different probability for each terrain type
@Kitsuneko111
@Kitsuneko111 6 ай бұрын
This ended up on my recommended and I decided to bite the bullet and learn about the big scary name algorithm at 3am. This video explains it so clearly and cleanly at such a nice pace I think I already understand it perfectly which is amazing! I already summarised it to a friend as “it’s like doing a jigsaw by looking at the similar sides and then picking a random piece that seems to fit” 😂
@Rohan2300
@Rohan2300 7 ай бұрын
An idea I've been playing with is to create a world of "object impermanence" where we use Wave Function Collapse in a semi-continuous fashion during gameplay. Basically anywhere you're not looking is in a state of flux, and when you look at it, it temporarily pins it down. Imagine placing beacons or torches to cast light in a world of darkness, and only things that are illuminated are fixed. Perhaps some element of "decay" could be added too, so things become increasingly likely to change when you revisit an area the longer you look away. Meaning areas you traverse frequently tend to stay consistent, while new places, or old places you've not returned to in a while will regenerate.
@CodingQuest2023
@CodingQuest2023 7 ай бұрын
I think you can add a timestamp value to each tile when it gets out of sight..... then after a certain time has passed without re-visiting you could reset the entropy of the tile to maximum. But when re-visiting the wavefunction co0llapse algorithm will generate a different world. However that seems exactly what you want. I have one concern... you will need a very fast WFC implementation to do this all on-the-fly. Not sure this will be easy. One good thing is that you only need to apply WFC to tiles that are about to become in sight.
@Rohan2300
@Rohan2300 7 ай бұрын
@@CodingQuest2023 thats kind of my thought, yeah.
@nifftbatuff676
@nifftbatuff676 7 ай бұрын
Like the Shroedinger cat.
@Rohan2300
@Rohan2300 7 ай бұрын
@@nifftbatuff676 pretty much yeah, the idea with Schrodingers cat was the superposition of two valid states. Dead or alive. Either fits reality. Just like the WFC algorithm can only produce results that match its rules. You can't have grass next to water without coast in between them.
@Green24152
@Green24152 6 ай бұрын
anyone got potential name ideas for this?
@arejaybee
@arejaybee 6 ай бұрын
Spent an hour debugging because I made my direction enum NORTH, SOUTH, EAST, WEST instead of NORTH, EAST, SOUTH, WEST. I'm kinda glad I did because I got a very deep understanding of how all of these functions and maps are tied together. Thank you for this! I got it working in kotlin :)
@anon_y_mousse
@anon_y_mousse 8 ай бұрын
One tiny tip, try making an IntFlag inheriting Enum for the cardinal directions and set their values as North = 1, South = -2, East = 2, West = -3. Then to set the opposite direction you can just use ~direction and it'll work. You can even type check by doing if direction in Cardinal.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Nice one! That would indeed make the code more compact and smart! However to keep the code easy to read and requiring less explanation in the video, I may stick with the less compact code sometimes
@downstream0114
@downstream0114 8 ай бұрын
I've run into suddenly wanting intercardinals multiple times so I'd just go with vector offsets.
@anon_y_mousse
@anon_y_mousse 8 ай бұрын
@@downstream0114 That's what's really fun. I recently found out that you can do that by using the | operator and apparently you can set the values using auto() and set them in relation to each other. For instance, North = auto(); South = ~North; East = auto(); West = ~East; NW = North | West; SE = ~NW; et cetera.
@kevnar
@kevnar Ай бұрын
I once used wave function collapse for a procedural melody maker about 15 years ago. I didn't even know the algorithm existed. I just set up a system that decides what notes can come next, based on the current note. For example, if it's the 4th note in the scale, it has a higher probability to go to the 1, 5, or 8th note, and a lower probability to go to 2, 3, and 6. And so it just kept plinking along through the endless melodies. Great things happen when you're bored and curious.
@obszczymucha1337
@obszczymucha1337 8 ай бұрын
Very nice production and explanation. Thank you!
@InCognite
@InCognite 5 ай бұрын
Thank you for uploading this video! Now I finally understand how wave function collapse works both in theory and code and managed to port it into my own project.
@NosAltarion
@NosAltarion 7 ай бұрын
Fantastic work. Thanks a lot. One of my student is a lot into game dev and I'll be sure to redirect him towards your video so he's motivated to dig a bit deeper in his coding classes
@habbokoreiapix
@habbokoreiapix 8 ай бұрын
Thanks to your video i've got to make my version of wfc finally work
@shanerooney7288
@shanerooney7288 8 ай бұрын
Another suggestion for added functionality: Adjust the probabilities as you place each tile. Every time you place a [water] tile, the chance for a [ship wreck] tile gets +1. Every time you place a [ship wreck] tile, the chance for a [ship wreck] tile gets -99. Placing [cliff] → [cave entrance] +1 Placing [forest] → [big tree] set +1 If the chance for placing [grass] is 100, and each time it is placed the chance goes down by 1, then the map should never have more than 100 [grass] tiles.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Interesting ideas.... but maybe these things you would like to control even further. For example the chance of having ship wrecks is higher near the coast line. And larger cities maybe more often concentrated near the sea or rivers.... And cave entrances shouldn't be too close to each other... etc
@GeorgeD_
@GeorgeD_ 8 ай бұрын
Great educational video! Thanks for posting.
@codelinx
@codelinx 8 ай бұрын
Very awesome layout and explanation of this concept and algorithm
@user-yf7pi9hy5b
@user-yf7pi9hy5b 5 ай бұрын
This is something I would find very interesting to implement using F#. I am developing a simulation program in .NET for a research that I'm conducting, and generating terrains with diverse and realistic environment factors is one of the main problems I have to tackle. This video gave me great insight!
@xCCflierx
@xCCflierx Ай бұрын
Just started watching and I'm already inspired. Putting a limit on how many times a tile can be used would mean only a certain percentage of the map will ever be that tule, and only if the condition to place that tile is correct. So if I want a small building I would only make 4 corner tiles, top tile, bottom tile, left tile, right tile, center tile. It only makes sense for them to connect to each other. And then I'm thinking the algorithm would look beyond just what's next to each square, otherwise i might start a building that cant be finished
@fishingtrippy
@fishingtrippy 8 ай бұрын
I've been working implementing this with Game Maker 2. I decided the easiest way to get the allowed neighboring tiles for each direction was to draw an example level with the existing tile set where I try to use the tiles to draw every possibility of tiles that can be placed next to each other. Then I have a process that scans the level and ads each allowed neighboring tile and direction to a data structure that I saved as a JSON. It seemed to work and it was more fun than coding all possibilities manually.
@matt8ress
@matt8ress 3 ай бұрын
yall make this sound too simple, took me 4 months to make my own implementation. nonetheless, all videos i watched were great, but this one stands out to me because its about wfc and wfc only. 👍
@GameBoy-ep7de
@GameBoy-ep7de 7 ай бұрын
You could also add extra restrictions like how a set of tiles can only be chosen when near some other tile, or changing the weights of some tiles being chosen based on some condition (such as adjusting the probability to have building tiles want to bunch up and be a square with walls around it for a town). Just something that entered into my head, and would probably make the code more unwieldy.
@teamredstudio7012
@teamredstudio7012 Ай бұрын
Fascinating! Ik ga dit zeker eens proberen gebruiken. Een ander interessant algoritme is met Perlin noise, maar dit lijkt simpeler.
@Derni-yp5mk
@Derni-yp5mk 7 ай бұрын
Incredible project
@user-qr4jf4tv2x
@user-qr4jf4tv2x 8 ай бұрын
under rated channel
@VickylanceMedia
@VickylanceMedia 8 ай бұрын
This video blew up congrats :D KZfaq algorithm liked this one. Wish you make more complex algos like this
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Yeah I'm a bit surprised 😀 I think I will try more videos about algorithms in the future!
@TheViperZed
@TheViperZed 8 ай бұрын
A point that I feel is missing from the beginning of the video is that wave function collapse generation plays very well with already existing tiles, generated by other means or placed manually. To be plain it just works as long as those tiles have information for which tiles can be placed next to them. As an example, let's say you have a few exits to other maps and a couple of landmarks on this map. You just place those first, connect them with tiles that allow a player movement between them and then run wave function collapse for the rest of the still un-generated tiles.
@tarck333333rrrr
@tarck333333rrrr 8 ай бұрын
Great explanation and presentation quality!
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Thanks!
@umgeburstet8161
@umgeburstet8161 7 ай бұрын
You have just presented a world gen algorithm to me that perfectly fits a game idea i had a couple years ago. I should implement that instead of working on my bachelor thesis.
@CodingQuest2023
@CodingQuest2023 7 ай бұрын
You should! But after working on your bachelor thesis 😉
@gavingrover7853
@gavingrover7853 8 ай бұрын
Thanks for the detailed explanation, now I understand the concept and how Sid Myers would have done all those great games :)
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Glad I could help! 🙂
@ollllj
@ollllj 8 ай бұрын
no sid meyer game uses this, because this is an inefficient map generator, that cares for a LOT of detail or options, that is not needed for sids games.
@TalicZealot
@TalicZealot 8 ай бұрын
Cool generator. One thing that came to mind is what about removing getLowestEntropy and instead using a priority queue, containing the adjusted nodes. This way we don't iterate over the entire grid every step and we get a fast min value.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
The current code probably has plenty of room for optimization. I think indeed using some data structure to keep track of tiles that had their entropy updated by the constrain method, will make getLowestEntropy much faster. But it will add some complexity to keep track of all tiles in that data structure and their up-to-date entropy value. Let me know if your idea can speed things up 👍
@ollllj
@ollllj 8 ай бұрын
queues need more memory. and you want randomness, because this method will regularily fail to fil lthe whole area and have to roll back or retry from the start, with other random choices being made till some attempt fills the whole area. this must not be too deterministic.
@TalicZealot
@TalicZealot 8 ай бұрын
@@ollllj Yes some memory will be used, but a pq in this situation will internally contain an array of coordinates and a hashmap, so it's not something dramatic. All it would be doing is speed up the process of grabbing the node with the lowest entropy, not affecting other parts of the system.
@Innengelaender
@Innengelaender 8 ай бұрын
Nice video. Another idea to create larger "biomes" would be another tile-set of randomly chosen biomes where each tile represents one biome and contains maybe 10x10 terrain tiles, adjusting the probabilities of all available terrain within that section of the map. Basically you could just check for the coordinates of each tile, which biome that tile is in and use appropriate probabilities. That way you can have a mix of near infinite amount of combinations of probabilities of your base tiles. And you can go even further and create super-sets of biomes that only allow biomes within certain parameters within it to create large structures like climate-zones, continents, ocean, archipelagos etc. that still allow for an arbitrarily large or small range of different biomes within them.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
I like your idea! But you will need a lot of tiles to connect the tile types of one biome to the tile type in another biome. Maybe grassland in one biome will be a snowy plane in another connecting biome. But you will need to place a transition tile from grass to snow on the edge of one biome. You will get a very large tile set! But the worlds will definitely become more interesting! Thanks for the idea!
@MrRyanroberson1
@MrRyanroberson1 8 ай бұрын
i think this could better be solved by using perlin noise to generate probability biases. another factor that would contribute to this would be to simply have a tileset where biome transition tiles are much less likely to be selected. Consider, for example, if your water tiles had 5 depths and you could only ever go up or down one depth at a time. a randomly selected deep water tile would cascade to a very large ocean biome, whereas a coastline is very unlikely to give rise to an ocean, even without biasing the probabilities.
@Suthriel
@Suthriel 8 ай бұрын
@@CodingQuest2023 of course you will need more transition tiles, but to avoid going from deep frozen snowy mountain chains to dry hot deserts (or to require transition tiles for each possible combination of tiles and terrains), you can make rules, that snowy regions can only connect to f.e. grasslands, and then grasslands can connect to desert or tropical terrain. You can apply general rules like our world has, the more north of the whole world, the colder the biome becomes, the more south, the warmer, and either more tropical (warm and wet) or more desert (warm with decreasing chance of water). But you usually don´t have snow in one tile, and then desert within the next two or three tiles... well, unless you are in New Zealand... So a temperature map and maybe a moisture map will help in creating those different biomes and climate zones etc. or maybe throw in a type of underground map, like, mostly sand, mostly rock, mostly clay, etc. and what types of vegetation can grow there.
@flameofthephoenix8395
@flameofthephoenix8395 8 ай бұрын
Personally, I think a full water tile should make other full water tiles more likely so as to get bigger ponds/oceans.
@flameofthephoenix8395
@flameofthephoenix8395 8 ай бұрын
Like 7:49 but more specific to full waters next to full waters, maybe you could have a duplicate full water tile that can't be next to anything but another full water tile? Of course, you'd probably want to swap it for one that can be next to other tiles when you place it to prevent any issues.
@flameofthephoenix8395
@flameofthephoenix8395 8 ай бұрын
If you did this for all of the tiles you should get bigger patches of everything without making one thing more common than the other.
@flameofthephoenix8395
@flameofthephoenix8395 8 ай бұрын
It would also be neat if there were more custom options for what blocks can be next to what blocks, for instance making it possible for water to spawn next to other water but if it's too far away it can't spawn but also making sure that the waters don't interfere with each other so that you don't have two bodies of water right next to each other.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
I think you can only easily control directly neighboring tiles, with the weight values for controlling the chance and the tiles rules to control which tiles can be next to each other. Not sure how complicated things will get when you start to look at more distant tiles in the constrain method. But an interesting idea!
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
This you can control using the weight value for the full water tile to increase the chance of it being picked by the collapse method. You could also reduce the chance of coast line tiles to be chosen, to push for larger water areas.
@mopar3502001
@mopar3502001 8 ай бұрын
Brilliant!
@berkormanli
@berkormanli 8 ай бұрын
Both the video and the comments are really precious for me because I'm working on a procedural generated 3D world right now and I was having some difficulties about how I should fill the terrain. Thank you and thanks for all that commented!
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Great to hear you like the video 😊 Also check out noise based procedural generation, like Perlin noise!
@berkormanli
@berkormanli 8 ай бұрын
@@CodingQuest2023 I'm using Perlin noise for the base terrain, I'm now working on generating rivers so I had some ideas but it always feels a bit wrong. I'm trying to mimic the real life rivers. Your video gave me some ideas how I might do it, unlucky I don't have much time right now to try it out.
@primalaspid7197
@primalaspid7197 8 ай бұрын
Awesome video!
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Thanks!
@sanjeev.rao3791
@sanjeev.rao3791 8 ай бұрын
This is pretty much how a level is randomly generated in minesweeper I believe. Nice video!
@spell105
@spell105 8 ай бұрын
Actually, generating solvable minesweeper levels is a LOT more complex than this. There's a great example written in C you can easily find online; but essentially to generate Minesweeper levels that can be solved, you also need to write an algorithm to solve them; and then use that algorithm to generate a game of minesweeper. This is because it is very hard to create minesweeper grids that are actually 100% solvable by a human.
@gildedbear5355
@gildedbear5355 8 ай бұрын
Catch the deadlocked tile and output what tile would be needed there 8) that way it can also make sure you've made all the tiles.
@iloveblender8999
@iloveblender8999 3 ай бұрын
I really like this video and will use the algorithm in godot.
@user-gu2fh4nr7h
@user-gu2fh4nr7h 8 ай бұрын
would be nice to look at ALL possibilities for a given tile set for small maps
@disdroid
@disdroid 8 ай бұрын
Its also a tree, so we could paint tiles onto the map and only regenerate the affected tiles
@Dr.W.Krueger
@Dr.W.Krueger 8 ай бұрын
interesting. we used this algo for texture synthesis back in the late 80s/early 90s.
@63801170
@63801170 8 ай бұрын
Thanks for the instructional video and source code. It's spot on what I was working towards for a fixed tile map method (but not in python, so trying to work through your coding methods). I didn't notice in your talk or via the code what the correct way would be to extend the current "single adjoining NESW" tile option to more than just 1 possible match per tile direction? For example, my tile set has possibly 20 tiles that could match up against my "grass" tile in different directions. As there are various terrain types and transition tiles and other grass types, etc. Would this need a separate tileRules_N & tileRules_S, etc ?
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
If you have like 20 different grass tiles, I think you don't need to create different tile types for each of them. I think you could just stick to 1 tile type, but when you actually draw the map you could just randomly choose from 20 different tiles in the tile sheet for a grass tile. Right? As long as the connection rules don't change, I would stick to only 1 tile type.
@63801170
@63801170 8 ай бұрын
@@CodingQuest2023 The tile-edge variations I am working on are more about changing terrain, like to "snow" or "mountain" or "different forrest" or "road", so there's definitely a need for more options. I think my version is needing to have a list of options for each edge. I will consider some more about it. Thanks for your input.
@darkfrei2
@darkfrei2 7 ай бұрын
Thanks, I've made one WFC algorithm too, maybe not so good as your, I have no backward steps to solve unsolvable situations.
@CodingQuest2023
@CodingQuest2023 7 ай бұрын
I also didn't need the backward steps. It depends on the tile set you are using. Sometimes you just cannot reach any deadlock situation. Or you may be able to add another tile to the tile set to avoid deadlocks.
@darkfrei2
@darkfrei2 6 ай бұрын
@@CodingQuest2023by the Coding Theain was an implementation of WFC, it makes circuits and it cannot have any transitions, some of them are impossible.
@williamdrum9899
@williamdrum9899 8 ай бұрын
Isn't this essentially reverse Minesweeper
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Kind of looks like it. For sure this algorithm can be used as a Sudoku solver
@indieBen
@indieBen Ай бұрын
Somehow, looks like an improved version of the Minesweeper game :)
@TESSAHOOGENDOORNTJES
@TESSAHOOGENDOORNTJES 7 ай бұрын
Mooi
@Ejb5154
@Ejb5154 7 ай бұрын
Is this what they refer to as "procedural generated" worlds like in MineCraft, Dead Cells, and No Man's Sky? This was a really neat video.
@CodingQuest2023
@CodingQuest2023 7 ай бұрын
Minecraft and No Man’s Sky use Perlin Noise to generate the worlds, and I just made another video about that topic! 😆 You should check it out
@Ejb5154
@Ejb5154 7 ай бұрын
@@CodingQuest2023 I will do that. Thanks!
@Tiemen2023
@Tiemen2023 7 ай бұрын
He talks a Dutch version of the English language
@jimmygervaisnet
@jimmygervaisnet 8 ай бұрын
A relief map could influence the direction of water as to form rivers. Flat terrain would yield lakes, but a water tile in a descending position would force more water in that direction.
@jimmygervaisnet
@jimmygervaisnet 8 ай бұрын
The relief map itself could be created first using a similar wave collapse algorithm.
@feuermurmel
@feuermurmel 8 ай бұрын
Have you explored using non-uniform probabilities for the tiles? For example, you could use an image spanning the terrain as inout, on which you can paint e.g. where you want to have more or less water.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Interesting idea, so make the probabilities region specific? Haven’t looked into that. Others have mentioned seeding the map with some tiles before running the algorithm, which could also lead to different looking regions in the world
@kaawan3201
@kaawan3201 8 ай бұрын
i think it would be cool to add a few pass on the algorithm, like generating a small map (16*16 for example) and then use the small map to create a big map using the tile type to weight the possible output in the entropy, Or i would implement a convex hull algorithm to make "rounder" lake and remove the skinny coast to coast line that appears ! i would also add a chance for each now defined lake to generate a island! we could also combine a marching square algortithm or djikstra pathfinding to create towns and road, and bridges ! i may try to make all of that
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Wow, big plans 🙂 I wrote down some of the algorithms you mentioned, maybe I can think of some topic for a future video. Thanks!
@NinjarioPicmin
@NinjarioPicmin 8 ай бұрын
"and then use the small map to create a big map using the tile type to weight the possible output in the entropy," sorry i'm not clearly understanding what you are suggesting here, care to explain again?
@piercexlr878
@piercexlr878 8 ай бұрын
​@NinjarioPicmin So you can't have a super hot environment next to a snowy one. So on the very first pass it would be like picking a biome. You don't know what tiles are placed where yet, but you know it'll be desert oriented or plains oriented. Each biome will have different weights for certain pieces. Plains might have some trees, but forests will have a higher weight for them. You then run the algorithm again giving each of those grids a certain size. So your first pass could have a 16x16 square grid of biome tiles. Each biome tiles could have another 16x16 grid of tiles inside them. This way you get a variety of terrain and it doesn't shift from the arctic to a plains to a desert in 5 tiles. In short. First pass picks your biomes Second pass fills in the details
@kaawan3201
@kaawan3201 8 ай бұрын
@@piercexlr878 yes exactly what I was thinking
@dijego-jelle
@dijego-jelle 8 ай бұрын
Funny, I was literally working on something like this in Unity. I am also thinking of using layers of perlin noise to determine possible options.@@kaawan3201
@MacroAggressor
@MacroAggressor 8 ай бұрын
What method should be used to ensure all generated terrain is path-able? I've been thinking on this for a bit, and (assuming dead ends are a valid tile choice) I can't think of a good way to ensure generation will connect all endpoints and/or prevent "islands" from forming. A simplification of my intended use case is a maze.
@Free.Spirit1
@Free.Spirit1 8 ай бұрын
As someone who is interested in this topic but never actually made this algorithm before. My best guess is doing a second pass over the terrain using a path-finding algorithm and if you find a walk-able tile with no valid path, try overwrite part or all of the boundary of the problem area.
@bloggy6465
@bloggy6465 3 ай бұрын
can this be used for biomes cus it doesnt seem like it would?
@j4yd32
@j4yd32 7 ай бұрын
Could you increase the chances of having the same tile show up next to itself to favor bigger areas and do the same in reverse to make them smaller?
@CodingQuest2023
@CodingQuest2023 7 ай бұрын
Yes, I think you can do that with the weight values.... so for example if you want large lakes you can increase the weight of the full water tile, and reduce the coast lines tile weights. Something similar for full grass tiles if you want large planes. In that case increase the weight of the full grass tile, and lower the weights of coast and forest tiles. By making the weight of coast line tiles larger and lowering the full water tile weight, will create very small lakes....
@catprog
@catprog 8 ай бұрын
I wonder if you could adjust the probability based on the total of each terrain in the world and the neighbouring tiles.
@ollllj
@ollllj 8 ай бұрын
yes you can, for each tile individually, andOr you can increase the kernel-size to care for more than direct-neighbors, and use a small template that sets probabilities for larger areas over more than direct neighbors.
@RajelAran
@RajelAran 8 ай бұрын
hmmm this could also be used to generate terrain heightmaps
@Awakiia
@Awakiia 8 ай бұрын
very cool
@iloveblender8999
@iloveblender8999 3 ай бұрын
So if you have n tiles and m possible values, that would be m^n possible combinations, but we want to find one that satisfies the rules. I have heard of that. CSP?
@Nickgowans
@Nickgowans 8 ай бұрын
You're making your computer play minesweeper against itself to buuod a world.. nice
@enormousearl8838
@enormousearl8838 8 ай бұрын
Would be neat to see how to code this so that there's always an unobstructed walking path. No good if the map can trap the player in a forest.
@jorgegomes83
@jorgegomes83 8 ай бұрын
Thanks for the video! Considering the code editor and the absence of coding convention I assume you're new to Python. If so, welcome!
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
True, quite new to Python.... used to do a lot more C++ programming. But I love how quickly you can create stuff in Python! Need to improve my coding indeed, already got some feedback on this. Feel free to point out the things that are most annoying to you 😉
@jorgegomes83
@jorgegomes83 8 ай бұрын
@@CodingQuest2023 There's nothing wrong with your code. I like to see how other people write and structure their code, so I almost never get annoyed, quite the contrary, I enjoy it. It's just a matter of style. In case you plan to get more familiar to the language, I would like to recomend you to read Python's PEP8. It's the python enhancement proposal number 0008 and it focuses on coding conventions. When I started with Python, it took a while for me to discover this PEP, so a lot of my early code had conventions from other languages too. It may be useful to you.
@HDMensur
@HDMensur 8 ай бұрын
thi is like reverse minesweeper
@chofmann
@chofmann 8 ай бұрын
I like the algorithm, but parts of your coding choices seem odd to me :D How long are you working with this? Examples that got me: What's the point in waveFunctionCollapse to return an integer that is always either 1 or 0 als always just checked for it being a value? Why not return the boolean value of that comparisson instead. That way, you could just call done = waveFunctionCollapse. Also, for the non-interactive loop, I would just not bother with done at all. I would just make something like while True: if not waveFunctionCollapse: break Why do you compare booleans against boolean constants? Why not just use if foo and if not foo: instead of if foo == True: and if foo == False:? Especially since the way you make it by putting the true/false at the end makes it harder to grasp whether a value should be true or not. Why do you have a stack class if it does nothing that array itself couldn't already do? Also, why does getLowestEntropy has so many ifs instead of just doing lowestEntropy = min(lowestEntropy, tileEntropy)?
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Haha, good points. I have no excuse for most of the points you mentioned. Next time I shall do a better job cleaning and simplifying the code! It's my first video that gets so many views!! I should strive for a higher quality from now on! wrt to getLowestEntropy, you can get rid of one IF, but you should keep the check for > 0 I think Thanks for the feedback!
@SpecialeW
@SpecialeW 8 ай бұрын
@@CodingQuest2023 It should be easier to keep track of the lowest entropy. Instead of going through the whole world in a double for loop, you could create a sorted list (by entropy) of tiles that were just updated. This should make the entire algorithm faster. You can either choose to randomize the equal entropy tiles in the list or you can keep them in order of when they were inserted in the list. The latter option should also prevent more deadlocks I think, because it is harder for the algorithm to create holes on the map. EDIT: oh I see now that TalicZealot suggested something similar 🙂
@petersmythe6462
@petersmythe6462 8 ай бұрын
Isn't there a possibility that you could have a series of rational steps which lead to an irrational result though? For example, a loop which creates a situation where there are ungenerated tiles with zero entropy?
@piercexlr878
@piercexlr878 8 ай бұрын
Yeah, you need to implement a catch for when something like that happens. The 3 ways I know of are to have a back tracking system where you backtrack and mark what you did as impossible. Back track several steps with no update. Or to just restart. If your weights are decent and it's not an overly complex piece, then you shouldn't have it restart too much.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Yes indeed this is possible. I think the easiest solution is to create more tile types to avoid dead locks. If this is not possible, you will need to extend the algorithm to catch the situation in which the constrain method results in an entropy of 0. And then the more simple solution is to just start all over... which is probably very slow. Or backtrack, and retry...
@LuskyMJ
@LuskyMJ 8 ай бұрын
I remember getting a shit grade 2 years because I was making a bullet hell game and got sidetracked by spending wayyy too much time implementing WFC for the world generation😭 I thought I'd be able to do it super fast so I remember being so down because it was the first time I was really disappointed with my programming skills.
@waffle8364
@waffle8364 8 ай бұрын
I would suggest maybe cleaning the code up. also also do you have any tests?
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Sorry, I have no test.... And yeah I should have done a better job cleaning up the code a bit. Thanks for the feedback!
@Derni-yp5mk
@Derni-yp5mk 7 ай бұрын
I review the code for the World generation and i see some improvements to do
@CodingQuest2023
@CodingQuest2023 7 ай бұрын
Yeah some other people also pointed out I should have done a better job cleaning up the code 😉 And I'm sure there could be some improvements to efficiency of the implementation as well. Feel free to use the code as starting point and make it better! 👌
@sagemeline
@sagemeline 7 ай бұрын
You can seed it by seeding the RNG. but you cannot seed this with multithreading. while it always generates the same thing, it does so by nature of the RNG, which you cannot replicate across threads. This also cannot add different terrain features (think biomes, structures) without multiple passes and significantly more layers / complexity. So, this is fine for something very simple -- and in fact works quite well for something very simple -- but it cannot ever be anything more than simple. Now, if you use this as a smaller tool in greater world generation, it would work amazingly well for filling in the minor details in already-generated maps. You could use this for clutter/accent placement, as a map maker's tool for filling areas in with random terrain/clutter (for ideas/filler), etc.
@Insideoutcest
@Insideoutcest 8 ай бұрын
i assume you could also do this in reverse? wave genesis function for reaching a "goal" randomly by starting with all 0s and choosing a location to increase entropy. i think the solution space would need to be more confined at the outset though.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Not sure I get what you want to achieve by this. What application would you get from this?
@Insideoutcest
@Insideoutcest 8 ай бұрын
modelling probably more organic initial conditions @@CodingQuest2023
@jamesbogart3334
@jamesbogart3334 7 ай бұрын
I wish you had gone over building that dict more. It's the more complicated part then the code
@xTwisteDx
@xTwisteDx 8 ай бұрын
I wonder how useful this would be for Screeps.
@Oscar-vs5yw
@Oscar-vs5yw 7 ай бұрын
Could you like combine this with perlin noise or some other "smooth" noise function to modify the random number generator in order to modify terrain type to create "smooth" transitions between "biomes?" Also the O(n^2) traversal to find smallest element was pain, you could just keep an array of length max entropy and then add and subtract to indices of that array to keep track of the counts of each entropy
@CodingQuest2023
@CodingQuest2023 7 ай бұрын
Yeah I suppose Perlin would be perfect for making a smooth biome map. Good solution to improve the performance of finding the lowest entropy tiles 👌
@spartanfoxie
@spartanfoxie 7 ай бұрын
it seems like if this was used in a chunk based game similar to minecraft it would generate terrain differently based on the direction you approach it from right?
@CodingQuest2023
@CodingQuest2023 7 ай бұрын
Yeah, I assume you want to destroy the chunk again after a while? In that case it will re-generate differently depending on the neighbor tiles on the edges of the then existing neighbor chunks.... even if you would save the random seed. It would only regenerate the same if you start generating with the same tiles on the neighbor chunks (and the same random seed(
@spartanfoxie
@spartanfoxie 7 ай бұрын
@@CodingQuest2023 thought as much I ended up going with overlapping perlin noises one for height and like 4 for which biome, then a seed based on the x and y coordinates of the chunk so its guaranteed to be identical no matter what direction you come from
@CodingQuest2023
@CodingQuest2023 7 ай бұрын
Yeah Perlin noise should only depend on the random seed. But with a per-chunk random seed, will Perlin not give you a mismatch in terrain height at the chunk borders? I suppose for Perlin you use one random seed for the whole world?
@jorenvangoethem343
@jorenvangoethem343 7 ай бұрын
Tell me you're a hollander without telling me you're a hollander 😂
@CodingQuest2023
@CodingQuest2023 7 ай бұрын
It's that obvious? 😅 North or South? Can you guess the city also?
@sebbes333
@sebbes333 8 ай бұрын
Cool algorithm, but is it really more efficient than other options to generate a world? You still need to reduce _X * Y * Tiles_amount_ ( eg: _X * Y * 35_ Eg: at 3:33 ) into a _X * Y * 1_ amount, that is MANY (quantum-)tiles that needs to be updated, to generate a world.
@ollie-d
@ollie-d 8 ай бұрын
I'm wondering the same. This method is also not ideal for parallelization since there are scenarios where you would run into impossible boundaries, although it might be cheaper to parallelize and re-generate problematic chunks
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
I don't think this is a very efficient way indeed.... especially when you have a tile set that could lead to deadlocks, and you need to retry certain parts. Maybe I will create a video about Perlin noise world generation in the future, also a very interesting algorithm.
@piercexlr878
@piercexlr878 8 ай бұрын
It works well in some environments and poorer in others. It won't beat perlin noise in elevation generation for instance but if you want to generate dungeons procedurally there's not a lot of noise algorithms that handle it as well as this one can.
@TheBlenderblob
@TheBlenderblob 8 ай бұрын
you have 30 seconds to explain how this is any different to a markov chain.
@piercexlr878
@piercexlr878 8 ай бұрын
Markov chains use probability to determine a stable state rather than generate a random state if memory serves. Correct me if I'm wrong they aren't my strong suit.
@piercexlr878
@piercexlr878 8 ай бұрын
After more thought. This could probably be reduced to a Markov chain, but not all Markov chains can be described as this. Similar to how all squares can be called rectangles but not all rectangles are squares. It's a specialization of a much broader idea.
@TheBlenderblob
@TheBlenderblob 8 ай бұрын
you are wrong @@piercexlr878
@user-uc2qy1ff2z
@user-uc2qy1ff2z 8 ай бұрын
​@@piercexlr878You can. But you shouldn't.
@RajelAran
@RajelAran 8 ай бұрын
Ah, so it's multidimensional reverse Minesweeper
@thattigercat
@thattigercat 8 ай бұрын
Seems doomed to create tons of bodies of stagnant water with a nary a river to be seen
@penfelyn
@penfelyn 7 ай бұрын
wait this is literally Carcassonne
@buriedbones-nh9xr
@buriedbones-nh9xr 21 күн бұрын
Just because a game has a generated world that doesnt make your game more unique or interesting I mean how much does it make a difference if the tile is a grass texture tile or a tree I think indie game developers are still struggling with what makes a game interesting
@kyle_rosenberg
@kyle_rosenberg 8 ай бұрын
Cool video.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Thanks!
@McMurchie
@McMurchie 8 ай бұрын
This is amazing, though not to nitpick too much it's not super useful for set level games. If you only have 7 levels it's easier to just build a map editor and plan out your maps - writing the logic to pull in the tiles, separate them by type and class is hard enough let alone writing up rules for their interactions. That said, this is amazing for games that have hundreds of maps and levels (or a dwarf fortress kind of game)
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Sure if you only want a limited set of levels in your game, I would be better to design them yourself. Human creativity will produce better results than procedural generation. But I think a strategy game for example, should next to a few scenarios also have a random world generator. Because playing the same scenarios over and over won't be much fun in the long run.
@theyoshine
@theyoshine 7 ай бұрын
You just use larger chunks then it works
@rezashir3873
@rezashir3873 8 ай бұрын
very interesting. please complete create magic forest tutorials first
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Yeah, next video will be about that topic again 👍
@brownie3454
@brownie3454 7 ай бұрын
This is Pokemon
@josh5231
@josh5231 8 ай бұрын
I really don't get this approach. Would it not be far better to build up your list of possibilities? The need to store and sort all tiles not yet defined, in order to find the one with the lowest "entropy", is slow and wasteful. Plus if you moved through it in a standard way (left to right, top to bottom), you would only need a max of 3 lookups. Your list of possibilities would simply be the overlap of the lists for the surrounding tiles. So while it's always good to know more ways to accomplish something, I don't think this solution fits the problem.
@erikeriknorman
@erikeriknorman 7 ай бұрын
Why did they bot farm boost this?
@eitantal726
@eitantal726 8 ай бұрын
Looks like a Warcraft 2 map
@zalzalahbuttsaab
@zalzalahbuttsaab 8 ай бұрын
3:36 Nothing is random especially after the fact.
@yellingintothewind
@yellingintothewind 8 ай бұрын
Unless you are doing something dirty with `__eq__` , you should _never_ compare eq against `True` or `False` . You do so on line 91.
@catbertsis
@catbertsis 8 ай бұрын
It doesn't really hurt. Whatever makes the code more readable.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
It's my habit to do so in C-code, although there also not necessary. You are not the first commenting on this, will try to avoid this in the future. Thanks for the feedback!
@yellingintothewind
@yellingintothewind 8 ай бұрын
@@CodingQuest2023As you say, there it is also not necessary. It *can* be worth checking identity against `True`, but that still raises "code smell" warnings to me. It is worth noting that python's polymorphism means you can have `if foo` and `if foo == True` _not_ have the same result, if someone did something funky to `foo` .
@lawrencedoliveiro9104
@lawrencedoliveiro9104 8 ай бұрын
This has nothing to do with quantum wave functions, or any collapse thereof. If you want a physical analogy, consider how liquid water freezes to ice. The relevant physical jargon (if you really feel the need for such pixie dust) would be “phase change” and “symmetry-breaking”. But of course “quantum” somehow makes everything sound extra-cool, doesn’t it.
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
I didn't make up this algorithm myself. It is an existing algorithm loosely based on the quantum mechanics world's waveform collapse. But indeed that makes it all extra cool 🙂
@lawrencedoliveiro9104
@lawrencedoliveiro9104 8 ай бұрын
@@CodingQuest2023 It is not based at all on how waveforms collapse. Remember that quantum wave functions are not probabilities.
@hri7566
@hri7566 8 ай бұрын
can it play minesweeper?
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
That is your homework!
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Actually, not sure if this algorithm can solve minesweeper..... but it is an excellent Sudoku solver!
@piercexlr878
@piercexlr878 8 ай бұрын
​@@CodingQuest2023It can solve minesweeper as well as it can be solved. There are impossible situations in minesweeper.
@deadman746
@deadman746 8 ай бұрын
See _Wang Tiles._
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Nice! Yes you can use this algorithm to fill a plane with Wang tiles to check if they are able to fill the entire plane or not..... checking for repetitive patterns will be more complicated 😉
@timonix2
@timonix2 2 ай бұрын
You did not go through any back tracking. If it cannot find a solution it needs to undo some amount of assumptions
@nonchip
@nonchip 8 ай бұрын
wow that stack class does nothing :P
@megatu1915
@megatu1915 8 ай бұрын
From the accent i feel like you from Belgium maybe dutch speaking one
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
You almost guessed right... I am from the Netherlands 😀
@megatu1915
@megatu1915 8 ай бұрын
​@@CodingQuest2023haha well 80% of the time it was Dutch sometimes I heard French accent. So I though Flemish haha.
@DJSUPERSAW
@DJSUPERSAW 8 ай бұрын
do i smell dutch?
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Yes you do 😆
@xicad1533
@xicad1533 8 ай бұрын
noise is better and faster
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Yeah I might make a video about Perlin noise in the future, if I can manage to avoid too much maths to explain it 🙂
@xicad1533
@xicad1533 8 ай бұрын
perlin is awful@@CodingQuest2023
@xicad1533
@xicad1533 8 ай бұрын
there's too many 45-90 degree artifacts in perlin noise, something like simplex is better because then you don't need to use stuff like domain rotation@@CodingQuest2023
@CodingQuest2023
@CodingQuest2023 8 ай бұрын
Never looked into that one yet, will check it out! Thanks!
@kfftfuftur
@kfftfuftur 8 ай бұрын
Bad name choice: "Wave function" refers to the complex probability amplitude seen in quantum physics. Meanwhile this has nothing to do with quantum physics. It's only about classical probability - no Wave function involved. The name probably just comes from some random programmer who wanted to sound cooler than he actually is by implying he is doing something "quantum".
@furkanyildirim4288
@furkanyildirim4288 7 ай бұрын
Minecraft ☠️
@durden91tyler
@durden91tyler 8 ай бұрын
That's what we want. More generated garbage.
@tr1p1ea
@tr1p1ea 7 ай бұрын
A good video but this has nothing to do with wave functions, entropy or collapsible states ... So unfortunately all that is 'tech clickbait'. What's being referred to as entropy is closer to the complete opposite of entropy for example.
@CodingQuest2023
@CodingQuest2023 7 ай бұрын
Thanks for liking my video! 😊 I had some similar feedback already. Just want to tell I didn't invent this algorithm or came up with the quantum physics analogy. 😅
Minecraft Doesn't Get More Confusing
9:07
Shalz
Рет қаралды 137 М.
How to turn a few Numbers into Worlds (Fractal Perlin Noise)
15:24
The Taylor Series
Рет қаралды 185 М.
FOOLED THE GUARD🤢
00:54
INO
Рет қаралды 62 МЛН
Just try to use a cool gadget 😍
00:33
123 GO! SHORTS
Рет қаралды 85 МЛН
I’m just a kid 🥹🥰 LeoNata family #shorts
00:12
LeoNata Family
Рет қаралды 16 МЛН
Superpositions, Sudoku, the Wave Function Collapse algorithm.
14:28
Martin Donald
Рет қаралды 681 М.
The purest coding style, where bugs are near impossible
10:25
Coderized
Рет қаралды 893 М.
A.I. High Resolution Texture Design (Wave Function Collapse #7)
16:08
Do Quantum Wavefunctions Actually Collapse?
11:13
Science Discussed
Рет қаралды 46 М.
I run untested, viewer-submitted code on my 500-LED christmas tree.
45:17
Popular Technologies that Won't be Around Much Longer...
14:36
Sideprojects
Рет қаралды 128 М.
💅🏻Айфон vs Андроид🤮
0:20
Бутылочка
Рет қаралды 729 М.
сюрприз
1:00
Capex0
Рет қаралды 1,7 МЛН
Игровой Комп с Авито за 4500р
1:00
ЖЕЛЕЗНЫЙ КОРОЛЬ
Рет қаралды 373 М.