Cellular Automata | Procedural Generation | Game Development Tutorial

แชร์
ฝัง
  • เผยแพร่เมื่อ 20 ธ.ค. 2024

ความคิดเห็น • 78

  • @WhiteBoxDev
    @WhiteBoxDev  4 ปีที่แล้ว +45

    Errors in this video:
    1. At 2:10, I state that there are four neighboring white tiles. Obviously, there are actually five neighboring white tiles.
    2. At 7:40, the random number generation is placed on line three. This should instead be inside of the for() loop on line four so that each value in the noise grid is randomized independently.

    • @clasherz_gut328
      @clasherz_gut328 2 ปีที่แล้ว +2

      deserves more attention, the way you explained this video makes it so useful. thanks a lot, i just implemented this into my 2d scrolling game and it is very cool

    • @survival_man7746
      @survival_man7746 2 ปีที่แล้ว

      yeah I knew the caves shouldn't look spiky

    • @LineOfThy
      @LineOfThy 2 ปีที่แล้ว

      @@survival_man7746 uuuuuh that's not the problem here

    • @survival_man7746
      @survival_man7746 2 ปีที่แล้ว

      @@LineOfThy yes it is, maybe we just don't see the same way what I call spikey cave because I did "cave"/"island"/"whatever you use it for" generation more than one time and I know what it is supposed to look like under normal circumstances

    • @LineOfThy
      @LineOfThy 2 ปีที่แล้ว

      @@survival_man7746 I don't know what you mean by spiky cave but I'll take your word for it.

  • @darkgecko5581
    @darkgecko5581 4 หลายเดือนก่อน +4

    Loved this video because it was just concept and not a walkthrough of any particular game engine or code. I've been working through a lot of Unity tutorials but my brain needed something meta level to see how the nuts and bolts actually work. Thank you kindly

    • @WhiteBoxDev
      @WhiteBoxDev  4 หลายเดือนก่อน

      @@darkgecko5581 Glad you found it helpful. 🙂

  • @svenskazengrodan
    @svenskazengrodan ปีที่แล้ว +3

    I really appreciated all your map generation videos. Very pedagogical.

  • @sushismitcher225
    @sushismitcher225 10 หลายเดือนก่อน +3

    It's really cool, but I'm having performance issues. I'm probably going to create a chunk system so that the tiles only have to check nearby tiles, but I'd love to learn about other optimisation methods. Great video!!

  • @GbyP
    @GbyP ปีที่แล้ว +2

    I really needed this so I can finally understand my CS projects for class

  • @123a169
    @123a169 3 ปีที่แล้ว +18

    This was super informative! I never realised how simple implementing CA could be.
    Definitely going to give this a try to smooth out my maps.

  • @DrCaesarsPalace_MD
    @DrCaesarsPalace_MD ปีที่แล้ว +4

    So cool!!
    In the pseudo code at 8min you would want to regenerate the random number for each (i,j) cell in the grid 👍

  • @lln6123
    @lln6123 5 หลายเดือนก่อน

    A very big thank you, I was able to rebuild it in my own little 2D engine and saving it as bmp.
    Next will be something like using Fragment-Shader instead saving and loading the image all the time...

  • @NikoKun
    @NikoKun 6 หลายเดือนก่อน +1

    Neato. The maps this generates remind me a little of the level design from the old Sega Genesis game Sub Terrania.

  • @andisarifi5805
    @andisarifi5805 10 หลายเดือนก่อน +1

    great video!

  • @DaveDude323
    @DaveDude323 3 ปีที่แล้ว +4

    Thank you so much Klayton. This video has really helped me understand how cellular automata works, and it is by far the easiest to follow tutorial on this subject on youtube.
    I like how rather than just writing actual code and talking about it as you do it, you use pseudo-code and break it down to explain in detail what each step is actually doing.
    Now that I understand how Noise generation and Cellular Automata works, I'm confident that I can work on making my own script in Unity based upon your information in this video for use in the Cave -crawling game I'm making.

  • @chasehorton2324
    @chasehorton2324 3 ปีที่แล้ว +5

    Extremely high quality video, you deserve many more subscribers

  • @marcuthdev
    @marcuthdev 11 หลายเดือนก่อน

    14:00 como você fez aquele ruído ficar assim? Estou há alguns dias tentando fazer algo parecido em TypeScript, mas sem sucesso. É para gerar cavernas em um jogo como Minecraft 2D

  • @LKamodon
    @LKamodon ปีที่แล้ว +2

    Great video! At 8:55 it was a bit confusing seeing the whole grid being re-generated from scratch as you narrated "you will notice as the iterations increases", maybe you could have increased the iteration counter by pressing 6 multiple times instead. I don't mean to be rude, just trying to provide a bit of constructive feedback. Thank you for making the video.

    • @WhiteBoxDev
      @WhiteBoxDev  ปีที่แล้ว

      Thanks for the feedback! Since the demos are not scripted like the rest of the video, my error-ridden brain takes over and thus we see some explanation quirks.

  • @axellacce1470
    @axellacce1470 4 ปีที่แล้ว +2

    Really nice video. Your voice is clear and audible and your explanation are detailed an quite easy to understand 👌

  • @shenshaw5345
    @shenshaw5345 2 ปีที่แล้ว +2

    Great explanation! Surprising how simple it is.

  • @NathoSteveo
    @NathoSteveo ปีที่แล้ว +1

    Awesome video mate thanks

  • @nonameprojects1156
    @nonameprojects1156 3 ปีที่แล้ว +7

    Wow, such high Quality!
    i also used a different Ruleset that worked better for me...
    if neighbour Count > 4, updated Cell is alive
    if neighbour Count < 3, updated Cell is dead
    else updated Cell is last Cell
    For me it makes the generation much Smoother, but great Video after all.

    • @paschalasobirionwu1183
      @paschalasobirionwu1183 3 ปีที่แล้ว

      What do u mean by last cell?

    • @nonameprojects1156
      @nonameprojects1156 3 ปีที่แล้ว +1

      @@paschalasobirionwu1183 the Last state of the cell that you are calculating. It means basicly: nothing Changes with the cell.

  • @monkey7218
    @monkey7218 ปีที่แล้ว +1

    Hi! Great video :D I know this is quite an old video by now but, do you know why you get quite "jagged" walls a lot of the time? Any clues on how to fix that?

    • @sdbadik
      @sdbadik 8 หลายเดือนก่อน

      For every wall cell, try to apply this:
      If the wall has 0 neighbors to the left or right, destroy it. If the wall has 0 neighbors to up or down, destroy it as well.

  • @mattzrsimon
    @mattzrsimon 3 ปีที่แล้ว +1

    Dude. Great video! High quality explanations, editing and content. Keep it up.

  • @spartianaleck
    @spartianaleck 3 ปีที่แล้ว +3

    Really good video and really nice explanation of cellular automata! I even realised an error I made in a game of life type of game I created a while ago! Thank you and keep up the good work!

  • @jay_william17
    @jay_william17 ปีที่แล้ว +1

    Nicely done tutorial

  • @felipecruz9567
    @felipecruz9567 ปีที่แล้ว +1

    nice explanation

  • @godfreyofbouillon966
    @godfreyofbouillon966 2 วันที่ผ่านมา

    I dont understand what am I doing wrong but if I apply this rule (wall if 5+ neighboors are walls, floor otherwise) and I start with roughly 50/50 or 60/40 initial distribution, after the very first iteration I'm left with huge floor-only map with very few walls around the edges. I've tried adding additional rule if zero neighbors are walls, become a wall, that I saw in some tutorial, in which case I end up with a map virtually undistinguishable from an initial random generation, maybe walls/floors distributed a bit more evenly but that's it. I really dont get it how you end up with such nice organic looking maps.

  • @atjoo5375
    @atjoo5375 3 ปีที่แล้ว +1

    Omg, your explanations are so good. Even I can understand it.

  • @daka.notatp
    @daka.notatp ปีที่แล้ว +1

    i followed the tutorial... and it works! but my maps are mirrored diagonaly, from upper left to bottom right, anyone knows why?

  • @calumlindsay
    @calumlindsay 3 ปีที่แล้ว +2

    Hey super simple way to get this to run faster would be to use a double buffer instead of creating a new array on each iteration if possible! Not sure if that would be optimised out if this is being compiled but if not might give a decent boost!

    • @dualbladedtvrecords4383
      @dualbladedtvrecords4383 ปีที่แล้ว

      Unless you have huge maps (10k x 10k, or even more) then this boost is going to be negligible. And in those cases, the boost it gives would be far too low than the computation itself. And if you do get to the big numbers, then I think holding the whole map itself in memory is your next problem.

  • @porcelainface7809
    @porcelainface7809 3 ปีที่แล้ว +4

    Great video, I have a question hope it's not too dumb but how would a dynamic size of the caves be implemented, like some are smaller some are bigger

    • @WhiteBoxDev
      @WhiteBoxDev  3 ปีที่แล้ว +5

      The caves will naturally be different sizes, as demonstrated in the demo project. If you want to be able to have more control over the sizes, perhaps you could get a little creative and do something like:
      (1) Run the algorithm with a low wall density, which would result in a few large caves. We will call this gA.
      (2) Run the algorithm with a high wall density, which would result in several small caves. We will call this gB.
      (3) Using a flood fill algorithm, "erase" a few of the large caves from gA. Then, copy and paste those same areas from gB into gA. This would basically be replacing some of the large caves with several small caves, so you would have a mixture of both.
      That's just one method off the top of my head, I'm sure there are plenty other ways of going about it.

  • @umtbmt2395
    @umtbmt2395 11 หลายเดือนก่อน +1

    Thank you for your tutorial, but i don't quite get it what's the difference between step and iteration?

    • @WhiteBoxDev
      @WhiteBoxDev  11 หลายเดือนก่อน

      I use the two terms interchangeably.

  • @민지홍-k8f
    @민지홍-k8f 2 ปีที่แล้ว +1

    Thank you! This video so much helpful to me, that was simple but strong enough!

  • @le_plankton
    @le_plankton 4 หลายเดือนก่อน

    I love this video

  • @FacuDuck
    @FacuDuck 3 ปีที่แล้ว +1

    Hi, nice video, you know how to implement some kind of island gradient later on the generation?

  • @piercenathanlopez6285
    @piercenathanlopez6285 3 ปีที่แล้ว +1

    I recently got in touch with this topic in my elective class, and found it exciting! Although, can I ask you about your thoughts regarding cellular automata in a polar grid? I recently want to implement a CA of that liking. :)

    • @WhiteBoxDev
      @WhiteBoxDev  3 ปีที่แล้ว +1

      I don't have any thoughts about it because I've never thought about it! :)
      It would be an interesting project, though. Implementing CA on a polar grid looks like it would be more difficult than a cartesian grid. I glanced through a paper that talked about generating a model of a spinning hurricane from a top-down perspective. Pretty neat stuff.

    • @piercenathanlopez6285
      @piercenathanlopez6285 3 ปีที่แล้ว

      @@WhiteBoxDev Can I get to know what paper you're talking about? Currently finding papers that have been using polar CAs as well to start with my project! :)

  • @vaibhavpandey6640
    @vaibhavpandey6640 3 ปีที่แล้ว +5

    hey u explained better than sebastin lague!
    hope I can implement something like this for my survival game made with pygame in python

  • @spectrecular9721
    @spectrecular9721 2 ปีที่แล้ว +1

    Any chance to get a tutorial on how to remove unconnected islands of a certain volume, and/or connect islands of a certain volume?

    • @WhiteBoxDev
      @WhiteBoxDev  2 ปีที่แล้ว +1

      Unlikely, however thinking on my feet, I might do the following:
      1. Use flood fill algorithm to scan all areas on the map and keep track of their volumes.
      2. Average the position of each tile in each volume to get the "center tile" of each volume (or somewhat close to it).
      3. If any volume is less than some threshold, then it should be either filled (eliminate it) or connected to the nearest volume.
      Hope this gives you an idea of how to go about doing this. I'm sure there are plenty of alternative ways, but this would be my first approach.

    • @spectrecular9721
      @spectrecular9721 2 ปีที่แล้ว +1

      @@WhiteBoxDev ​Thanks for the advice! I assume after performing a flood fill (but before actually filling in the cells), the volume would simply be how many elements were to be filled? That's a lot simpler than I thought it would be

    • @WhiteBoxDev
      @WhiteBoxDev  2 ปีที่แล้ว

      @@spectrecular9721 Based on your term "volume", yes I figured you meant "group of similar cells". The actual connecting of distinct volumes would be up to your creativity. Glad to help. :)

  • @emmaccode
    @emmaccode ปีที่แล้ว +1

    Nice. Well explained, good code. Thanks. This will be easy to reinterpret and implement :p

  • @darkfrei2
    @darkfrei2 3 ปีที่แล้ว +1

    Thanks, it was very useful!

  • @diligencehumility6971
    @diligencehumility6971 3 ปีที่แล้ว +1

    Really helpful

  • @zephguo145
    @zephguo145 2 ปีที่แล้ว

    I have a question here that in apply_celullar_automoton function:
    If I do not count the type of the current tile itself in.
    Then the neighbor_wall_count should be 0 to 8. And that's 9 status, an odd number.
    If the thershold is N_W_C > 4,
    0,1,2,3, 4 -> Floor
    5,6,7,8 -> Wall
    The chance of a tile becoming FLOOR or WALL seems not ot be 50 : 50.
    Becasue of that, as the iteration goes, I get less Wall and more Floor. Within 10 times, they are most Floor.
    But if we count the tile itself in.
    Then
    0,1,2,3, 4 -> Floor
    5,6,7,8 , 9-> Wall
    the generating chances are the same.
    And I got the correct map by doing so.
    Or did i misunderstand something in the algorithm?
    (I apologize for my poor English level)

    • @WhiteBoxDev
      @WhiteBoxDev  2 ปีที่แล้ว

      Whatever works for you, there is no strictly correct answer. If you count the tile itself and you like the result more for your particular use case, then feel free to do that. :)

  • @Microbex
    @Microbex 3 ปีที่แล้ว +1

    Thanks a lot mate. :)

  • @ankanroy2931
    @ankanroy2931 2 ปีที่แล้ว

    hey in line 7 and 8 what are the ...(3 dots) doing

    • @shenshaw5345
      @shenshaw5345 2 ปีที่แล้ว

      you're checking the previous & next value of both width & height

  • @numero7mojeangering
    @numero7mojeangering 3 ปีที่แล้ว +13

    Need quantum computer to make this algorithm faster

    • @haiweihe8737
      @haiweihe8737 11 หลายเดือนก่อน

      it can be gpu accelerated like neural cellular automata

  • @TheOneWithComments
    @TheOneWithComments 2 ปีที่แล้ว

    Maybe someone can help me with this... after implementing the cellular automaton my grid looks like the end of a game of snake. It looks very square compared to what it is supposed to be. The noise part seems to be working fine but its the cellular automaton part that seems to mess up. The only part of the algorithm i don't fully understand is the "temp_grid" part so I'm guessing that may be part of the problem.

    • @radiance_37k
      @radiance_37k 2 ปีที่แล้ว +1

      pseudo code: (hope this clarifies it)
      repeat for each iteration
      copy grid to temp_grid
      loop through each cell in temp_grid
      count number of walls surrounding cell
      if walls are less than 4, make this cell in grid floor
      else make it a wall
      Basically you are checking the neighbours in temp_grid and changing the original grid accordingly.

  • @FungIsSquish
    @FungIsSquish 3 ปีที่แล้ว +1

    I had no idea dwarf fortress used cellular automata!

  • @noahbrunner3431
    @noahbrunner3431 3 ปีที่แล้ว

    in what coding language is it written

    • @WhiteBoxDev
      @WhiteBoxDev  3 ปีที่แล้ว +1

      The demo in the video is written in Lua.

    • @noahbrunner3431
      @noahbrunner3431 3 ปีที่แล้ว

      how to use it in godot

    • @pbthroggy
      @pbthroggy ปีที่แล้ว

      ​@@noahbrunner3431 The code in the video is psuedocode, you just need to know how to code in GDScript. Take a Computer Science class for the basics of code logic.

    • @pbthroggy
      @pbthroggy ปีที่แล้ว

      ​@@noahbrunner3431 You can also try teaching yourself, I would recommend Crash Course in Python as a starter.

  • @willculpepper9637
    @willculpepper9637 3 ปีที่แล้ว +1

    The nested loops will continue until morale improves

  • @piago1457
    @piago1457 3 ปีที่แล้ว

    what are i and j?

    • @stormfath3r754
      @stormfath3r754 2 ปีที่แล้ว

      I don't know if you still need an answer to this but, for anyone who does it's the initialization value of the for loop. i=1 in the for loop means your loop starts at 1. Any time you call i in the for loop it will return the value the loop is on. So if i=1 then it runs three loops when you call i it will return 3.

  • @jaxonpetersen5942
    @jaxonpetersen5942 ปีที่แล้ว

    The for loop makes no sense