Programming Chaos
Programming Chaos
  • 42
  • 85 558
Procedural Generation using Constraint Satisfaction
Learn how to use constraint satisfaction algorithms to generate a wide variety of procedural content, including maps, plants, and textures.
zhlédnutí: 15 729

Video

Programming tricks to create beautiful day/night cycles.
zhlédnutí 549Před měsícem
Learn the programming tricks to create some beautiful day/night cycles. See how to use a combination of recursion, trigonometry, color theory and more to generate stunning sunsets, night scenes, and fractal trees.
Evolving creatures using 3D particle life.
zhlédnutí 899Před měsícem
An evolutionary model is applied to 3D particle life to create an amazing range of colorful creatures.
Program a 3D version of Particle Life
zhlédnutí 1,2KPřed 2 měsíci
Create an infinite set of amazing organic-looking forms using a 3D version of Particle Life.
Program a Chaotic Strange Attractor
zhlédnutí 736Před 3 měsíci
Learn to program chaotic systems and strange attractors.
Programming Sierpinski Triangles
zhlédnutí 382Před 4 měsíci
Create dozens of beautiful, fractal forms based on the classic Sierpinski Triangle. Sierpinski Triangles are the perfect starting point for a huge variety of more complex fractal forms that use color, images, and motion to create amazing, mesmerizing projects.
Programming 1D Cellular Automata
zhlédnutí 1,4KPřed 4 měsíci
Create an infinite array of amazing, intricate patterns using the simple rules of a cellular automata. The 1-D version of Conway's Game of Life creates infinite patterns.
Creating an Evolutionary World, Part 3: Evolution
zhlédnutí 485Před 5 měsíci
Create a world of evolving creatures! This video finishes the programming for a simple evolutionary artificial life. The model is programmed in Java using Processing.
Create an Evolving World Part 2: Creatures
zhlédnutí 384Před 5 měsíci
Create an evolving world! In this video we program the second part of an evolving artificial life model - the creatures! The programming is done in Java using the Processing environment.
Create an Evolving World Part 1: The Environment
zhlédnutí 677Před 5 měsíci
Create an evolving world! In this video we program the first part of an evolving artificial life model, an environment with two types of terrain and two types of food. The programming is done in Java using the Processing environment.
Programming Differential Growth
zhlédnutí 3,1KPřed 8 měsíci
Program amazing, complex, and chaotic patterns via differential growth. Differential growth creates a chaotic system that can be used to model biological processes. Learn about vectors, ArrayLists, and how to program forces in Java (Processing) while creating beautiful, organic images.
Programming Flow Fields
zhlédnutí 2,9KPřed 9 měsíci
Use flow fields to create beautiful patterns. Program with Java (processing) to create flow fields that can be used to procedurally generate colorful images or simulate the movement of particles through complex fields of forces.
Program an Invisibility Cloak and other Cool Effects
zhlédnutí 521Před 9 měsíci
Learn how to program an invisibility cloak and other cool effects using green-screen style effects. This video is a quick introduction to capturing and manipulating camera captures to creating a range of video effects.
An Evolutionary Version of Particle Life
zhlédnutí 19KPřed 9 měsíci
An evolutionary version of the particle life model. In this model sets of particles representing organisms evolve their own internal and external rules in an attempt to out compete each other. The results include variations of ambush predators and spider ballooning. This is programming in Java using Processing and a zipped folder of the code is available here: webpages.uidaho.edu/tsoule/PC_Part...
Programming Particle Life
zhlédnutí 8KPřed 10 měsíci
Particle life is a recently developed model of interacting particles and forces that creates complex emergent behaviors mimicking many cellular structures. The version presented here is slightly simpler than traditional Particle Life, but creates equally complex behaviors and patterns.
Particle Swarms with Physics and Vectors
zhlédnutí 892Před 11 měsíci
Particle Swarms with Physics and Vectors
Drawing plants with L-Systems
zhlédnutí 1,6KPřed rokem
Drawing plants with L-Systems
Programming Simple, Fractal L-Systems
zhlédnutí 1,1KPřed rokem
Programming Simple, Fractal L-Systems
Programming a zoomable Mandelbrot viewer
zhlédnutí 1,9KPřed rokem
Programming a zoomable Mandelbrot viewer
Programming Reaction Diffusion Models
zhlédnutí 5KPřed rokem
Programming Reaction Diffusion Models
Programming Simple Procedural Flowers
zhlédnutí 894Před rokem
Programming Simple Procedural Flowers
How to Generate Fractal Trees
zhlédnutí 1,3KPřed rokem
How to Generate Fractal Trees
Programming Chaos Trailer
zhlédnutí 1KPřed rokem
Programming Chaos Trailer
Generating Procedural Maps using Perlin Noise
zhlédnutí 2,1KPřed rokem
Generating Procedural Maps using Perlin Noise
Generating Swarms of Creatures
zhlédnutí 740Před rokem
Generating Swarms of Creatures
Programming Conway's Game of Life
zhlédnutí 1,3KPřed rokem
Programming Conway's Game of Life
Using particle swarms to model Diffusion Limited Aggregation
zhlédnutí 1,2KPřed rokem
Using particle swarms to model Diffusion Limited Aggregation
Creating fractal snowflakes with recursion.
zhlédnutí 749Před rokem
Creating fractal snowflakes with recursion.
Creating fractals using recursion
zhlédnutí 2,8KPřed rokem
Creating fractals using recursion
Programming swarm based Christmas Trees
zhlédnutí 1KPřed rokem
Programming swarm based Christmas Trees

Komentáře

  • @badrakhariunchimeg1031

    I feel stable now

  • @morgan0
    @morgan0 Před 6 dny

    this is a neat technique. interesting that the search window functions to limit the spatial variance frequency. although i still think it’s generally much better to do multiple passes at lower resolution to bias it, or allow for more complex output from simple rules (like height, temp, and moisture as simple low res runs in that order, each depending on the previous, possibly with simpler rules or techniques, then upscaled, and then used to bias something to pick the final state. simple rules for each but much more complex output).

    • @programmingchaos8957
      @programmingchaos8957 Před 5 dny

      Thanks for the feedback. I tend to agree that there are a lot of things that could be done to make the terrain more interesting/realistic. I particularly like the idea of applying the algorithm at multiple scales. The purpose of the is video of course was just to be a relatively quick introduction to the approach, and a brief discussion of other application areas.

  • @Rockyzach88
    @Rockyzach88 Před 6 dny

    Now make them a slider and have it draw faster or draw slower based on another "render speed" slider or something like that. Make another "random parameter set" button that randomly picks values for the slider parameters. So much stuff you could do with this. For some reason I have a fixation on the disjoint set data structure we used to make mazes in one of my classes. I wonder if I could implement it in something like this to make something interesting. The maze like structures reminded me of it.

    • @programmingchaos8957
      @programmingchaos8957 Před 6 dny

      Great suggestion! I think Processing has a some interface libraries that include easy to use sliders. Part of my goal is definitely just to present a 'starter' project for people to build on. If you do extend it post a comment, I'd love to hear how it worked. I've seen projects that used more complex starting shapes, like letters, for the growth. Maybe starting with a simple maze and having this add twists and dead-ends?

  • @Rockyzach88
    @Rockyzach88 Před 6 dny

    There are actually mathematical ways to create these things using random numbers. I was going to try to make a project involving these when I first started learning programming but never really started. I haven't watched the video yet, so maybe you do it the way I'm thinking about.

    • @programmingchaos8957
      @programmingchaos8957 Před 6 dny

      I did it using recursion, draw a triangle, have it draw smaller triangles, etc. But I do vaguely remember seeing versions where the program places random points following some formula that leads to the same shape.

  • @freevipservers
    @freevipservers Před 7 dny

    Amazing video!

  • @Lulu58e2
    @Lulu58e2 Před 7 dny

    Awesome and inspiring, thank you for posting that. I appreciate that you left in your errors but added "Yes, I know that's incorrect" call-outs so that those of us yelling "You made a mistake!" can relax. I've built a web-based 2D animation framework for browsers with Erlang, JS and websockets, and this gives me an idea of what to use it for.

    • @programmingchaos8957
      @programmingchaos8957 Před 6 dny

      Thank you! I leave the errors in (and point them out) for a couple of reasons. I think it's a better representation of 'real' programming where we make mistakes, types, etc. I'm afraid that showing perfect coding is a little demoralizing, especially for newer programmers. And this way I don't have to rerecord over and over until its perfect :) I'm glad you appreciate the pointers to the errors. If you add this to your frame work, feel free to post another comment, I'd love to see it running.

  • @maxmustermann3938
    @maxmustermann3938 Před 7 dny

    The one thing that always annoys me about this type of procedural generation is that it's highly non-trivial to parallelize this. Of course, you can use ping-pong buffers, and then execute the algorithm for all cells in parallel. However, this means every cell considers a new type based on the old state independently, so after the step, the neighbors of a cell have changed as well, which changes whether the new type was an improvement or not. This means slower convergence (gauß-seidel vs. jacobi is basically a similiar situation) but this doesn't matter if it allows you to run it on the GPU much faster. The real problem is, this just leads to ugly maps. Sure the constraints will be fulfilled, but not in a manner that would satisfy us. So, in order to parallelize this in a meaningful way, we would have to run N threads for some number of randomly selected cells, where those cells are independent (i.e. no two cells are in range of each other). This is non-trivial, but can be done with rejection sampling. However, this just makes things harder to parallelize again. Rejection sampling is kind of a sequential thing, after all. If you try to do it in parallel and at multiple new samples at the same time, those samples are dependent on each other again and would affect each other in whether they need to be rejected or not... We could just use static patterns that divide our set of cells into independent clusters, but then this static non-random pattern will affect the results again. And computing sets of random independent clusters is... well, highly non-trivial. It is not impossible, but trying to make this a parallel thing on the GPU is very unsatisfying. Currently, the "simple" fix I use is to use a separate initialization step. I noticed that for a range of 1, the parallel version seemed to produce comparable results. But the higher the range, the more degenerate it becomes, generating mostly plains and forest in my case. So I simply initialize cells at random in (2*range+1) X (2*range+1) groups, i.e. every 7x7 pixels for range=3 are assigned the same random cell type. This looks much closer to the iterative method. I also tried a different method to select new types. Your current method is iterative and takes the best out of K randomly sampled types. In rare circumstances, it can pick a type that has more conflicts, and this is an important property. If I initialize leastConflicts to the current amount of conflicts and bestType to the current type, results are pretty bad again in my GPU example. Based on this observation, what I am doing right now is to only pick a single random type to try. I compute the signed difference in conflicts and run that through an exponential function. If the new type is an improvement, the exponential function returns a value > 1. Otherwise, the input is negative, and the worse the new type is, the smaller the value and the value will be in [0,1]. Then I use this value as an acceptance probability to allow accepting things that worsen the result (so long as the current cell isn't conflict-free already). Behaviour can be tweaked by multiplying the input to the exponential, values <= 1 mean that even improvements can be rejected sometimes, values > 1 make it less likely to pick worse cells. For a measure of how fast this is: at 1280x720 cells and a range of 3 (so iterating 7x7 cell areas), the first frame my eyes can see when the window opens is already in a stable configuration.

    • @programmingchaos8957
      @programmingchaos8957 Před dnem

      Great comments and suggestions! The exponential function sounds very similar to simulated annealing. With simulated annealing the probability of acceptance of a worse solution decreases over time as the 'temperature' decreases. One question it raises is how to measure 'ugly' maps? They are obvious to the eye, but can we characterize them mathematically? Presumably the 'count' of terrain matters: only plains and forest isn't good. But what is the right amount of mountains (and high mountains) and water (and deep water). And the distribution also matters, maybe a specific distribution of clump sizes? If it were possible to measure that then you could do meta-optimization on the algorithm to tweak it to give the best terrain types. One question, as a I mentioned in the video, I found using high mountains and deep water as 'anchoring' terrain seemed to help. Have you experimented with that approach at all?

    • @maxmustermann3938
      @maxmustermann3938 Před dnem

      @@programmingchaos8957 the way I am initializing the terrain is kind of inspired by this anchoring approach. Since I use larger squares of a uniform type, so I am basically anchoring or biasing the algorithm such that it won't just end up in one of these very uniform solutions. This could of course be combined with what you showed in the video and I think it could be further improved. For example, if you make the squares quite big, the converged solution can have some straight long edges. So one thing that would make sense is to randomly blend over to the surrounding terrain types in this initialization to remove these patterns. I definitely remember watching videos on simulated annealing before. That might be where this idea came from, I felt like I knew about something similar where the exponential function was used and now that you mention it I think it was simulated annealing. Although I feel like I have seen these concepts in some Monte Carlo sampling strategies as well. The exponential function really is quite useful across many applications, recently I learned about how to use what is basically exponential decay for interpolating animations smoothly.

    • @programmingchaos8957
      @programmingchaos8957 Před dnem

      @@maxmustermann3938 I also saw some suggestions to try multi scale systems, a larger cell of forest that when zoomed in has more varied terrain. Which is quite a bit like anchoring terrain regions.

  • @Eta_Carinae__
    @Eta_Carinae__ Před 7 dny

    Hi. Thanks for the video, it's very clear and easy to follow, despite you using C. I've been wondering about something for a really long time, and I'm wondering if you have any insights. Suppose I have something like a global constraint. What I mean is: in your example concerning forest, beach and ocean, to check if the contraint is satisfied - that forest can't touch the ocean - all you need to do is check a local kernel around each cell to check satisfaction. I'll call this a _local constraint,_ to contrast a _global constraint,_ whereby I have to check the whole array to determine if the constraint is satisfied (maybe in principle). One global constraint that I've been wondering about for example is say, "group-sizes must be distributed according to a power law" - look up something like mathematical percolation or the Ising model at critical temperature to get an idea of what this looks like. I think this global constraint tends to be satisfied by terrain generation in nature, so I was wondering: is there any sort of computational efficiencies we can exploit for global constraints like this; maybe even global constraints of a stochastic nature like this one, where the degrees of freedom aren't really clear until we see _a_ solution? And, could those efficiencies scale to something that might run in some practical time at the size of say Minecraft?

    • @programmingchaos8957
      @programmingchaos8957 Před 6 dny

      I'm glad you enjoyed it. Making the coding clear is one of my main goals so I'm glad to hear that you found it clear. The language is Java, not C, but at this level they are almost identical. The major difference is the arrays are declared as: int[][] map; // Java not int map[][] // C Global constraints are a great idea. I think the answer depends in part on the type of constraint. For example, if the constraint was no more than 20% forest then it would be easy to update a global counter as part of the constraint satisfaction algorithm. Every time you added a forest, add one to the counter, every time you removed a forest subtract one. But that's the simple case. For your group sizes constraint I think the only solution would be a separate pass over the whole map calculating the required statistics. But for a game this would only need to be done once at the beginning, so even if it took a while (tens of seconds) it could be hid behind a loading screen, tutorial, character selection screen, etc. Another interesting question is does this (at least for the power law) happen automatically with this algorithm? I could see where very large sets of terrain are increasingly unlikely. Or is there a way to seed the initial map to get a desired distribution? E.g. by placing random circles of forest that follow a power law.

    • @Eta_Carinae__
      @Eta_Carinae__ Před 5 dny

      @@programmingchaos8957 For the afforementioned algo.s, it's an emergent feature. Both of them are essentially cellular automata that update based on a local kernel passing over the grid element-wise with random fluctuations in cells, which would probably be more efficient than passing over the whole thing, checking the statistics and then making an adjustment and checking to see if the statistics are closer, etc. (plus I imagine that'd look more unatural), but scaling these things up is still a nightmare. I tried a while ago getting them to a good enough looking resolution, and it got to taking tens of minutes in Python (albeit using a less-efficient algorithm for it; but I kinda had to since I wanted to also track the correlation-length over time). The thing about the power law distribution is that it's scale-free, so you can zoom into any part of the distribution and it should be similar. This is really the property I'm interested in, because _in principle,_ if you have local information around some region in your grid, then that should also give you global information - but it only givees you the information about the distribution, not about how that distribution is realised. I just thought that it would be nice if I could exploit that fact to allow it to scale faster.

    • @Eta_Carinae__
      @Eta_Carinae__ Před dnem

      @@programmingchaos8957 Sorry, I typed a response to you, but it disappeared. The aforementioned algorithms are essentially cellular automata that check some local kernel around a cell and transform it depending on that calculated value. The power-law distribution is emergent from these rules. As they are, these algorithms scale pretty poorly both in space and (particularly of interest) time. There are more efficient algorithms that one can use (say for the Ising model), but you end up sacrificing some other things. It might be fine for the purposes of terrain generation, but I wanted to track the correlation-length of the whole system in real-time, which it looks like only the Metropolis algorithm was capable of doing. Nonetheless, I'm still unconvinced about the traditional approaches. I tried scaling these guys up before, and they took me tens of minutes on my machine with Python (I couldn't quite get what I wanted out of Numba; it threw a fit at me when trying to parse multidimensional arrays, so I shelved it. I know some C now, so I might revisit it in Cython). The thing about power-law distributions, is that they're self-similar at different scales - if you zoom in or out of the distribution, you end up seeing the selfsame distribution. Think: the Pareto 80/20 rule in economics: 80% of the wealth is in 20% of the population; 80% of _that_ wealth is in 20% of that population, etc. etc. Similarly, with these phenomena, if you zoom in or out of these grid-arrays, the group-size distribution is the same. This property is what's known as being "scale-free". This means that _in principle,_ we should have information about the global distribution of group-sizes from local information in some region. I'd hoped I could use that fact to kind of 'compress' the grid in some way, maybe to speed things up. I would say that with these algorithms, seeding can be difficult. What tends to occur is that the major groups end up moving around in non-trivial ways, making them unrecognisable from the initial seed. You can probably obtain utility out of seeding if you don't run them for a very long time, but you want to run these things for a very long time to obtain power-law results.

  • @maxmustermann3938
    @maxmustermann3938 Před 7 dny

    If I find the time, I'll implement this on the GPU. If anyone else is interested, my concrete idea to do this would be: - preallocate a buffer with an upper bound for how many particles can exist - keep an atomic counter for the current amount of particles - initialize particles with a sorting key t, for example uniform from 0 for the first particle and 1 for the last particle, with the others having ascending values in between - when a particle is added, you increment the counter and add it to the end of the buffer. You assign it the mean of the two keys. Special treatment is needed when inserting between the first and last particle due to the circular nature of the list - sort all particles by t (since I like to use CUDA, this is trivial, there are GPU sorting algorithms you can just use pre-implemented there, otherwise you need to code it yourself or find an implementation somewhere) Forces etc. are straightforward, the list is stored as a packed linear array after all. However, the repulsion/attraction needs to consider all particles, so in order to avoid iterating over all of them you need a spatial datastructure to accelerate this. The "gravitational" force could be approximated using an quadtree for example which averages information together, and then you use the averaged information for things that are further away.

    • @programmingchaos8957
      @programmingchaos8957 Před 5 dny

      This sounds like a great idea. If you implement it I would be very interested in seeing the results.

    • @maxmustermann3938
      @maxmustermann3938 Před 5 dny

      Edit: sorry, my previous reply was thinking about another video I commented on. I haven't implemented this one yet, I was thinking of the procedural generation with constraints when I typed this reply out earlier.

  • @BeautyInMath
    @BeautyInMath Před 8 dny

    Finally, I have a draft of the 3d version in threejs. Again, I will put the link where you found the two dimensional version. Cheers! Happy programming! And thanks again for such great content! :) Update: If you already found the previous version, you just need to add "-3d" at the end of the link before the slash.

    • @programmingchaos8957
      @programmingchaos8957 Před 4 dny

      That's great! I'm glad you're enjoying the content. I really need to find the time to try out GeoGebra.

  • @frodo279
    @frodo279 Před 8 dny

    Awesome videos! Reminds me of chemical morphogenesis by turning

    • @programmingchaos8957
      @programmingchaos8957 Před 6 dny

      Thank you! Your comment is on the differential growth video, have you checked out the diffusion reaction video: czcams.com/video/COMvgTLTw6g/video.html I think that is a model of chemical morphogenesis, although that's not the term I'm familiar with.

    • @frodo279
      @frodo279 Před 6 dny

      @@programmingchaos8957 ahhh! The equations are similar to the chemical morphogenesis! Fun fact this is prolly one of Turing's less known contributions but one of my favorite!

  • @zitronenwasser
    @zitronenwasser Před 8 dny

    This is a great showcase of how the process of procedural generation can go, and it's very well explained, thank you :) I do want to note, around 22:30 (dx + x + worldWidth) % worldWidth = (dx % worldWidth + x % worldWidth + worldWidth % worldWidth) % worldWidth = (dx % worldWidth + x % worldWidth + 0) % worldWidth = ( dx + x ) % worldWidth So it can be shortened :) Unless P5js has a modulo operator that works differently from normal math that is

    • @programmingchaos8957
      @programmingchaos8957 Před 8 dny

      Thank you! Making sure the explanations are clear is one of my main goals, so I'm glad that's working. Keep in mind that dx can be negative (it starts as negative of the range), if x is small (e.g. less than range) then dx + x is negative and, at least in Processing/Java % of a negative is that negative value. E.g. -2 % worldWidth = -2, which will cause an array out of bounds error. So, the +worldWidth is to wrap the negative cases.

    • @zitronenwasser
      @zitronenwasser Před 7 dny

      @@programmingchaos8957 Ah i understand, thank you The actual Modulo operator in maths is defined differently then, and i'm honestly not sure why it's done this way in javascript...

    • @programmingchaos8957
      @programmingchaos8957 Před 6 dny

      I'm not sure either. But I double-checked that -4 modulo 100 does return -4, not 96, which would make your approach work.

    • @zitronenwasser
      @zitronenwasser Před 6 dny

      @@programmingchaos8957 Unfortunate :( But if Javascript does not follow the normal modulo definition + worldWidth is a clean fix for it

    • @programmingchaos8957
      @programmingchaos8957 Před 3 dny

      @@zitronenwasser Me neither. It's why I've gotten in the habit of testing the behavior of functions to make sure they act they way I expect. It's rare, but there's nothing worse than spending hours trying to fix a bug that caused by unexpected behaviors rather than a mistake.

  • @qbytx
    @qbytx Před 8 dny

    one of the most insightful and straightforward videos on this topic on youtube. 5/5 tutorial <3

    • @programmingchaos8957
      @programmingchaos8957 Před 8 dny

      Thank you! I'm really glad that it was clear and straightforward, as making the explanation clear and easy to follow is one of my main goals.

  • @phobosmoon4643
    @phobosmoon4643 Před 9 dny

    How my uneducated 32 year old self taught not-quite 'programmer' thought of this before watching your video: 'bucket algorithms' and 'water algorithms'. Haha ignorance is truly bliss but thank you for the video! I'm trying to figure out how to do this with mpi in the bash terminal.

    • @programmingchaos8957
      @programmingchaos8957 Před 8 dny

      I'm glad you enjoyed the video. It's been a long time since I've use mpi, so probably can't help you there. But I would love to hear how it turns out.

  • @jerryrusso5656
    @jerryrusso5656 Před 9 dny

    great content and great channel man, I appreciate how you explain everything you are doing.

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Thanks! I'm glad to hear that the explanations are working - that's one of my major goals.

  • @NoonianSoong403
    @NoonianSoong403 Před 9 dny

    Holy cow it’s my old professor, always loved your work, glad CZcams recommended this to me (Kyle Morgan, you wouldn’t remember me lol but I was a decent student, software engineer now)

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Hi! It's great to hear the degree is serving you well. I hope you're enjoying the work. As you can probably tell I'm still enjoying teaching :) And thought I should help a larger audience.

    • @NoonianSoong403
      @NoonianSoong403 Před 9 dny

      @@programmingchaos8957 You’re a great teacher and professor. Your research has always had my attention. I’m treating SE as a career, which has served me well, but I miss the science side of CS. I have a library of rigorous math, CS, and physics books and I’m trying to figure out how to be valuable in those fields. Your work is endlessly inspiring and accessible to so many. Thanks for responding, I’ll be watching all your videos on this channel this weekend. Thanks again for not only being a great teacher but also sharing your fascinating research and creative projects with students at every level, cheers!

    • @TheNSJaws
      @TheNSJaws Před 8 dny

      oh this is an incredibly wholesome reunion

    • @programmingchaos8957
      @programmingchaos8957 Před 6 dny

      You're very welcome! I have to say that one of the huge advantages of being a professor (besides getting to teach) is the flexibility to try the random projects that seem interesting.

  • @zaidalhussain889
    @zaidalhussain889 Před 9 dny

    Wholsome video, fun and educational! Love you terry 🫶

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Thank you! I'm glad you're enjoying the content. If there's any topics you'd like to see covered let me know, I'm always looking for new ideas.

  • @awerclash1554
    @awerclash1554 Před 9 dny

    nice video, unc 😃

  • @llothsedai3989
    @llothsedai3989 Před 9 dny

    So - why not have a sat solver on algorithms themselves, procedurally generate algorithms then constraint solve.

    • @programmingchaos8957
      @programmingchaos8957 Před 8 dny

      Interesting idea. If the constraints necessary to make the algorithm work properly were well defined this could be doable. There is a field, genetic programming, that evolves programs to solve problems. Some of the ideas of fitness from that field might translate into constraints.

  • @g0kada
    @g0kada Před 9 dny

    Didn't absorb it all as I have many many things I still need to learn, but the way you explain makes it so much easier and fascinating, you made me feel like I was consuming something that should be paid. Great video! Also, just a rather silly thing. You might want to flip your webcam next time, so when you gesticulate to the right/left, it'll be the right/left meant to be shown.

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Thanks! I'm really glad you found it useful. Good point about flipping the camera. I should have noticed that during editing. Thanks for the suggestion.

  • @Kavukamari
    @Kavukamari Před 9 dny

    so, Wave function collapse is a subset of this?

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Not exactly. In WFC values are only assigned if they don't violate any constraints. If the WFC algorithm finds a variable (cell) with no assignable values (e.g. mountains on one side and deep water on the other) it either backtracks, undoing and retrying some previous assignments to avoid the issue, or starts over from scratch. In contrast the minimum conflicts algorithms just assigns the value that leads to the fewest conflicts and hopes it gets fixed on a later pass, by changing some of the neighboring values. The least conflicts algorithm is simpler to code and runs faster, but if there aren't very many solutions it may fail to find a solution with no conflicts. WFC is harder to code and may take longer to run, but is more likely to find a solution when they are rare.

  • @rafa_br34
    @rafa_br34 Před 9 dny

    Interesting how you can easily "filter" randomness to end up with some order, Stable Diffusion works in a very similar way, the only difference is that instead of using some simple logic it uses a UNet to predict the noise. Also, (not that I have anything against but) you should consider using something like shadertoy, GPUs are much much better at munching tasks that can parallelized, but for learning yea, using that makes it way easier to understand what is going on exactly.

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      I hadn't thought about the relationship to Stable Diffusion, there is an interesting similarity. And yes a shader would definitely be the way to do this if you wanted it to be super quick or had a much bigger map. As you noted, my focus is really on teaching the algorithm. But it does make me think that I should put together a video or two on basic shader programming and its applications. Thanks for the suggestion.

  • @BigBrainHacks
    @BigBrainHacks Před 9 dny

    Thanks for the video!

  • @Embassy_of_Jupiter
    @Embassy_of_Jupiter Před 9 dny

    This would be interesting paired with machine learning. Let's say I train a diffusion model on real world earth map data. Then trough contraint satisfaction I can guide the result in some direction for more "correct" results and artistic control.

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Great idea! I think it's been done on a smaller scale without machine learning using small, sample maps. E.g. take a small sample map, record what terrains are next to each other and which aren't, and use that to generate the rules. It can be done with any pattern, not just maps. But the idea of using ML and real maps is really good.

    • @Embassy_of_Jupiter
      @Embassy_of_Jupiter Před 9 dny

      @@programmingchaos8957 That would be cool, generate the model and the constraints from real world data. But I imagine the hardest part is getting detailed maps and how to map real data to a constraint model, what features you care about etc.. It would be cool to do all this with hyperspectral satellite images, not just RGB. So you can accurately distinguish different types of terrain, vegetation and man made structures. And all that in 4D would be even cooler. Then learn to model the evolution of a river with constraint satisfaction 😄 Realistic world generation has always been my favorite computational problem to daydream about. I love to see all these different approaches on CZcams.

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      I think getting detailed images of real terrain isn't too hard these days. But if they need to be annotated for the ML algorithm to work that may be harder - although I'm constantly surprised at the amount of annotated data that's out there for free. 4D would be fantastic, not sure if the high quality data goes far enough backwards in time though. World generation is definitely fun. I particularly like the versions that add cities with random 'facts' or descriptions (much easier these days with LLMs), so you can image visiting them.

  • @RupertBruce
    @RupertBruce Před 9 dny

    When to write the unit test for CheckConstrains? When you first use it, you have in mind what you expect so a perfect time to write the test. If you don't want to interrupt your flow, you delay the test case until you have written out all the use of the results. I'm looking forward to having a reliable AI write the test at the same time as generating the current stub function: not yet implemented...

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Writing the tests for the function is a great application area for an AI. I'm a little skeptical of the claims that it will take over programming. LLMs are great at problems that have been solved hundreds of times already, writing a resume, legal brief, or a quick sort algorithm, which makes them seem really impressive. But most programming projects should include some new aspects, requiring new solutions, which LMMs are not so good at. But generating tests for human written code seems like a space they would perform well in.

  • @gabrielgolzar
    @gabrielgolzar Před 9 dny

    Reminds me of the wave function collapse

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Good catch! It's very similar, but in minimum constraints the algorithm will assign values that violate the constraints with the hope of fixing them later. WFC traditionally will backtrack and undo some of its previous assignments (or start over) if it finds a variable (cell) with no acceptable values (e.g. no terrains that can be assigned without violating constraints). It means the WFC is more likely to find rare solutions, when minimum conflicts will just keep trying invalid values, but it also means that WFC is slower - and more complex to code. As a side note WFC is even more similar to (maybe identical) to the forward checking algorithm for constraint satisfaction.

  • @kuenstername
    @kuenstername Před 9 dny

    22:46 - I feel very stupid now, I had struggled a lot with rendering in a given range. This is so much cleaner. Not really good at coding though.

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Don't be hard on yourself. I've been coding for literally decades. And it still took me probably 6 or 8 different projects that used similar range checks to come up with that approach. I remember starting with 8 separate if statements, one for each neighbor, and each with it's own boundary checking conditionals, something like 24 if's altogether :)

    • @kuenstername
      @kuenstername Před 8 dny

      @@programmingchaos8957 That is a bit relieving! Thank you for the Video :=)

  • @Tanger68
    @Tanger68 Před 10 dny

    Very well explained, thank you

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Your welcome! I'm glad to hear that the explanation was clear, that one of my major goals in these videos.

  • @user-by8fp5uw2o
    @user-by8fp5uw2o Před 10 dny

    Question for ya when you have a chance, what’s the difference between this and the wave function collapse? I’ve seen that method used for sudoku as well

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      This minimum conflicts algorithm is willing to assign values that violate constraints with the hope of fixing it on a later pass. My understanding is that WFC won't assign a value that creates conflicts. If it reaches a variable that has no valid assignments it backtracks and undoes recent variable assignments and tries different values for those variables hoping to avoid the conflict (or it starts over). This makes WFC much better at solving problems with very few solutions (like sudoku) and it potentially can report that a problem is unsolvable (there is no valid set of assignments). However, the backtracking is trickier to code and it's potentially much slower. So, if you know there's a lot of solutions available, which is typical for procedural generation, this minimum conflicts algorithm is simpler and faster. But if there are relatively few solutions available WFC or other exhaustive search algorithms may be necessary to find one of the solutions. As far as I can tell WFC is very similar (identical?) to the forward checking algorithm for constraint satisfaction.

  • @2_Elliot
    @2_Elliot Před 10 dny

    This is an awesome video! I love the idea of it generating in real time, I could imagine implementing painting-systems where you can live edit the world and paint in your own details.

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Thank you! And that's a great idea! Painting in the rough map to start with, 'I want a mountain range here, a deep lake there, a massive forest in the North' and then letting the algorithm fill in the details, and then being able to go in and re-edit, clean up shorelines, merge mountain ranges, add mountain passes, etc. would be fantastic.

  • @jenbanim
    @jenbanim Před 10 dny

    The ability to add initial values like you did with the island seems like the coolest feature here. I could imagine drawing in a rough landscape idea with an image editor and then handing those initial conditions to the constraint satisfier to turn it into an actual map

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Thanks! I agree that that makes it much more interesting. I think its sometimes referred to as a falloff map if you want to learn more about how it can me done.

  • @HairyPixels
    @HairyPixels Před 10 dny

    ohhhhh I'm having an idea! How about a game where you play through a map which is generating itself in real time? I wonder if that concept would be viable.... If I had more free time I would start on that tomorrow morning. :)

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      So, the map isn't decided at all until the player moves into the new areas? That would be interesting, especially if the player's actions influence what appeared next. So, the terrain would have to follow the rules, but if a given cell could be either plans or forest which one it became depended (in part) on the player. For example, if they traveled from forest it was more likely to continue as forest, or they had some ability to influence the probabilities. If you make it Ill play it! :)

    • @HairyPixels
      @HairyPixels Před 9 dny

      @@programmingchaos8957 I didnt' think that far ahead :) I had an idea of the maps generating in a 2D platformer style. Having some gameplay elements advance the generation sounds more viable. Making a game out of that would require some serious deep thinking....

  • @uniaddict
    @uniaddict Před 10 dny

    This is so cool :) thanks for sharing!

  • @diegofloor
    @diegofloor Před 10 dny

    This is great! subscribed

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Thanks! I'm thrilled that you enjoyed it. Hopefully the other videos will be useful as well.

  • @mewdeen
    @mewdeen Před 10 dny

    Every now and then CZcams drops a gem in my recommended feed. This is one of those times. Liked and subscribed! 👍

    • @programmingchaos8957
      @programmingchaos8957 Před 10 dny

      Thanks! I'm very glad your enjoying the videos. If you have an ideas for projects you'd like to see video on, please feel free to let me know.

    • @swyveu
      @swyveu Před 2 dny

      Exactly my thoughts!

  • @sharkkbaron
    @sharkkbaron Před 10 dny

    Very cool video! Nice to explain in detail what you are doing.

  • @downloadjpg
    @downloadjpg Před 10 dny

    so glad the algorithm picked this one up, awesome channel!!

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      Thank you! I hope some of the other videos are also useful. And if you have suggestions for topics, please feel free to share them.

  • @morwar_
    @morwar_ Před 10 dny

    This could be used to generate test cases for obscure scenarios. One time I used constraint programming to generate all possible cases (maximum 100s different cases) with a bunch of weird rules given by business analysts. It proved that they didn't even knew what they were asking. It simplified the rules in the end, because they were cancelling each other in a few cases.

    • @programmingchaos8957
      @programmingchaos8957 Před dnem

      Very cool application! It is surprising how many problems can be reformulated as constraint satisfaction and then there's well defined solution approaches.

    • @morwar_
      @morwar_ Před dnem

      @@programmingchaos8957 Indeed. I believe that they sound too formal to be used out there. That's why we don't see more of it. In more important projects or fields, I believe this method is treated with more importance. I wish I could work with it.

  • @discreet_boson
    @discreet_boson Před 10 dny

    Super cool! I love the procedural generation niche

    • @programmingchaos8957
      @programmingchaos8957 Před 10 dny

      Glad you liked it! Procedural generation and artificial life (especially evolutionary alife) are my two favorite programming areas.

  • @be1tube
    @be1tube Před 10 dny

    Rather than randomly generating terrain types in leastConflicts, you can keep a set/arrayList of the types with the least conflicts. Then choose randomly from that list. This avoids the "fill everything with mountains" problem and also does not skip types or generate them twice.

    • @programmingchaos8957
      @programmingchaos8957 Před 8 dny

      Definitely! I was thinking my approach was a bit easier to code, and was trying to keep things simple. But removing items in a random order from and ArrayList would be pretty simple. Languages with a built in shuffle function would also work well of course.

  • @oolong4700
    @oolong4700 Před 10 dny

    Just found this channel, this is really cool! I love it.

    • @programmingchaos8957
      @programmingchaos8957 Před 10 dny

      Thank you! I'm glad you're enjoying it. If you have any favorite projects you'd like to see coded let me know.

  • @WalterSamuels
    @WalterSamuels Před 10 dny

    Very cool. I think you need to figure out a way to calculate every cell at once though. For example for plants, it's not that it's always the top layer that grows, but rather every plant layer divides and spreads out further, which makes it look like it's growing upward. I don't like the idea of using random. Nothing is random in nature, and pseudo-random is just bias. I'm sure you could come up with more clever ways to do that too. For example, rule 30 cellular automata looks random, but is actually not. Incorporate some clever rules like those that exhibit complex seemingly "random" behavior, but are actually deterministic.

    • @Eta_Carinae__
      @Eta_Carinae__ Před 7 dny

      People used Rule 30 as a pseudo-random number generator for a long time after it was developed. pRNGs are all like this, so there isn't really a material distinction between Rule 30 and other methods like it. Also it's not correct to say pRNGs are biased. If they were, we could detect it by running it a whole heap of times, and generating the empirical distribution for the frequency of numbers it generates, and test to see if it's significantly different from a uniform distribution. We use pRNGs _because_ there is no test we have yet developed that can distinguish them from true RNGs. All we know is that they will eventually cycle, because they are determinate.

    • @programmingchaos8957
      @programmingchaos8957 Před 6 dny

      Very interesting idea! It would be possible to go through and calculate the 'next' value, but not update it until all of the next values were calculated. This is the standard approach for cellular automata like Conway's Game of Life czcams.com/video/SgrenppLn8c/video.html. Of course, it could lead to the problem of picking conflicting choices for neighboring cells and having to fix it on the next iteration. It might give interesting results for the plants, not sure if it matters for the maps or textures. I understand wanting everything to follow solid, deterministic rules. The issue with purely deterministic rules is that they will always lead to the same outcome and I want different outcomes each time. I could use deterministic rules with (pseudo)random starting conditions, but that might give a smaller range of outcomes (and doesn't completely do away with randomness). I prefer to think of the (pseudo)randomness as representing unknown hidden variables. For example, coin flips are not truly random - in the sense that if you knew the exact forces being applied at the beginning of a flip then a physics simulator could tell you whether it would be heads or tails (and I believe that accomplished slight of hand artists can flip a coin exactly N times to control whether its heads or tails). But if I want a coin flip in a game I'm just going to randomly determine heads or tails, not build a physics simulator for coin flips. This is the same idea, for plants I'm not going to try to simulate all of the factors that cause a plant to branch or not, I'm just going to choose to randomly branch. However, that's because of my relatively simple goals. There's probably a good use for a program that does simulate all of those factors. (And a mini-game where you try to apply the forces to get a coin to flip exactly N times might be fun.)

    • @programmingchaos8957
      @programmingchaos8957 Před 6 dny

      Few, if any, pseudo-random number generators are biased in the sense of generating more 8's than 9's. But all(?) have artifacts that can be detected with subtle statistical tests. The Wikipedia article on pseudo-number generators has a nice overview of some of the issues. My understanding is that because of this for super high risk areas, like generating encryption keys for launch codes, they use hardware random number generators that use physical phenomena, like radio static, to generate random values.

  • @aleksa_etf
    @aleksa_etf Před 10 dny

    Interesting. Is it possible for conflict resolution to create infinite loop? Like for example, you fix one set of conflicts and after few iterations you get back at initial set of conflicts (like those cellular automata that regenerate themself)

    • @programmingchaos8957
      @programmingchaos8957 Před 10 dny

      I'm not sure. I think it's very unlikely for this algorithm to get stuck in a literal loop because it's making random selections to resolve conflicts. So, to get stuck in a loop it would have to be a condition where there are only a few options that it cycles through. On the other hand its very possible for it to search endlessly through different terrain assignments without every finding a conflict free solution - it's just unlikely to loop. There are other systematic conflict resolution algorithms that never get stuck and can say whether or not a solution exists, but they are much slower and because they are systematic, don't lead to interesting terrains. They are useful for problems like sudoku, where there are very few solutions, or if you want to know if any solution exists.

  • @M_1024
    @M_1024 Před 10 dny

    You could make your code simpler by not including a separate condition for undefined tarrain type, and just treating it a regular terrain type which never satisfies any constraints: notAllowed[0] = {100, 100, 100, 100} without changing other constraints: notAllowed[n][0] = 0.

  • @M_1024
    @M_1024 Před 10 dny

    I am going to use a similar algorithm to simulate stuff by generating a map with one dimension: time. Pixels are going to be replaced by states and there is a constraing violation if state[t] can't evolve into state[t + 1]. Also I am going to add time travel to this system.

    • @programmingchaos8957
      @programmingchaos8957 Před 4 dny

      That's sounds really cool! I'd be interested in hearing about how it turns out if you want to share the results.

  • @M_1024
    @M_1024 Před 10 dny

    The "Perfect CS" algorithm would look something like this: ``` generate_random_map(); // each pixel is random value while (!is_map_valid()) { // check if map has any constraint violations generate_random_map(); // try again } ``` Of course this would be very inefficient and have exponential time complexity. So what other algorithms produce the same output (with same probabilities) as "Perfect CS"? Is algorithm shown in this video "perfect"? Is WFC "perfect"?

    • @Erkle64
      @Erkle64 Před 9 dny

      A faster solution using multiverse theory would be: generate_random_map(); if (!is_map_valid()) destroy_universe();

    • @M_1024
      @M_1024 Před 9 dny

      @@Erkle64 True, but my computer can't destroy the Universe yet :(.

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      I'm not sure about perfect, but one formal term is 'complete'. A complete algorithm is guaranteed to find a solution if one exists and return false if no solution is possible. The minimum conflicts algorithm I presented is definitely not complete. It is only find likely to find a solution if lots of solutions exist - which should be the case for procedural generation. WFC can be complete if every time it reaches a variable the no longer has a valid assignment (e.g. a cell between forest and deep water) it backtracks, undoing previous assignments and trying new ones until it solves the conflict. But that type of exhaustive search tends to be a lot slower. With regards to probabilities I suspect, but don't know for sure, that both minimum conflicts and WFC collapse create terrain that's 'clumpier' than your algorithm would produce. Because the easier to find solutions have large clumps of the same terrains. In fact, if a map problem is hard (for example if the range where the cells can't conflict is large) the minimum conflicts tends to 'give up' and just push everything towards a middle terrain like plains.

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      I want to live in the universe where all of my code compiles and runs correctly the first time. But I suspect that even in an infinite multiverse that one doesn't exist :)

    • @M_1024
      @M_1024 Před 8 dny

      @@programmingchaos8957 By "perfect" I don't mean a program that finds a solution, but it also needs to have the same probability distibution as the orginal algorithm

  • @thomasaton
    @thomasaton Před 10 dny

    Is this same as the "Wave function collapse" algorithm?

    • @thomasaton
      @thomasaton Před 10 dny

      yup

    • @programmingchaos8957
      @programmingchaos8957 Před 10 dny

      Very similar, but not quite the same (I'm pretty sure). With minimum conflicts the algorithm will assign a value (terrain) even if it violates constraints. With WFC it will only assign conflict free values, if there's a variable/cell has no acceptable values left, WFC will backtrack, undoing past assignments, and try again (or will start over from scratch). This means that WFC is more likely to find a solution if they are rare, but can be much slower. WFC is, as far as I can tell, identical to the forward checking algorithm that is used for constraint satisfaction.

  • @FFehse-dk9is
    @FFehse-dk9is Před 10 dny

    Remember to include some check that guarantees termination, otherwise this might run forever for unsatisfiable problems

    • @programmingchaos8957
      @programmingchaos8957 Před 10 dny

      Right! But this is the drawback to local search, because it's fairly random there's no guarantee that it will find a solution even if one exists (technically its an 'incomplete' search). So, the best you can for termination is stop after a lot of tries. The assumption is that if you are doing procedural generation there should be a lot of possible solutions and so the algorithm will find one. If there's only one (or possibly no) solutions it's better to use a complete search algorithm, but they can be harder to code and a lot slower to run.

  • @nand3kudasai
    @nand3kudasai Před 10 dny

    This is really cool. You should try with particles that die after some time and respawn randomly. Maybe moving the flowfield. Im sure you know this but to map a number N (0,1) to 0, Max. You can simply do N*Max. The beauty of normalized values. Or 0,1 > a,b = a + n*(b-a) (iirc) Which is useful on vectors.

    • @programmingchaos8957
      @programmingchaos8957 Před 9 dny

      I'm glad you enjoyed it. The dying and respawning is clever idea, I'll have to give it a try. Thanks for the comment about N*Max. I tend to fall into the habit of using the same tools even when they are not ideal. In this case I had been using map() a lot and didn't stop to think about the simpler approach.

  • @fifoflo
    @fifoflo Před 10 dny

    Just discovered your channel, fantastic video, thanks a lot for sharing this type of content!