Page 1 of 1

BPS Tree Dungeon Generator

Posted: Thu Sep 27, 2018 7:40 am
by StormtrooperCat
BPS.love
(1.8 KiB) Downloaded 210 times
Hello LOVE Community!
I am trying to figure out how to make a BPS tree for a basic dungeon generation system.
I am using 10.2 (I don't like 11's colour system). Any help would be appreciated.

:awesome: Thanks!

P.S. the design/grid on the first one is left over from different types of dungeon generators. (Which were successful)

Re: BPS Tree Dungeon Generator

Posted: Thu Sep 27, 2018 8:51 am
by grump
StormtrooperCat wrote: Thu Sep 27, 2018 7:40 am I am trying to figure out how to make a BPS tree for a basic dungeon generation system.
I think you mean BSP tree?

Are you asking about the algorithm in general, or Lua specifics, or LÖVE specifics?

Here's a basic tutorial how simple BSP dungeon generation works in general. The site provides more resources regarding dungeon generation, also this site.

If you want more help, you should ask more specific questions. Be aware that this is a LÖVE support forum.
I am using 10.2 (I don't like 11's colour system).
Might give this a try then.

Re: BPS Tree Dungeon Generator

Posted: Thu Sep 27, 2018 10:57 am
by StormtrooperCat
I've seen how BSP works in general, I'm just trying to figure out love specifics.
I've been trying to use tables, but it doesn't seem to work and I don't understand enough of other languages to accurately transcribe it to lua.

Re: BPS Tree Dungeon Generator

Posted: Sun Sep 30, 2018 1:40 pm
by 4aiman
Try this (untested, not a pure bsp):

Code: Select all

local width = 200
local height = 200
local min_room_wall_size = 20 -- a min margin of a room, used to prevent too small rooms
local rooms = {[1]={x=0, y=0, w=width, h=height, col = {1,1,1}}}

local function get_vol(room) -- we need this to get the volume of a room
   return room.w*room.h
end

local function volume_sort(table1, table2) -- this one compares two rooms and tells whether room1 is bigger than room2
   return get_vol(table1) > get_vol(table2)
end

function love.keyreleased(key)
   if key=='escape' then -- not that needed on a PC, but Android users will be able to exit app normally
      love.event.quit()
   end
   
   local dir = math.random(0,1) -- choose a direction: 0 for vert, 1 for horz
   table.sort(rooms, volume_sort) -- sort rooms by volume, after this the first room will be the biggest one and the one to divide
   local wall -- a placeholder for a new wall's x *or* y
   if dir == 0 then -- if we split vertically:
      if rooms[1].w > min_room_wall_size*3 then -- it is a  good idea to not divide a room if it is not too big in the first place
         wall = math.random(min_room_wall_size, rooms[1].w - min_room_wall_size) -- pick up a place to place a  wall
         rooms[#rooms+1] = {x = wall+rooms[1].x, y = rooms[1].y, w = rooms[1].w - wall, h = rooms[1].h, col = {math.random(),math.random(),math.random()} } -- create  a new room; col is needed to draw a room with a different color
         rooms[1].w = wall -- we can't change the initial room's width due to the way a new room size is being calculated
      end
   elseif dir == 1 then -- with minor changes, the same for horizontal division
      if rooms[1].h > min_room_wall_size*3 then
         wall = math.random(min_room_wall_size, rooms[1].h - min_room_wall_size)
         rooms[#rooms+1] = {y = wall+rooms[1].y, x = rooms[1].x, h = rooms[1].h - wall, w = rooms[1].w, col = {math.random(),math.random(),math.random()}}
         rooms[1].h = wall
      end
   end

   for k,v in ipairs(rooms) do -- this will yield info on all rooms
       print(k,get_vol(v), v.x, v.y, v.w, v.h)
   end
end



function love.draw()
   love.graphics.print('Rooms: '..#rooms, 40, 10)
   love.graphics.translate(40,40)
   for k,v in ipairs(rooms) do
       love.graphics.setColor(v.col)
       love.graphics.rectangle("line", v.x, v.y, v.w, v.h)
   end
end
The code is not Ideal as it doesn't check if the biggest room can be divided in a selected way (vert or horz). Nevertheless, this should help you to organize your data ;)

Edit: ahh, what the heck, have a *.love file :)
bsp.love
(1.09 KiB) Downloaded 192 times

Edit2: As for 11.x color system, I'm using this:

Code: Select all

local _major, _minor, _revision, _codename = love.getVersion()

if _major>=11 then
   local old = love.graphics.setColor
   function lg.setColor(arg,two,three,four)
      if two then -- there's 3 or 4 vars
         old(arg/255,two/255,three/255, (four or 255)/255)
      else -- arg is a table
         if arg then
            old(arg[1]/255,arg[2]/255,arg[3]/255, (arg[4] or 255)/255)
         else
            local arg = main
            old(arg[1]/255,arg[2]/255,arg[3]/255, (arg[4] or 255)/255)
         end
      end
   end

   local _old = lg.getColor
   function lg.getColor()
      local ret = {_old()}
      return ret[1]*255,ret[2]*255,ret[3]*255,ret[4]*255
   end

   lw.getPixelScale = lw.getDPIScale
end
Not perfect, but suits me ;)

Re: BPS Tree Dungeon Generator

Posted: Sun Sep 30, 2018 1:50 pm
by 4aiman
Sorry for a double post, but attachments are broken. Maybe this will draw moderators' attention...