Procedural map generation help?

I am a brand new user to Corona SDK, and very intrigued by its possibilities. Lua seems like a very robust language and I’m excited about learning more.

One this that I am struggling with is procedural level/map generation. I’ve been reading posts regarding math.random and math.randomseed, along with the billions of stars tutorial. I was tripped up, unfortunately, when attempted to stick the generated items to a grid. I essentially ended up breaking my own code!

Does anyone know of a useful tutorial/explanation/index of procedural level generation for Corona? Specifically generation on a grid? I attempted to do my due diligence and I wasn’t able to find any existing posts relating directly to this. Thanks in advance for any help! [import]uid: 135394 topic_id: 24952 reply_id: 324952[/import]

Hi! I think your questions is very generic, it depends on the specific items and locations you would like the elements to be, but it’s certainly doable. In fact in my game Wonder Witches the obstacles (like geese, bats, poles,…) are created programmatically using random functions, etc.

It’s not clear to me what you mean with grid? Is this something you are using from another project?
–wunderwuzzi [import]uid: 118947 topic_id: 24952 reply_id: 101302[/import]

I was thinking an example of what I’m looking for would for a Roguelike. That is the best way I can describe it and make it a bit more specific. I realize that Roguelike take quite a bit of code and there is no specific roadmap for development.

Maybe it would be best to identify grid coordinates and formulate logic around placement of barriers? As I said I’m relatively new and having trouble realizing the best way forward.

I’m also pursuing additional steps and methods to achieve my designed results, but I was just hoping there was something specific that I was missing when it came to Corona. [import]uid: 135394 topic_id: 24952 reply_id: 101307[/import]

For my roguelike I established a grid for the map of a given size, and made every square an ‘obstacle’ (wall). Then I wrote a variant of Prim’s maze algorithm to carve a “path” through the map. Each room is generated in this way. It makes more interesting maps than, for instance, starting with an empty grid and placing walls randomly.

Setting up the grid itself is pretty straightforward. You use a two-dimensional array and apply useful properties to each cell, e.g.,

[lua]board = {}
for i=1, maxWidth, do
for j=1, maxHeight, do
board[i][j] = { xRef=i, yRef=j, x=screenCoordX, y=screenCoordY, isObstacle = true }
end
end[/lua]

There are lots of approaches, of course, but in a roguelike you know you’re going to be putting *something* (a sprite, probably) in a given cell, so to manage that placement it’s helpful to have a record of where each cell sits in grid and screen/group coordinates.

Shameless plug: http://bit.ly/yXBKQB

edit: Start with this wikipedia article: http://en.wikipedia.org/wiki/Maze_generation_algorithm [import]uid: 44647 topic_id: 24952 reply_id: 101312[/import]

There are a large amount of guides on procedural dungeon generation in the vain of Rogue-likes.

Check a few of these links:

Random Dungeon Generator
Written in Perl, but can give you guidance on the logic applied.

Procedural Content Generation Wiki
Lots of links to various resources and algorithms based around dungeon generation and maze generation.

Basic Level Generation
A simplistic guide and outline for a simple level-generation algorithm.

Generating Caves
A blog post describing another method, this time creating caves in a platformer/2d style with bitty gfx (including basic water effect).

I’ve lost a few other links I had, but that might help guide you around to at least some resources and further search queries to try out :slight_smile:

Once you have the dungeon generator created, it is best then to store it in a 2D array of tiled objects if possible. That way you can apply some basic 2D collision and tiling techniques for textures etc. There are some nice little code snippets for things like pathfinding if you are going to have moving AI (check the Code Exchange).

Good luck! [import]uid: 122384 topic_id: 24952 reply_id: 101313[/import]

Thanks all for the help! Much appreciated. I am new to both Corona and development, and I’m more on the creative side than the technical. This is going to assist immensely.

I have been reading and attempting to absorb all the information in the Pathfinding demo, but I’m having trouble comprehending how one would utilize the map output, scale it to playable dimensions and place a controllable character inside of it. Any tips? [import]uid: 135394 topic_id: 24952 reply_id: 101321[/import]

Sorry folks, I should know better than throwing out random information and expecting some assistance.

I think I figured out the answer to my above question during my travels. Scaling is something that I have a hard time wrapping my head around, so I’m adding that to my to-do list.

I’ve been messing around with the Pathfinding Demo code info, and I like the maze it creates. However, trying to get the code to recognize custom .pngs as assigned to cells of 1’s and 0’s is proving difficult. In other words, I would like to assign images instead of color to the cells generated. I have no doubt I’m missing/breaking something rudimentary, but a helpout would be much appreciated.

Here’s my test code, thanks!

[code]display.setStatusBar(display.HiddenStatusBar)

– constants to fiddle with
local kRoadProbability = 6 – number between 0 and 10 with 10 being a lot of roads and 0 being none
local kLevelRows = 35
local kLevelCols = 25

– our map to be generated –
local level = {}

– table contains display.newRect objects –
local cells = {}
local cellWidth = display.contentWidth / kLevelCols
local cellHeight = display.contentHeight / kLevelRows

– builds our grid –
function buildGrid()
– build map array –
for x = 0, kLevelCols do
level[x] = {}
for y = 0, kLevelRows do
local probability = math.random(0,10)
if probability <= kRoadProbability then
level[x][y] = 1
else
level[x][y] = 0
end
end
end

– build screen now –
for x = 0, kLevelCols do
for y = 0, kLevelRows do
local cell = display.newRect(x*cellWidth, y*cellHeight, cellWidth, cellHeight)
cell.strokeWidth = 1
cell:setStrokeColor(0,0,0)
if level[x][y] == 0 then
cell:setFillColor(0,0,0)
end

if cells[x] == nil then
cells[x] = {}
end

cells[x][y] = cell
end
end
end
buildGrid ()
[/code]

[import]uid: 135394 topic_id: 24952 reply_id: 101682[/import]

ARGH! I know I have to make substitutions to the cell:setFillColor portion but I can’t figure out what to do. If I had any hair I would be pulling it out! Any help for this complete n00b question would be greatly appreciated! [import]uid: 135394 topic_id: 24952 reply_id: 101988[/import]

To insert and display images instead of filling a Rect with color, you need to use the [lua]display.newImage( )[/lua] Factory Function.

So something like :
[lua]for x = 0, kLevelCols do
for y = 0, kLevelRows do
local cell
if level[x][y] == 0 then
cell = display.newImage(“blocked.png”, x*cellWidth, y*cellHeight)
elseif level[x][y] == 1 then
cell = display.newImage(“open.png”, x*cellWidth, y*cellHeight)
end

if cells[x] == nil then
cells[x] = {}
end

cells[x][y] = cell
end
end[/lua]

Ensuring that the images are exactly the same size as the standard cell is (width and height wise) and replacing open.png and blocked.png with the relevant image files which need to exist in the same folder as main.lua. [import]uid: 122384 topic_id: 24952 reply_id: 102049[/import]

You are a gentleperson and a scholar my friend! I IMMENSELY appreciate your assistance. I thought I had tried every combination of those variables with no success. Thank you again very very much! [import]uid: 135394 topic_id: 24952 reply_id: 102184[/import]

@toby2, thank you for the above suggestion. I definitely want to keep track of my cells for the same purpose. I would presume I could use the existing level table in my code to specify a specific cell/tile. However, I’m running into a brick wall as far as that is concerned.

one would presume specifying the coordinates with, for example, level[1][1] would return that cell, but that is not the case. I have attempted to build a level table in the same manner as your example above but to no avail. I keep receiving errors regarding my curly brackets. Do you have any advice for me regarding configuring my level table? Perhaps my grid function is not optimal for what I am attempting to achieve?

local level = {}  
 for i=1, kLevelRows do  
 for j=1, kLevelCols do  
level[i][j] = { i=cellwidth, j=cellHeight, x=screenCoordX, y=screenCoordY }  
  
function buildGrid()  
 -- build map array --  
 for x = 0, kLevelCols do  
 level[x] = {}  
 for y = 0, kLevelRows do  
 local probability = math.random(0,10)  
 if probability \<= kRoadProbability then  
 level[x][y] = 1  
 else  
 level[x][y] = 0  
 end  
 end  
 end  
  
 for x = 0, kLevelCols do  
 for y = 0, kLevelRows do  
 if level[x][y] == 0 then  
 local cell = display.newImage("test.png", x\*cellWidth, y\*cellHeight)  
 elseif level[x][y] == 1 then  
 local cell = display.newImage("test1.png", x\*cellWidth, y\*cellHeight)  
 elseif level[5][5] == 0 then -- obviously does not work  
 local cell = display.newImage {"test2.png", x\*cellWidth, y\*cellHeight }  
 end  
 end  
 end  

would you say that identifying a specific cell should take place as:

local cells = {}  
for i=1, kLevelRows do  
 for j=1, kLevelCols do  
level[i][j] = { i=cellwidth, j=cellHeight, x=screenCoordX, y=screenCoordY }  

Or another variation on that theme? I suppose my real question is, can I have two different tables identifying the same grid cells? [import]uid: 135394 topic_id: 24952 reply_id: 102478[/import]

@toby2 and @angryphase,

Thanks for your help and direction! I was able to solve the issue myself. I’m coming into Lua/Corona coding with very little background, so I appreciate all the assistance. @Toby2, I’m plaing Minotaur Maze and enjoying it thoroughly! Keep up the good work! [import]uid: 135394 topic_id: 24952 reply_id: 102804[/import]

Ahh, those heady days of 2012…

I don’t mean to bother anyone by reviving this thread, but I thought I’d post my Jumper (pathfinding) tutorial here, for anyone searching for PCG stuff with Corona.

http://www.panc.co/tutorials/jumper-logic-modified-for-corona-sdk

Ahh, those heady days of 2012…

I don’t mean to bother anyone by reviving this thread, but I thought I’d post my Jumper (pathfinding) tutorial here, for anyone searching for PCG stuff with Corona.

http://www.panc.co/tutorials/jumper-logic-modified-for-corona-sdk