Level generation

TesloStep

Member
Intro: working on 2D platformer and start thinking of replayability.

First think to ask - about fully procedurally generated levels. Is it even possible to create pretty and always fully player-reachable levels without thousands strings of code? Some not-too-much-complicated solutions, or guides, or both.

Second - if decide to just compile levels from 3-8 different pregen pieces - what are best way to store that "pregens"? 2d array are kinda ok, but how to write them in form of 2d matrix to proper visualization? Or better are create huge amout of rooms, one for every piece of future level?
 

slayer 64

Member
Storing the pre made level sections in a 2d array or ds_grid might seem like a good idea, I'm not sure it is. Another way would be to write down all the objects in a ds_list. That list could be easily written to a file, read from a file, and more quickly looped through to create all the objects. Each entry in the list could be a string with some text describing what to create and where, or a container instance that stores variables called: name, x, y, object, etc... which would be more flexible in the long run in case you change your game.
 
Intro: working on 2D platformer and start thinking of replayability.

First think to ask - about fully procedurally generated levels. Is it even possible to create pretty and always fully player-reachable levels without thousands strings of code? Some not-too-much-complicated solutions, or guides, or both.

Second - if decide to just compile levels from 3-8 different pregen pieces - what are best way to store that "pregens"? 2d array are kinda ok, but how to write them in form of 2d matrix to proper visualization? Or better are create huge amout of rooms, one for every piece of future level?
Yes, though I think you mean 'lines of code' rather than 'strings of code.' Assuming you are working on a fairly standard platformer, your second question is actually probably the best way to do it. Create a series of tiles in a couple of related ds_grids; each tile should have numerous variants and its contents (such as enemies and collectables) can be made to be pseudo-random. Your estimate of 3-8 is too low, though. Maybe ~10 per type of level, but even that is a bit low, imho. All depends on your game though.

If you want something non-tiled, you will either end up with something so simple as to be a bad solution or so complex you would end up with the thousands of lines of code you want to avoid.
 

TheouAegis

Member
Spelunky's source code is essentially procedureally generated 2D platforming terrain.

I would personally create sets of platforms, if possible. I mean, look at a lot of NES games. Look at modern games even. Developers use prefabs for almost everything for a reason - they're easier to work with. Do you care if the ground level looks immaculate? Probably not. Do you care if floating ledges look immaculate? I know I would. Do you care if a building in the background looks immaculate? You probably damn well better.

Why avoid thousands of lines of code? If those thousands of lines are going to make your game look like a masterpiece, then it's thousands of lines well used.
 

TesloStep

Member
toring the pre made level sections in a 2d array or ds_grid might seem like a good idea
Create a series of tiles in a couple of related ds_grids; each tile should have numerous variants and its contents (such as enemies and collectables) can be made to be pseudo-random.
Yes, looking for a way to save pieces in that manner:
Code:
1111
1001
0201
1111
"1" for walls, "0" for empty tiles, "2" for chest. Its easy to read, its comfortably to edit.
Is it necessary to store them in separate files? Or where else?

Yes, though I think you mean 'lines of code' rather than 'strings of code.'
Sure, sorry for far from perfect English.

Spelunky's source code is essentially procedureally generated 2D platforming terrain.
Yep, maze-like generation from pregens are cool, but store 2D pieces of level in hell damned 1D strings - no way.

Why avoid thousands of lines of code? If those thousands of lines are going to make your game look like a masterpiece, then it's thousands of lines well used.
Well, because there is other important aspects to do. But yes, you're totally right.
 
Yes, looking for a way to save pieces in that manner:
Code:
1111
1001
0201
1111
"1" for walls, "0" for empty tiles, "2" for chest. Its easy to read, its comfortably to edit.
Is it necessary to store them in separate files? Or where else?


Sure, sorry for far from perfect English.


Yep, maze-like generation from pregens are cool, but store 2D pieces of level in hell damned 1D strings - no way.


Well, because there is other important aspects to do. But yes, you're totally right.
No reason to apologize re: English, it's just a matter of wanting to be clear. There are a lot of miscommunications on this board (I have noticed) from not using the correct terms. Not that this was important in this case, but just thought you might like to know.

The best solution I can suggest to you is to write an editor that you can use to make files that store each of your tiles and then load them into your game.

I would use ds_grids to store information. This way, you can just store where you want an object to be rather than create a sort of lookup table (0 = solid, 1 = no, 2 = chest, and so on). If you don't want to create an editor for your pre-fab tiles as I have suggested, you could create them manually with ds_grids in the same way you would in a 3d array.
 

TheouAegis

Member
Writing the data to a file on a 1-to-1 program-to-file method will make reloading the data within the game faster, but if you want file sizes to be small or less legible for the layman, you can save the data into a binary file, storing multiple tiles per byte or using a repeating tile algorithm to keep track of which tiles are repeated and which aren't.

I would personally keep things like treasure chests and NPCs in their own separate data set.

In regards to clustering the tiles, you could write to the file
$9F $F1
And that would be a 4x4 room with an exit at (0,3) not including the chest in the code.

In regards to a repeating algorithm, it could be something like
$85 $01 $82 $00 $01 $00 $02 $00 $85 $01
It takes up more memory, but at least you can account for the chest there.
 

seanm

Member
A couple of things.

1) You can create prefab rooms and stitch them together. This is how Spelunky, and Rogue Legacy work. So long as you can guarantee a solution inside of every prefab, you can guarantee a solution through all of the prefabs.
You can go download the spelunky gamemaker file and look at how he stores and loads the levels inside of strings.

2) You can just give the player some way to fly, give him multiple jumps, etc. that way the player can traverse pretty much anything. Perhaps allow the player to destroy blocks as well, that way nothing will prevent him from reaching the goal.

In terms of creating and storing level prefabs, I would just make my own level editor in gm, and export the prefabs into a format I could then load into my game.
 

TesloStep

Member
The best solution I can suggest to you is to write an editor that you can use to make files that store each of your tiles and then load them into your game.
Writing the data to a file on a 1-to-1 program-to-file method will make reloading the data within the game faster, but if you want file sizes to be small or less legible for the layman, you can save the data into a binary file, storing multiple tiles per byte or using a repeating tile algorithm to keep track of which tiles are repeated and which aren't.
In terms of creating and storing level prefabs, I would just make my own level editor in gm, and export the prefabs into a format I could then load into my game.
Never work with files that way before, will included files work right when choose single .exe file upon "create application"?
Also think to store levels in text files, becuase its allow to easy edit them with just notebook. Is it bad?


1) You can create prefab rooms and stitch them together. This is how Spelunky, and Rogue Legacy work. So long as you can guarantee a solution inside of every prefab, you can guarantee a solution through all of the prefabs.
Yep, that stich-from-prefabs solution best by the now.
You can go download the spelunky gamemaker file and look at how he stores and loads the levels inside of strings.
As mentioned upper, spellunky stores 2d level in one string right in scripts. Its terrible.

2) You can just give the player some way to fly, give him multiple jumps, etc. that way the player can traverse pretty much anything. Perhaps allow the player to destroy blocks as well, that way nothing will prevent him from reaching the goal.
Good adwise, but not for this game.
 

seanm

Member
@TesloStep

I did something like this

Code:
'
111111111
00000000
00000000
00000000
00000000
00000000
111111111
'
that was my format. Then I would parse those strings by looking for the linebreak character, and load the prefabs into my global grid. Then just create the instances from there.


And yes, included files should be stored in the exe.
 

TheouAegis

Member
The file editing I was talking about would be pretty difficult with notepad, since it would literally be just garbage. The user would need a hex editor and understand bitwise manipulation.
 
Top