Random Level Generation with a Walker - Godot Tutorial

Поділитися
Вставка
  • Опубліковано 4 лип 2024
  • Thanks for watching my video!
    Github page: github.com/uheartbeast/walker...
    If you are interested in taking a deeper dive into the Godot game engine you can buy my 1-bit Godot Course at this link: www.heartgamedev.com/1-bit-go...
    Check out my Patreon: / uheartbeast
    Follow me on Twitch for GameDev livestreams: / uheartbeast
    Twitter: / uheartbeast
    Facebook: / heartgamedev
    Thank you all so much for your support!
  • Навчання та стиль

КОМЕНТАРІ • 170

  • @uheartbeast
    @uheartbeast  4 роки тому +48

    Here is the githup page for this project (MIT License): github.com/uheartbeast/walker-level-gen
    Hope you all enjoy the video!
    - Ben
    P.S. Audio was a bit off in this video. I' guess I'm having mic issues. I'll see if I can get it fixed for the next video.

  • @henrysabin165
    @henrysabin165 4 роки тому +52

    Benjamin, this video has changed everything for me, for the last four months I have been working on a procedural dungeon crawler in Godot using skills which i gained primarily from your courses online, but I had been struggling to find tutorials on the subject level generation for Godot, this video is exactly what I needed to make a breakthrough in programming my game! Thank you so much, I cannot believe you do all of this out of a passion for the art of games, I admire you more than you can know my friend. I hope one day to release my own game and to embody your passion for the art as well. Again, thank you.

  • @noxalas
    @noxalas 4 роки тому +85

    Another awesome tutorial.
    I'm not sure of the exact term, but I would love to see your take on random level generation, but with hand-made rooms. (Connecting pre-existing rooms together) For example like in Binding of Isaac or Enter the Gungeon.

    • @asuseeepc5801
      @asuseeepc5801 4 роки тому +4

      I'd like to see that too. Dead Cells does that as well.

    • @xaxaWOW
      @xaxaWOW 4 роки тому +7

      The term you are looking for is " Procedural generation " right ? :)

    • @sleepychicken3938
      @sleepychicken3938 4 роки тому +1

      yes to this! would love to see.

    • @noxalas
      @noxalas 4 роки тому +3

      @@xaxaWOW You're right! I just always connect that term a lot more to something like randomization of color and parts for monsters (No Man's Sky, Starbound), but I guess that's kind of the same thing, just on a larger scale. :D

    • @Eliasdbr
      @Eliasdbr 4 роки тому +1

      Spelunky is another good example

  • @azulcrescent715
    @azulcrescent715 4 роки тому +30

    YESSS another Heartbeast Godot tutorial!!! You've helped me so much in learning godot, and i might add, making me enjoy game dev again.

  • @ToastBubbles
    @ToastBubbles 9 місяців тому +8

    I was having a lot of issues replicating this with the 4.1+ Terrain system, after playing around for over an hour, I was finally able to achieve the results at 4:17
    Tips:
    -Only paint/assign the floors to the terrain, just like at 3:30, this will assign the walls a peering bit value of -1 meaning they will be placed only when adjacent cells are empty.
    -When going to paint cells, select Connect mode, it looks like an 8 sided arrow, if you select any of the tiles on the right, or path mode, it just acts buggy

  • @AerikForager
    @AerikForager 4 роки тому +22

    I'm interested in seeing more content about your random walker, specifically how to "coherently" place items like doors, chests, power-ups etc... :)
    Thanks for the interesting content!

  • @GraniteFaun
    @GraniteFaun 8 місяців тому +16

    Gonna leave this here in case someone with Godot 4 wants to use this, since figuring it out wasn't very straightforward at least for me.
    To set a cell you use this, the Atlas Coordinate came from my fully walled tile (using default full tilemap) which is important for the terrain connect function to work properly.
    tileMap.set_cell(ground_layer, tile_pos, ground_layer, Vector2i(0,3) )
    And the other thing you have to do for the autotiling to come to effect is by this code, ground layer is a variable for my base layer ( usually 0 )
    var used_cells = tilemap.get_used_cells(ground_layer)
    tilemap.set_cells_terrain_connect(ground_layer, used_cells, ground_layer, ground_layer)
    Also with bigger tiles you might need to crank that factor for the spawn points up to 64

    • @Lion4de
      @Lion4de 4 місяці тому +1

      This saved my bacon. For clarification, by "fully walled" tile, you mean the one that only has a single spot painted in the middle, which indeed, if you inspect that tile in the tile set should have every one of its bitmask fields set to -1. Thanks for the tip!

    • @tomod45
      @tomod45 4 місяці тому +1

      how did you get tile_pos?

    • @Lion4de
      @Lion4de 3 місяці тому +2

      @@tomod45 tile_pos comes from the loop that you are using to iterate through the tile map.

    • @tomod45
      @tomod45 3 місяці тому +1

      @@Lion4de ty!

    • @alecmcfadyen8616
      @alecmcfadyen8616 3 місяці тому +1

      I’m having a little trouble with the auto tile how. Did you do that?

  • @insignia201
    @insignia201 4 роки тому +15

    As someone who has done a bunch of your tutorials, I am super excited for this one too!

  • @JohnIvess
    @JohnIvess 3 роки тому +5

    Oh my, it's just amazing. You're making complex stuff simple and INDEED understandable. No screw-your-brain recursive algorithms, just simple and plain code that results in a great system at the end of the end. Man, you're great.

  • @BadDesignBryan
    @BadDesignBryan 4 роки тому +3

    You're an absolute legend.
    I was literally looking for a video on random level generation in Godot, today.
    Can't wait for the next part. :)

  • @rungeon83
    @rungeon83 4 роки тому +9

    PLEASE keep on with this, I'd love to see part 2, this is a great way to learn Godot for those who are past newb staging.

  • @bigusdigus2485
    @bigusdigus2485 2 роки тому +1

    This tutorial is one of the most amazing ones that I've seen so far. You pretty much explained in a small sentence what each code does in order for a wide audience to understand. Most of the tutorials don't do that, thinking that it takes too long, but you proved everyone wrong with this video man.
    I just started like 3 days ago learning Godot, and this video pretty much saved most of my questions that I had. Thank you so much.

  • @RetrovoiD
    @RetrovoiD 4 роки тому +8

    I really could have used this a week ago haha The dungeon generation for my game is pretty different, but this definitely would have helped! I was trying to use your old tumblr post explaining generation you did for an old game you were making, but ended up having to kind of make it from scratch. Great video!

  • @SharyqSiddiqi
    @SharyqSiddiqi 4 роки тому +1

    Thanks Ben! I really love your videos, i have been watching your action RPG series, and this series gots me excited to see what you make in the future

  • @pudgystump
    @pudgystump 4 роки тому +1

    Great video! I would love to see you expand upon this random generation algorithm and go over other random generation algorithms as well! Loving your tutorials and Godot!

  • @hitrikrtek6012
    @hitrikrtek6012 4 роки тому +1

    Great stuff again Ben! I was just learning this subject myself atm and your tutorial came in perfectly :D Learned some cool stuff here that was giving me issues. Thanks!

  • @jellovendigar
    @jellovendigar 4 роки тому

    Thrilled to see a new tutorial comin out. Settling in for hopefully a long series

  • @shirotonbo6315
    @shirotonbo6315 2 роки тому +1

    I am so thankful for the wonderful godot community! Especially HeartBeast and BornCG!

  • @ethanstringham9710
    @ethanstringham9710 Рік тому

    Love this video, teaches important aspects of Procedural Generation without going to heavily into theory or to heavy but rather by teaching a simple algorithm.

  • @samx6557
    @samx6557 4 роки тому

    Awesome!
    I requested something like this some time ago.
    I haven't coded for a while but this inspires me to make an Rogue-lite, as I was working on one back in the day.
    Thanks for the video!
    If you make a series out of this, it would be awesome!

  • @itsdirkelsevangilist555
    @itsdirkelsevangilist555 4 роки тому +4

    You are like the brackeys of Godot, thanks for your awesome tutorials you inspired me to make my first game and release it, have an awesome day further ;)

  • @AniketSingh-hr8mi
    @AniketSingh-hr8mi 4 роки тому

    I love this guys tutorials. Please always keep them coming

  • @chef2654
    @chef2654 4 роки тому +9

    Hey Ben, awesome video as always! I noticed that the vibrations from you typing on your keyboard gets picked up by the microphone. I used to put a small thin cushion under my keyboard to avoid this, until I got a shock mount for my mic. Just a tip, you're videos are great either way :)

  • @flamingo2946
    @flamingo2946 4 роки тому +1

    this may be just exactly what I was in need of. Yay!

  • @donforex
    @donforex 4 роки тому

    Great addition to your tuts!!

  • @sleepychicken3938
    @sleepychicken3938 4 роки тому

    thank you for the tutorial!
    Will you consider a segment on putting monsters, biomes or other objects into the level? Most tutorials that talk about level generation leave you with instruction on how to build a randomly generated level, but with no idea on how to populate it.
    Thank you for all your hard work.

  • @alessandrovarisco9162
    @alessandrovarisco9162 4 роки тому +1

    Love your tutorials, I was wandering how to do this in an isometric type of game

  • @JesseBourretGheysen
    @JesseBourretGheysen 3 роки тому +1

    I like this alot, I used the cliffs tile set from your other tutorial

  • @marcosgomes3140
    @marcosgomes3140 3 роки тому

    Very nice, bro!!
    I'm subscribing right now! 👏🏼👏🏼🤘🏼

  • @omjigames
    @omjigames 4 роки тому +3

    Oi Ben!
    Muito legal ver que seu canal cresceu bastante!
    Abraços do Brasil!

  • @phuhoanguc563
    @phuhoanguc563 4 роки тому +1

    It's been a long time since the last Godot Tutorial!

  • @bookiemeow173
    @bookiemeow173 4 роки тому +1

    Thank you so much for this great tutorial!

  • @Cristonic74
    @Cristonic74 11 місяців тому

    you are the best
    i guess i learned most of godot by your tutorials
    keep it up man i apperciate it
    👊👊👊

  • @nyannaing8217
    @nyannaing8217 3 роки тому

    Hi HeartBeast, I would really appreciate it if you continue this series, I am trying to make a 2D sandbox game that uses random world generation but I don't know how to code that. Your videos rally helped me thanks.

  • @kitpierce2988
    @kitpierce2988 3 роки тому

    Procedural generation is my jam! Always trying to learn it better.

  • @MithranTruck
    @MithranTruck Місяць тому +5

    GODOT 4.2.2 USERS:
    After 3 hours of reading comments and figuring out what exactly the code does, I came up with this to get the same results in the video:
    func generate_level():
    var walker = Walker.new(Vector2(19, 11), borders)
    var map = walker.walk(500)
    walker.queue_free()

    for location in map:
    tileMap.erase_cell(0, location)
    await get_tree().create_timer(0.001).timeout # You can delete this, I like to see the level slowly generate.

    var used_tiles = tileMap.get_used_cells(0)
    for tile in used_tiles:
    tileMap.erase_cell(0, tile)
    tileMap.set_cells_terrain_connect(0, used_tiles, 0, 0)
    I learned that ".get_used_cells" specifically gives vector coordinates for anything that wasn't erased in the "for location in map" loop. I also learned that the code doesn't want to paint over existing used cells. So the used cells are stored in the variable "used_tiles" after the location loop. Those used cells are then erased in the "for tile in used_tiles" loop, and then redrawn at the very end in the "set_cells_terrain_connect" command.
    For folks interested in an inverse generator, which means starting with a blank tilemap on your world node:
    func generate_level():
    var walker = Walker.new(Vector2(19, 11), borders)
    var map = walker.walk(500)
    walker.queue_free()

    tileMap.set_cells_terrain_connect(0, map, 0, 0)
    And the variation to see the walker walk:
    func generate_level():
    var walker = Walker.new(Vector2(19, 11), borders)
    var map = walker.walk(500)
    walker.queue_free()

    for location in map:
    var walked = []
    walked.append(location)
    tileMap.set_cells_terrain_connect(0, walked, 0, 0)
    await get_tree().create_timer(0.001).timeout

  • @rekkimaru7
    @rekkimaru7 4 роки тому

    Oh yes! Give me those sweet Godot tutorials!

  • @laknar60
    @laknar60 4 роки тому

    Nice! I am excited for this series, after this series can you possibly do a tutorial for a text based game? Anyways thank you for your amazing tutorials. Hope your channel gets bigger.

  • @gustavols6699
    @gustavols6699 4 роки тому

    hoolly, thank you man, you really helped my a lot, and right when i was needing a model of procedural generation :P

    • @gustavols6699
      @gustavols6699 4 роки тому

      but now i need search how to change just the top sprites without changing all the rest haha

  • @vinipossatto9586
    @vinipossatto9586 4 роки тому

    nice video! I love your work

  • @shtr86
    @shtr86 4 роки тому

    What's better than this topic ?! randomness is awesome ! tyyyy

  • @ROLU.online
    @ROLU.online 2 роки тому

    Thank you so much, it helps a lot! Great tutorial

  • @aleks2603199
    @aleks2603199 4 роки тому

    The only person who's big godot tutorials whe shall care about! ☺️😍🔥

  • @breadslise5659
    @breadslise5659 3 місяці тому +1

    FOR PEOPLE STRUGGLING IN GODOT 4
    i figured out a pretty good way to gibe the same effect in the video without having to have all the tiles on screen to start off with for Godot 4
    create a new array called used tiles then use the for loop shown in video but have it append those positions in used tiles like this:
    for location in map:
    used tiles.append(location)
    then this next part is optional but if you dont want to have to place all the tiles in the editor plus itll give you variable room sizes if you want that
    for x in borders.size.x + 2:
    for y in borders.size.y + 2:
    var point = Vector2(x, y)
    tilemap.set_cell(0, point, 1, Vector2i(3, 3))
    I used the fully walled or enclosed tile for the atlas coords because it has a -1 for all of its sides (dont really understand this part) and the plus twos are for the extra tiles so the tiles created dont go off the borders
    then ypu take the tiles you saved in used tiles, the iterate them in a for loop to erase tiles for the actual level
    for tile in used_tiles:
    tilemap.erase_cell(0, tile)
    then you take the used cells amd use the terrain connect method to connect them all
    var used_cells = tilemap.get_used_cells(0)
    tilemap.set_cells_terrain_connect(0, used_cells, 0, 0)
    this should give you the proper levels

  • @-TheRF
    @-TheRF 4 роки тому

    Idea for a next video on this series: using this method of generation to create a map for your actual level made of pre-made rooms.
    You could have pre-made rooms for corners, horizontal and vertical hallways, and open spaces. Maybe even make couple pre-mades for each "type" of room to increase the variety on the final product.

  • @lufixgaming3652
    @lufixgaming3652 4 роки тому +2

    Seus tutoriais são os melhores, muito obrigado!

  • @saulnores3477
    @saulnores3477 Рік тому

    Great tutorial!!

  • @mythology100
    @mythology100 4 роки тому +6

    (sighs)...
    (gives HeartBeast a thumbs up while wishing he can give two)

  • @benchampagne5266
    @benchampagne5266 4 роки тому +2

    First
    Thanks for making another procedural generation tutorial this is the exact thing I’ve been looking for. Your tutorials are awesome and I probably wouldn’t have started game development without your tutorials.

  • @ronitmann899
    @ronitmann899 4 роки тому

    Finally new series
    Yeah!!!!!!!!

  • @theirtemple8262
    @theirtemple8262 3 роки тому

    I would suggest getting rid of the habit of Array.shuffle() and pop, which is O(n) and instead do array[randi() % array.size()], which is O(1).
    And thanks for all your wonderful tutorials!
    ;-)

  • @BoyoWhoGoesPoyo
    @BoyoWhoGoesPoyo 4 роки тому +2

    CORRECTION: "const" in gdscript does not mean immutable. You can freely modify constant arrays/dictionaries. const-bound variables just can't be re-assigned (and must be initially assigned a literal constant expression). The error in the video was a result of DIRECTIONS becoming empty due to repeated erasure of elements.

  • @steffenderfreak1
    @steffenderfreak1 4 роки тому +1

    Nice tutorial, THX 🎉
    I started to use a specific wording some years ago to prevent reading and typing errors.
    Arrays and lists just get pluralized by adding the suffix "List"
    So the List directions become direction_list
    this is quicker to read, even when you are tired because of a short night, a log day or you are on a game jam ;)
    And it is easier to work with non native englisch speaking people, who sometimes need to search for the right plural form of the word.
    is plural of person, persons? No, it is people. Oh right, my bad. No, it is a person_list 🤷‍♂️
    and you can rename it much easier, when you realize, it's not a bunch of people, it's staff.
    And you prevent this one weird coworker to give variables funny names loke "Oh, its a bunch of files, I call it a folder"
    Oh and you can call your const ALLOWED_DIRECTION_LIST
    This is a longer word, but code completion to the rescue, we don't need to write the whole variable name ;)
    I personally would add the step_history.append() stuff to the step method, because, yoou COULD access the step method from some ware else in your code and would need to add this step (haha) again, to append it to the history

  • @davifox94
    @davifox94 4 роки тому

    Awesome! Nuclear Throne fan here :)

  • @spooki-2451
    @spooki-2451 4 роки тому

    id like to see how to implement stuff like buildings/special rooms in the random terrain . like having a consistent starting room and ending room .

  • @SeniorSupersuade
    @SeniorSupersuade 4 роки тому

    More random level generation, please. Also, consider doing a platform genre random level generation. Thank you!

  • @kshitijbaria5883
    @kshitijbaria5883 4 роки тому +1

    Dude i was just gonna ask for this kind of tutorial Good Job!
    Can you please make a level generation similar to binding of isaac

  • @louietheswan9689
    @louietheswan9689 4 роки тому

    Great video

  • @vatsalajoshi3473
    @vatsalajoshi3473 4 роки тому

    Thank you so much for such tutorials. I have been following your rpg series and started development on my own game but I'm facing problem in dialog box for npcs, signs, etc., please make a video on that.

  • @Syeno
    @Syeno 3 роки тому

    I love your tutorials, youre so intelligent. I have one quick question tho, is it possible to include walls on the south sides of the auto tiled floors? Almost like a mountain maker.

  • @KlausWulfenbach
    @KlausWulfenbach 4 роки тому

    Fantastic!

  • @iherbivore1
    @iherbivore1 3 роки тому

    Your keyboard has a satisfying thumping sound.

  • @silluis88
    @silluis88 4 роки тому +1

    love you bro :) ...you are great

  • @cqtlc
    @cqtlc 4 роки тому

    Hey Benjamin, I had the same glitch issue, I fixed it with the Pixel Snap option on in the redering project setting

  • @grymmjack
    @grymmjack 4 роки тому

    Awesome video. Did you ever make a course on GoDot?

  • @Felix-ce5de
    @Felix-ce5de 4 роки тому +1

    Benjamin, could you do a tutorial on moving clouds that loops? (from right to left)

  • @AmuhAje
    @AmuhAje 4 роки тому +2

    Soo lucky having myself among the first watchers. GREAT CONTENT!!! 👏👏👏

  • @rl_ledge9284
    @rl_ledge9284 4 роки тому +2

    Hey heartbeast,
    Could you make an tutorial about items and a Inventory system. I've looked around how to make this but I am really struggling with it :(

  • @abhilashpawar1875
    @abhilashpawar1875 4 роки тому

    Awsome!

  • @KaidenXIII
    @KaidenXIII 4 роки тому

    Im a fan.

  • @Eliasdbr
    @Eliasdbr 4 роки тому

    I love procedural generation in games. If the dev does it well, the game can get a great level of diversity

  • @BladeNgames
    @BladeNgames 4 роки тому

    Yes yes YESSSSS

  • @VerMishelb
    @VerMishelb 4 роки тому

    How do you look at making series about "space invaders"-like game but more complex, like "chicken invaders" series? The hard part in this could be making enemies move in correct groups.

  • @Bollalillo
    @Bollalillo 2 роки тому

    Would be awesome to see the same result in 3D

  • @dodde216
    @dodde216 3 роки тому

    Pretty sure your nill error was because directions has the same pointer as DIRECTIONS, so if you remove items from directions, then DIRECTIONS will end up empty as well.
    I'm not that familiar with gdscript so I can't be sure, but in most languages cosntants are pure for assigning (using the = sign), functions can still change them

  • @Dolfin-dolfin
    @Dolfin-dolfin 4 роки тому +1

    I am very interested in videos about random level generation.

  • @williamliu7082
    @williamliu7082 3 роки тому

    Wow, that's so creepy.
    I generarated the exact same level as the level generated in the tutorial

  • @anuradhaghatti4779
    @anuradhaghatti4779 3 роки тому

    Hi can you make a tutorial on how to place objects in the level like random enemies and all of that cool stuff

  • @TheMinecraftCookies
    @TheMinecraftCookies 4 роки тому

    Coulda used this a while ago thanks anyways

  • @sosasees
    @sosasees 3 роки тому +5

    What about the Hybrid Approach?
    For my game, I need to spawn Hand-made Scenes a specific distance apart (Spelunky style)
    as suppose to just generating the level automatically (Minecraft style).
    That hybrid approach is like giving the Level Designer a lot of pre-made Rooms in the form of actual TSCN files,
    and ze can also not physically place certain rooms next to other certain rooms,
    and that Level Designer is a computer algorithm.

  • @heman6275
    @heman6275 4 роки тому

    Nice

  • @Daviesdev
    @Daviesdev 3 роки тому

    This question might sound stupid or useless but how did you remove the 3d tab from the editor

  • @boone_e
    @boone_e 4 роки тому

    When are you making a menu tutorial for the action rpg??

  • @Davi_Dash
    @Davi_Dash 4 роки тому +1

    You reading my mind ?

  • @Dwy19
    @Dwy19 4 роки тому

    henlo. can you teach us how we can interact with like the game environment like chests, npcs, coins... like how we can expand on your rpg tutorial? thanks...

  • @7seven398
    @7seven398 4 роки тому

    how would i approach making a spelunky styled level generation?

  • @starwars2078
    @starwars2078 3 роки тому

    When I try to instance a player in the demo you uploaded, I get the message:"Script inherits from native type 'KinematicBody2D', so it can't be instanced in object of type: 'Node2D'" in my player's GDScript. I am not sure as to why these are interfering.

  • @pikcelalien7793
    @pikcelalien7793 4 роки тому

    Can you make proceedial generated infinite terrain tutorial for action rpg game like your action rpg series?

  • @seanocansey2956
    @seanocansey2956 4 роки тому

    If you're doing a Series, you should use the same sprite idea and theme as the ones you had in your previous one in GameMaker.
    (purple robe guy)

  • @karlo7996
    @karlo7996 4 роки тому

    Hello,
    I stumbled on a bug that I can't resolve, basically, the layer names won't change for me, I did the classic change scene, but it won't work, does someone know other ways to fix this issue?

  • @xTPXLx
    @xTPXLx 3 роки тому +1

    Hey,
    The bit about DIRECTIONS and constants is incorrect. You cannot change a reference to it (So you can't do DIRECTIONS = []), but you can change what it contains (pop_front and the like). The null error was because you remove an element from directions every time you call change_direction. If you print the value of DIRECTIONS and direction you get:
    directions [(1, 0), (0, -1), (-1, 0), (0, 1)]
    dir (-1, 0)
    directions [(0, -1), (0, 1)]
    dir (0, -1)
    directions [(0, 1)]
    dir (0, 1)
    directions []
    dir Null
    Calling duplicating the array on every call ensures you don't eventually end up with an empty array.

  • @bvictor
    @bvictor 2 роки тому

    may have a good way to create procedual generations like Dead Cells?

  • @loupax
    @loupax Рік тому

    The levels I saw generated here really want a platformer hero with a grappling hook.

  • @akiradossantos2635
    @akiradossantos2635 3 роки тому

    I can use this to do sometyhing like binding of Isaac?

  • @Evan-gg1tk
    @Evan-gg1tk 4 роки тому

    Are you going to still make game maker tuturials?

  • @deetorz
    @deetorz 2 роки тому

    I'd like to see this map generator with the 3d dungeon video you made.. hmm..

  • @arturorojas1062
    @arturorojas1062 4 роки тому

    F*%ck Yeah! Just what I needed

  • @forg783
    @forg783 3 роки тому

    hey, there's this part when you defined change_direction() in Godot, and the engine won't allow me to generate the code. can you please help?
    thx for the videos by the way!
    edit: same thing happened in the world.gd script.

  • @intangiblematter_misc
    @intangiblematter_misc 4 роки тому

    First question: How did you make Godot have a 2d default?

  • @mindstreamx
    @mindstreamx 4 роки тому

    Cool. I hope this isn't affecting your 'Monster Pack'