Dungeon/Cave generator

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
Luke100000
Party member
Posts: 232
Joined: Mon Jul 22, 2013 9:17 am
Location: Austria
Contact:

Dungeon/Cave generator

Post 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 6570 times
screen2.png
screen2.png (6.48 KiB) Viewed 6570 times
Here is the download:
cave generator.lua
version 0.0.0.0.1 :D
(3.44 KiB) Downloaded 352 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?
User avatar
Ragzouken
Citizen
Posts: 84
Joined: Fri Aug 10, 2012 7:59 am
Contact:

Re: Dungeon/Cave generator

Post by Ragzouken »

love rot (rot.js port) has some https://github.com/paulofmandown/rotLove
Rickton
Party member
Posts: 128
Joined: Tue Mar 19, 2013 4:59 pm
Contact:

Re: Dungeon/Cave generator

Post 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.
Attachments
layouts.lua
Dungeon generators
(39.71 KiB) Downloaded 203 times
Possession - Escape from the Nether Regions, my roguelike made in LÖVE for the 2013 7-Day Roguelike Challenge
And its sequel, simply called Possession , which is available on itch.io or Steam, and whose engine I've open-sourced!
User avatar
SiENcE
Party member
Posts: 806
Joined: Thu Jul 24, 2008 2:25 pm
Location: Berlin/Germany
Contact:

Re: Dungeon/Cave generator

Post by SiENcE »

User avatar
Jasoco
Inner party member
Posts: 3727
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Dungeon/Cave generator

Post 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.)
User avatar
XCaptain
Prole
Posts: 23
Joined: Tue Apr 09, 2013 11:18 am

Re: Dungeon/Cave generator

Post 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
User avatar
Jasoco
Inner party member
Posts: 3727
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Dungeon/Cave generator

Post 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.
Rickton
Party member
Posts: 128
Joined: Tue Mar 19, 2013 4:59 pm
Contact:

Re: Dungeon/Cave generator

Post 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.
Possession - Escape from the Nether Regions, my roguelike made in LÖVE for the 2013 7-Day Roguelike Challenge
And its sequel, simply called Possession , which is available on itch.io or Steam, and whose engine I've open-sourced!
User avatar
Jasoco
Inner party member
Posts: 3727
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Dungeon/Cave generator

Post 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.)
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Dungeon/Cave generator

Post 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?
When I write def I mean function.
Post Reply

Who is online

Users browsing this forum: No registered users and 6 guests