Page 1 of 2

Dungeon/Cave generator

Posted: Fri Apr 11, 2014 3:37 pm
by Luke100000
Hi everbody!

I needed a good lua-dungeon-generator for my game. So I tried to make my own one. But it's a simple tunnel-cave generator. :(
screen1.png
screen1.png (5.38 KiB) Viewed 6164 times
screen2.png
screen2.png (6.48 KiB) Viewed 6164 times
Here is the download:
cave generator.lua
version 0.0.0.0.1 :D
(3.44 KiB) Downloaded 265 times
--how you can use it

Code: Select all

require("cave generator")

love.window.setMode(800,800)
--set the size
worldX = 150
worldY = 150
blockSize = 800/worldX
world = cave_generator.createWorld(worldX,worldY) --create an empty world

function love.keypressed(key)
	if key==" " then
		ok, dt = cave_generator.create(world,worldX,worldY,11) --create a cave, 11 is the cave-size, chose a size between 10 and ~20
	end
end

function love.draw()	
	for x=1,worldX do
		for y=1,worldY do
			if world[x][y].type==0 or world[x][y].type==2 then --0==nothing, 1==air, 2==block
				love.graphics.setColor(180,180,180)
				love.graphics.rectangle("fill", (x-1)*blockSize, (y-1)*blockSize, blockSize, blockSize)
				love.graphics.setColor(255,255,255)
			elseif world[x][y].type==1 then
				love.graphics.setColor(80,80,80)
				love.graphics.rectangle("fill", (x-1)*blockSize, (y-1)*blockSize, blockSize, blockSize)
				love.graphics.setColor(255,255,255)
			end
		end
	end
end
Do someone know a good dungeon generator, written in lua?

Re: Dungeon/Cave generator

Posted: Fri Apr 11, 2014 4:50 pm
by Ragzouken
love rot (rot.js port) has some https://github.com/paulofmandown/rotLove

Re: Dungeon/Cave generator

Posted: Sun Apr 13, 2014 5:20 pm
by Rickton
I'm attaching the code for the dungeon generators I've written for Possession 2. Unfortunately, they're pretty tied into the game so you won't be able to use them as-is, but maybe the code is readable enough to give you a starting point.

You can see pictures of maps made by some of the generator types here.

If the code's no help, I based the cave generator off of this article, the "BSP Tree" off of this article, and the maze off of this, I think. The drunk walkers I made myself, so there's no article for that one.

Re: Dungeon/Cave generator

Posted: Mon Apr 14, 2014 9:59 am
by SiENcE

Re: Dungeon/Cave generator

Posted: Mon Apr 14, 2014 8:08 pm
by Jasoco
Rickton wrote:If the code's no help, I based the cave generator off of this article, the "BSP Tree" off of this article, and the maze off of this, I think. The drunk walkers I made myself, so there's no article for that one.
Haha, for the heck of it I decided to start playing around with this using the Cellular Automata method link and after tweaking it a bit I came up with a pretty good algorithm so far...

Image

Currently it generates the random map, then does the 5 step smoothing process. Then I added some post processing where it removes catty-corner empty spaces by replacing one of them with a wall for looks. It also checks for stray islands and removes most of them. And lastly marks certain tiles for potential door placement later.

I don't know what I'm doing with it though. But I have plans for later stuff. I want to use a fill algorithm to find all the individual sections of empty space, find all separate islands and depending on their size, either remove them or do something else with them, discard or integrate isolated parts whenever possible, and maybe later figure out how to make it a maze and add keys in proper places. (Find dead ends that are separated by a single narrow passageway/door and use them as special rooms.) As well as find large empty spaces and mark them as potential event rooms.

I dunno. No idea how I'd use it, but it's fun to experiment.

This is my generation code so far:

Code: Select all

function game:generateMap(w, h)
	local startTime = love.timer.getTime()

	local grid = self:generateGrid(w, h, true)

	for x = 1, #grid-1 do
		for y = 1, #grid[1]-1 do
			grid[x][y] = math.random(0,100) < 32
		end
	end

	self.oldGrids = {}
	self.oldGrids[0] = grid

	self.potentialDoors = {}

	self.curLayer = 0

	for i = 1, 5 do
		local tempGrid = self:copyGrid(grid)
		for x = 1, #grid-1 do
			for y = 1, #grid[1]-1 do
				local total = 0
				for xx = x - 1, x + 1 do
					for yy = y - 1, y + 1 do
						if grid[xx][yy] then
							total = total + 1
						end
					end
				end

				if total > 4 then
					tempGrid[x][y] = true
				end
			end
		end
		grid = tempGrid
		self.oldGrids[i] = grid
	end

	for x = 1, #grid-1 do
		for y = 1, #grid[1]-1 do
			local total = 0
			if grid[x][y] then
				for xx = x - 1, x + 1 do
					for yy = y - 1, y + 1 do
						if not grid[xx][yy] then
							total = total + 1
						end
					end
				end
			end

			if total >= 6 then
				grid[x][y] = false
			end
		end
	end

	for x = 1, #grid-1 do
		for y = 1, #grid[1]-1 do
			if grid[x][y] and not grid[x+1][y] and not grid[x][y+1] and grid[x+1][y+1] then
				local which = math.random(1,2)
				if which == 1 then
					grid[x+1][y] = true
				else
					grid[x][y+1] = true
				end
			end

			if not grid[x][y] and grid[x+1][y] and grid[x][y+1] and not grid[x+1][y+1] then
				local which = math.random(1,2)
				if which == 1 then
					grid[x][y] = true
				else
					grid[x+1][y+1] = true
				end
			end
		end
	end




	for x = 1, #grid-1 do
		for y = 1, #grid[1]-1 do
			if not grid[x][y] and not grid[x-1][y] and not grid[x+1][y] and grid[x][y-1] and grid[x][y+1] then
				self.potentialDoors[#self.potentialDoors+1] = {x = x, y = y, dir = "h"}
			end
			if not grid[x][y] and not grid[x][y-1] and not grid[x][y+1] and grid[x-1][y] and grid[x+1][y] then
				self.potentialDoors[#self.potentialDoors+1] = {x = x, y = y, dir = "v"}
			end
		end
	end

	print("Time Taken:", love.timer.getTime() - startTime)
	return grid
end

function game:generateGrid(w, h, pad)
	local low = 1
	local high = 0
	if pad then low = 0 high = 1 end
	local grid = {}
	for x = low, w + high do
		grid[x] = {}
		for y = low, h + high do
			grid[x][y] = true
		end
	end
	return grid
end

function game:copyGrid(oldGrid)
	local newGrid = {}
	for x, gg in pairs(oldGrid) do
		newGrid[x] = {}
		for y, gg in pairs(oldGrid[x]) do
			newGrid[x][y] = oldGrid[x][y]
		end
	end
	return newGrid
end
In case it's useful to anyone. (You'll need to modify the code to make it work.)

Re: Dungeon/Cave generator

Posted: Mon Apr 14, 2014 8:42 pm
by XCaptain
I made a quick cave gen yesterday using the Cellular Automata technique with a 3-6 rule.
These are surprisingly easy to make. :awesome:
Image

Code: Select all

local cave = function(w,h,seed)
	local dir = {
		{-1,-1}, --nw
		{0,-1}, --n
		{1,-1}, --ne
		{-1,0}, --w
		{1,0}, --e
		{-1,1}, --sw
		{0,1}, --s
		{1,1} --se
	}
	local map = {}
	for x = 1, w do
		map[x] = {}
		for y = 1, h do
			if math.random(0,100) < 45 then
				map[x][y] = "#"
			else
				map[x][y] = "."
			end
		end
	end
	for i = 1, 4 do
		for x = 1, w do
			for y = 1,h do
				neighbors = 0
				for ii = 1,#dir do
					if map[x+dir[ii][1]] then
						if map[x+dir[ii][1]][y+dir[ii][2]] then
							if map[x+dir[ii][1]][y+dir[ii][2]] == "#" then
								neighbors = neighbors + 1
							end
						else
							neighbors = neighbors+1
						end
					else
						neighbors = neighbors+1
					end
				end
				if map[x][y] == "#" then
					if neighbors >= 3 then
						map[x][y] = "#"
					else
						map[x][y] = "."
					end
				elseif map[x][y] == "." then
					if neighbors >= 6 then
						map[x][y] = "#"
					else
						map[x][y] = "."
					end
				end
			end
		end
	end
	for x = 1, w do
		for y = 1, h do
			if x == 1 or x == w or y == 1 or y == h then
				map[x][y] = "#"
			end
		end
	end
	return map
end

Re: Dungeon/Cave generator

Posted: Mon Apr 14, 2014 8:58 pm
by Jasoco
I based mine on the ideas from that link but I had to use a number lower than 45 because it kept generating a lot of walls and very little open space. The number I ended up with was 32 as can be seen. I can tweak it to give it variance but 32 seems to be a sweet spot.

Currently working on finding all the individually isolated sections and marking them as separate rooms, then taking their sizes and discarding or merging them as needed depending on if they're small or far enough away from the main areas. This is kind of fun.

Re: Dungeon/Cave generator

Posted: Tue Apr 15, 2014 12:08 am
by Rickton
Yeah, tweaking and experimenting with random map generators is surprisingly addicting. I always have to go into it with set goals and cut myself off or I'll end up just playing around with it.

Re: Dungeon/Cave generator

Posted: Tue Apr 15, 2014 1:11 am
by Jasoco
I have successfully figured out how to find all the separate sections of the map. Colorized into "rooms".

Image

There's always a single huge area. I will have to try and break it up. Will probably have to force it. And will be figuring out which rooms should be discarded based on their sizes.

If only I knew what to actually do with this technology. (I'm not huge on Roguelikes despite my company name, unless it's Spelunky or Minecraft.)

Re: Dungeon/Cave generator

Posted: Tue Apr 15, 2014 4:14 pm
by kikito
Jasoco wrote:There's always a single huge area. I will have to try and break it up.
Why? You don't like things connected?

But if you really want to have "disconnected islands", you can always use the "white" as "empty space" and the "red" as "walls".
Jasoco wrote:I'm not huge on Roguelikes despite my company name, unless it's Spelunky or Minecraft.
What name is that?