Generating 2d levels

  Рет қаралды 2,646

Nick Brooking

Nick Brooking

17 күн бұрын

I adventure into the world of procedural terrain generation for my 2D roguelite platformer and learn a bunch of gamedev maths.
The game engine is Godot 4.2.
I used Canva for the illustrations.
If you want to create x and y like I do at the end of the video you can do it like this:
First generate a random angle between two bounds
var theta = _rng.randf_range(theta_lower, theta_upper)
Next generate a radius length between two bounds
var r = _rng.randf_range(r_lower, r_upper)
Then convert theta and r back from polar coordinates to cartesian coordinates
var x = r * cos(theta)
var y = r * sin(theta)

Пікірлер: 37
@TheAstroPhoenix
@TheAstroPhoenix 12 күн бұрын
An elegant solution! Polar coordinates in situations like this definitely make life a lot easier. For more complicated scenarios (which don't follow circular spawing points), it might be worth reading into basic monte carlo implementations. These will randomly sample a space of x,y points (which you can restrict the range of using polar coordinates), and when chained, you can make them converge to a region of interest.
@dorusie5
@dorusie5 14 күн бұрын
Very cool. Nice thing with your approach is that you can also clamp the generated values to the allowed range of the angle and distance, so any generated number is valid.
@nick-brooking
@nick-brooking 14 күн бұрын
Yeah that's exactly right!
@HappyGaminz
@HappyGaminz 14 күн бұрын
Amazing video! you are so under-rated!!
@nick-brooking
@nick-brooking 14 күн бұрын
Thanks! Glad you enjoyed it
@bellbobs
@bellbobs 15 күн бұрын
Randommmmmm (but thoughtful)
@thedopesquad7179
@thedopesquad7179 14 күн бұрын
Awesome video omg!!!
@nick-brooking
@nick-brooking 14 күн бұрын
Thanks so much :)
@Descifrando_la_economia
@Descifrando_la_economia 14 күн бұрын
Great video,Great explanation, anyone could understand it
@davidvarga2916
@davidvarga2916 13 күн бұрын
You know you could just code like 20-30-ish next platform positions based on the current one and just pick one at random from that list. Well you could play around with it by adding weights to the randomness so that you get more of the ones you want or don't want at certain times. Like let's say 3 minutes in you start adding more of the thin platforms or what not. If you read my previous comment about adding more objects in. I'll give you an example: You have current platform and in the next platform you won't only have the info about the next platform stored, but also some coins and spikes and what not. This would simplify the work greatly. I think.
@nick-brooking
@nick-brooking 13 күн бұрын
Yeah interesting. I'm thinking I will have some set pieces, ie areas where I have specifically laid out the positions. But I think I've done enough on the platforms for now, I'll come back to them once I've added a few other things to the game
@pavloburyanov5842
@pavloburyanov5842 5 күн бұрын
Very simple: 1. Pick random angle from range: var a = rand(range(deg(20), deg(100))) 2. Pick random distance from range: var dist = rand(40, 80) 3. Grab x coordinate: var x = dist * cos(a) 4. Grab y coordinate: var y = dist * sin(a) 5. Place platform at (x, y)
@nick-brooking
@nick-brooking 5 күн бұрын
Yep, that's exactly right. It turns out so easy this way
@pavloburyanov5842
@pavloburyanov5842 5 күн бұрын
@@nick-brooking it makes a bit difficult when you need to add branching, or when platforms have various widths. The best way, imo, is doing recursion by storing position ant width of last placed platform. ^ can be idea for your next video
@nick-brooking
@nick-brooking 5 күн бұрын
I don't need recursion because I'm just generating one platform at a time. I store a list of all the platforms with the most recent one at the end so adding the randomly generated coords to the position of the last platform is thankfully also trivial.
@nick-brooking
@nick-brooking 5 күн бұрын
But yeah you're right about more platform variability. I haven't got to that yet
@aqua-bery
@aqua-bery 13 күн бұрын
How are you generating the shape for the sprite at the end? To represent the spawning range I mean
@nick-brooking
@nick-brooking 13 күн бұрын
When I create a new platform I create a Polygon2D and add it as a child. Polygon2D has a variable called 'polygon' which is just a list of vertices. So I calculate a bunch of points around the far edge and then calculate more but backwards on the near edge which creates the loop of the shape. Then I can rerender it when it needs updating by calling the same function again. I wrote it super quick and dirty because it's just a debug tool, not intended for the game.
@rikvanduijn7060
@rikvanduijn7060 14 күн бұрын
Very nice loved the explanation. Not very good at math would like to see how you actually implement this.
@nick-brooking
@nick-brooking 14 күн бұрын
Hey glad you liked it! I just added a code example to the description of the video
@davidvarga2916
@davidvarga2916 13 күн бұрын
Just jumping on platforms is boring. Add a few more interesting objects that change the mechanics like a simple moving platform or pick ups or an objects that deals damage like spikes or what not. And you can start scratching your head on how to place them in correlation to one another randomly, but thoughtfully.
@nick-brooking
@nick-brooking 13 күн бұрын
Yeah I have plenty more planned. Just need to keep testing what is actually fun
@WildKiwiUnleashed
@WildKiwiUnleashed 11 күн бұрын
Anyone else notice his eyebrow movement.
@nick-brooking
@nick-brooking 10 күн бұрын
🤨
@WildKiwiUnleashed
@WildKiwiUnleashed 10 күн бұрын
@@nick-brooking No its good, very engaging.
@user-dw5ch6ux3u
@user-dw5ch6ux3u 14 күн бұрын
3:48 realistically speaking the "make a guess and if it is wrong through it out and try again approach" is absolutely fine. did you notice any lag? what did your code look like? you would need to run this code no more than ten-fifteen times (judging by eye) and not every frame and that should take a negligible amount of time. if you really want to squeeze out maximum efficiency from your code to the point where you would care about such small optimizations i suggest gdnative instead of gdscript (i am not trying to judge you btw. if you want to go full optimization on your code be my guest, i am just saying that it's not the best use of your time, especially if you are an indi dev)
@nick-brooking
@nick-brooking 14 күн бұрын
Yeah for sure. And you're right that I'm not overly concerned with performance at this stage. However the guess and check method involves the conversion between polar and Cartesian coords anyway so by the time you've gotten 1 wrong guess, the other method has finished running, forget the other 10 - 50 other guesses you might need. Imo the code is also less intuitive making it messier. Imagine I made the shape really tiny so it took up 1/500th of the x and y range. I would expect to need this to run 500 times, in which case I might want to cut down the range of x and y so it doesn't miss so much and all of that is unnecessary complexity. My point is not that I care about performance too much at this stage, more that it's a decision with no trade offs 1. We like the bias it introduces 2. The code is more straight forward and simple 3. It's more perfomant
@user-dw5ch6ux3u
@user-dw5ch6ux3u 14 күн бұрын
​@@nick-brooking ok fair enough but to clarify a couple of things : the 10-50 other guesses are a matter of milliseconds, your computer is capable of running billions of calculations it truly does not matter at all for code that runs once a second if you made the shape really tiny you would make the x,y range really tiny as well. for example if your shape had values of x [0,0.005] you wouldnt generate random numbers from 0 to 1. unless you had some really weird shape with some really thin areas that require a lot of empty space in between them it truly doesn't matter now to give the devil his due i agree with the benefits of the bias but there are more "brainless" ways to induce said or similar bias that would need less thinking and time. now the reason i am saying all that is that i see a lot of gamedevs that are working on personal projects overthink and over-engineer unimportant parts of their code without taking into account their lack of time/manpower. to write the function in the brainless way i suggested would land you with a couple ms of delay but could be accomplished in 5-10 minutes while to actually sit down and think on how to deform the random generator to fit the area i had in mind and how to change the biases of the generation function to get more platforms slightly closer to the player would take a lot longer which is time an indi-dev could use to add a more important mechanic to their game or to fix bugs. that is not to say you shouldn't do what you want with your project but i am just saying for most indi-devs its not a good idea to focus on such things because most indi-devs leave their projects half way through and over-engineering (i believe) is a big reason why.
@nick-brooking
@nick-brooking 14 күн бұрын
@@user-dw5ch6ux3u I completely agree with you that people waste time on things that don't matter and that in general, people spend way too long on solving problems they shouldn't. I laid it out my video the way that I did because I believe it made the most sense to explain the concepts that way. My goal is to share info about such concepts and describe what solutions I choose then let people do what they want with that info. When I actually wrote the code it took about one minute. Here it is, I don't know how to write the guess and check method and simpler than this but let me know if there's a way. var theta = _rng.randf_range(_theta_1, _theta_2) var r = _rng.randf_range(_r_1, _r_2) var x = r * cos(theta) var y = r * sin(theta)
@user-dw5ch6ux3u
@user-dw5ch6ux3u 14 күн бұрын
@@nick-brooking oh i don't disagree that the code is simple but you also have to factor in the time you spent thinking about it up until it clicked in your head to use polar coordinates and just mess with the radius and angle. now you might have polar coordinates and imaginary numbers fresh in your mind in which case it might come to you automatically or even faster than the "guess randomly and throw away" method but if you haven't recently worked with it it will take some time until that metaphorical light bulb lights up. since you asked the naive method would have been to get a random x,y pair and do these checks: x^2+y^2r_small vector from center to the x,y pair has angle within theta_1 and theta_2 the good with this method is that its easier to come up as a first thought not that its programmatically easier. that is because if you have a specific amount of time to allocate to a project it doesn't matter if that time is spent in thought looking at the ceiling or actually coding.
@nick-brooking
@nick-brooking 13 күн бұрын
Yeah totally, thanks for sharing. Hey are you working on any projects of your own? I'd be keen to hear how you apply this progress-focussed mindset
@tomitomislav8180
@tomitomislav8180 11 күн бұрын
Nice video but why you talk and look so funny, why are you flirting with me 😭😭😭
7 DEVS Make a GAME without COMMUNICATING! (centipede edition)
17:16
Blackthornprod
Рет қаралды 1 МЛН
A truly 2D game isn't what you think it is...
13:23
NivMiz
Рет қаралды 26 М.
Heartwarming moment as priest rescues ceremony with kindness #shorts
00:33
Fabiosa Best Lifehacks
Рет қаралды 37 МЛН
ЧУТЬ НЕ УТОНУЛ #shorts
00:27
Паша Осадчий
Рет қаралды 6 МЛН
Smart Sigma Kid #funny #sigma #comedy
00:25
CRAZY GREAPA
Рет қаралды 38 МЛН
- А что в креме? - Это кАкАооо! #КондитерДети
00:24
Телеканал ПЯТНИЦА
Рет қаралды 7 МЛН
I Tried Turning Games Into Text
18:18
Acerola
Рет қаралды 288 М.
How I Created a Voxel Raycaster in Python...
5:47
Gpopcorn
Рет қаралды 6 М.
This Problem Changes Your Perspective On Game Dev
25:51
Jonas Tyroller
Рет қаралды 368 М.
Optimizing my Game so it Runs on a Potato
19:02
Blargis
Рет қаралды 490 М.
I Solved The World's Hardest Maze (with Code)
9:54
Green Code
Рет қаралды 114 М.
Simulating the Evolution of Rock, Paper, Scissors
15:00
Primer
Рет қаралды 1,1 МЛН
The biggest lie in video games
15:18
AIA
Рет қаралды 1,6 МЛН