Brainstorm request: dungeon builder 2 - The next step

Thoughts, Help, Feature Requests, Bug Reports, Developing code for...

Moderators: dorpond, trevor, Azhrei

Forum rules
PLEASE don't post images of your entire desktop, attach entire campaign files when only a single file is needed, or generally act in some other anti-social behavior. :)
User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Brainstorm request: dungeon builder 2 - The next step

Post by wolph42 »

I would like to invite people to join this discussion for the next step for the Random Dungeon Generator. However to think about how version 3 can work, you'll first need to understand how the current version works. Thus...

...first an explanation of how the current version works:
currently I work with some sort of bytewise (or more accurately 4-tit-tytewise) method while calculating the dungeon. Im using the cardinal points (N/E/W/S) for entrances on a 6x6 tile. these points can have 3 values x,0 and 1. So every tile can be indicated with a 4-tit (ternary digit) tyte. Where 0==no exit, 1==exit and x==undecided
And because e.g. 0001 is automatically turned into the number 1 by MT a leader string is required to prevent that: 'f'. Also because facing '0' in MT == facing EAST AND facing works counterclockwise, makes EAST the first tit, North the second, west the third and south the final. THUS a tile with a single exit facing east is denoted as follows:
f1000 : 'f' being the 'do not turn into number trick', followed by exits ENWS where E == 1 and NWS are all 0.
f0101: a north - south hallway
f1111: a crossing
f1110: a t-junction
f0000: no entries
etc.

The 'x' comes in when you want to make a *random* dungeon. First you define a space, e.g. a 'dungeon' of 3x3 tiles, this you fill entirely with 'x' except the borders, which should all be 0 (so the dungeon as a whole has no exits). This results in a 'Template Dungeon':

Code: Select all

f0000 f00x0 f0000
f0x00 fxxxx f00x0
f0000 f0x00 f0000
for reference, let number the tiles
#1 #2 #3
#4 #5 #6
#7 #8 #9
Now for every tile you loop through all 4 tits (this is getting silly, but it really is the abbrev for ternary digit) and ONLY check the 'x''s. IF there's an 'x' then see what its facing.

First tile with an 'x' encountered is tile #2: f00x0. Here (S)outh is undecided, so check the tile south of #2 (== #5 == fxxxx) and check if it has an exit facing north, if it does then set the the south exit of tile #2 to '1' (== exit). In this case #5 tile has an 'undecided' exit facing north and thus it has to be decided, in other words roll a 1d2-1. Or in the case of the dungeon builder roll a 1d100 vs a preset number e.g. 60. this means that there is a 60% chance that there will be an exit. Lets assume the result is true==1==exit. And for tile #4 the result is false. Then at that point the dungeon looks like:

Code: Select all

f0000 f0010 f0000
f0000 fx10x f00x0
f0000 f0x00 f0000
etcetera...until you end up with a fully calculated dungeon, e.g.

Code: Select all

f0000 f0010 f0000
f0000 f1100 f0010
f0000 f0000 f0000
the final step is replacing this 'virtual' chessboard with actual tiles that submit the rules. So e.g. replace a f1111 with a tile with a crossing on it.

This is how the dungeon builder works.

Now the next step.
the above requires two things:
- ALL tiles to be limited to 4 exits (N/E/S/W), while this concerns 6x6 tiles, so corners could play a roll as well. One important thing to note: IF a corner is open, then with the current tileset its ALL open so e.g. the upper left corner or the N-W corner will always open up to both North AND West. So its not *necessary* to make the distinction an exit facing N and an exit facing W for a N-W facing exit. On the other hand, for future compatibility it *might* be prudent to do so...
- Every 'exit' can only have 3 states (true/false/undecided), while there are also tiles with e.g. 'stairs', 'rails' or other specific functions.

The question now is: HOW can this be best implemented ?

Here you can stop reading and start thinking! I'll add my suggestions in the next post, but I'm very curious to other methods

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Brainstorm request: dungeon builder 2 - The next step

Post by wolph42 »

here are some suggestions;

Exit types:

'stairs, rails and other things': this should be relatively easy: just change the 4-tit-tyte into a 4-qit-qyte or pyte, syte etc. In other words, broaden the spectrum:
x = undecided
0 = no exit
1 = hallway
2 = stairs
3 = rails
4 = ...?
And you can add % to these numbers to increase/decrease their existence. Another method is placing 'seeds' in the 'template dungeon'.

Question: given this method, how many of these should be defined (have a look at probono's tileset first). I'm asking cause im not sure how far I should go wit this.

Another method for this is to designate certain tiles for a dungeon, so you can pick e.g. all the 'rails' tiles and build a dungeon from that...

Exit Direction
on first face I'm inclined to say that it should be easy to in crease the 4-tit-tyte into a tyte (8 tits) by just adding the corners. Should you also want to keep 2 directions per corner in mind for future compatibility this becomes a 12-tit-tyte. Im not sure however how easy it is (and especially how slow) to do all the calculations.

Another issue is that ALL tiles need to be categorized... with 4 exits there are already 6 types:
t0 (no exits)
t1 (1 exit)
t12 (2 exits in a corner)
t13 (2 exits straight)
t123 (t-junction)
and
t1234 (crossing).

Adding the 4 corners:

Code: Select all

6	2	5
3	 	1
7	4	8
Then this results in 36 different types... (if you only look at the corners and name them 1,2,3,4 you get the exact same 6 archetypes as with the cardinal points. These 6 corner-types can be applied to all 6 cardinal-types resulting in
36 types
Untitled picture.jpg
Untitled picture.jpg (161.08 KiB) Viewed 1878 times
) thats quite a bit of work to categorize them. This will ALSO mean that you MUST have at least 1 tile of each category or the builder won't work.
Now add the 'exit types' to the mix and you get quite a volatile mix: add one type (e.g. stair) and this number doubles add another and it triples... and that is unmixed (so stairs ONLY), mix the two (so stairs AND hallways) and you get 1296 types. So maybe not the 'best' method.

Another issue I see is that even with the 36 types, the asymmetrical ones are not covered. The simplest example is t1 (this is the tile with only one cardinal exit on spot '1'=='E') combined with t56 (tile with two corner exits on spots 5=='NE' and 6=='NW') into t156. With t156 you can create t458, t378 and t267 by rotating t156 but you canNOT create t365, t467, t178 and t258. To create those you need to flip t156. One simple option would be to do this manually and re-apply the VBL.

I'm curious to your suggestions.

User avatar
Bone White
Great Wyrm
Posts: 1124
Joined: Tue Aug 23, 2011 11:41 am
Location: Cornwall, UK

Re: Brainstorm request: dungeon builder 2 - The next step

Post by Bone White »

I've tried to think any other possible solutions in my head but they all come back to your original idea. The most logical step forward from this is the complete 36 different rooms implementation. I don't think there's any way around it. Adding different variables for stairs, rails, balconies etc. might seem faster now, but I'm sure further down the line trying to set each tile to that rule-set would be just as tedious as the second idea, and less powerful.

EDIT: Iirc I tackled something like this in college, and the method we came up with was to draw the basic map, and then look for scenarios which fit into the tiles you have e.g. if you want some stairs in the dungeon, draw a flat map without stairs as idea 2, then re-scan the map with a % ratio to find compatible matches i.e. a east exit next to a west exit, especially a dead end. Now add the stairs going up/down here (much easier with a dead end) or if it's not a dead end, you must edit the stair tile so that compatible tiles open into it, which means scanning the other 7 tiles around the new stair tile. This saves you a _lot_ of work.

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Brainstorm request: dungeon builder 2 - The next step

Post by wolph42 »

Bone White wrote:I've tried to think any other possible solutions in my head but they all come back to your original idea. The most logical step forward from this is the complete 36 different rooms implementation. I don't think there's any way around it. Adding different variables for stairs, rails, balconies etc. might seem faster now, but I'm sure further down the line trying to set each tile to that rule-set would be just as tedious as the second idea, and less powerful.

EDIT: Iirc I tackled something like this in college, and the method we came up with was to draw the basic map, and then look for scenarios which fit into the tiles you have e.g. if you want some stairs in the dungeon, draw a flat map without stairs as idea 2, then re-scan the map with a % ratio to find compatible matches i.e. a east exit next to a west exit, especially a dead end. Now add the stairs going up/down here (much easier with a dead end) or if it's not a dead end, you must edit the stair tile so that compatible tiles open into it, which means scanning the other 7 tiles around the new stair tile. This saves you a _lot_ of work.
yes, I've already mailed probono, asking him whether he's interested to complete the set.
As for the rescan, thats an interesting idea. It would still require you to 'categorize' the tiles as MT has no way of knowing what tiles is what. But in this rescan scenario you can indeed work with a limited set of tiles and then look in the map for matches and put those tiles there.

Still curious to other ideas. Anyway thanks for the input! Confirming that im on the right path is also helpfull!

actually... there might be another method... using the donjon website, like i do with the dungeon builder version 1. I think it wouldn't be so hard to change the text map that drow added as export into a tyte-based map. And once you have the tyte based map, then the rest is easy. The only potential issue is that the donjon is of course not limited to 6x6 pieces... still...if you set the map to be a multiple of 6 and have all 36 tiles then I guess you should have all the pieces for the puzzle, how weird it might be. hmmm food for thought...

Edit: well it didn't take me long to find a flaw in the latter thought. For that to work you will also need tiles with a wall/not wall for the centre. Effectively doubling the required amount of required tiles to 72...

User avatar
Bone White
Great Wyrm
Posts: 1124
Joined: Tue Aug 23, 2011 11:41 am
Location: Cornwall, UK

Re: Brainstorm request: dungeon builder 2 - The next step

Post by Bone White »

Instead of "scanning" for suitable matches, you can just choose one at random, choose a facing for that special tile e.g. stairway, and then edit the one next to it. If you have the 36 basic tiles beforehand, then you're all set, you'll need a sprinkling of stair tiles, but most stairwells in dungeons have either one entrance or are the centrepiece of a junction. It'd be even better if the staircase was just an overlay for the existing tile-set.

1) Make a map
2) Randomly drop a stairwell tile
3) Scan the tile(s) to the exit(s) from the stairwell tile and alter those back.

Maybe you could store a property on the tile-tokens which lists the exits it has, or keep it as part of the name like you suggested so:

Tile - Blank - Blank
Tile - Tile - Tile

Then drop a stairwell in the top left slot making

Stair- Blank- Blank
Tile - Tile - Tile

You can set it so the Stair looks at the surrounding tiles for entrances, so in this case the only true is south, so your generator macro would drop the stairwell you have with the south entrance.

User avatar
JamzTheMan
Great Wyrm
Posts: 1872
Joined: Mon May 10, 2010 12:59 pm
Location: Chicagoland
Contact:

Re: Brainstorm request: dungeon builder 2 - The next step

Post by JamzTheMan »

As far as categorizing the tiles, I think we could automate it using the getVBL function. I could walk around the edge checking for blank VBL and as such list the grid cells that have exits.

Further more, if you want to find spots for stairs, we could possibly look for suitable holes in the vbl to place them, but probably not the best solution given some tiles have artwork in them and not technically blank.
-Jamz
____________________
Custom MapTool 1.4.x.x Fork: maptool.nerps.net
Custom TokenTool 2.0 Fork: tokentool.nerps.net
More information here: MapTool Nerps! Fork

User avatar
Bone White
Great Wyrm
Posts: 1124
Joined: Tue Aug 23, 2011 11:41 am
Location: Cornwall, UK

Re: Brainstorm request: dungeon builder 2 - The next step

Post by Bone White »

So when you generate the map, keep an array of arrays (x coordinate of y coordinate) which records the information of each tile e.g. 10101010S for a NESW crossroads which can take the stair graphic. Then it's as simple as parsing that information in a for-each loop for suitable tiles.

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Brainstorm request: dungeon builder 2 - The next step

Post by wolph42 »

yes categorizing them automatically by scanning VBl, I did think of that initially, but I first needed to understand the basics, which I think I've got down by now. As BW also concluded, it comes down to pattern recognition with actual bytes, there are 8 bits for every tile type. The only *issue* is the 2-bit shift comparison that needs to be done. E.g. a t1 aka 10000000 or easier to read: 10.00.00.00 is the same as 00.10.00.00, 00.00.10.00 and 00.00.00.10. This accounts for all 36 types (and not sure about the flipped versions which are another 13).

Is there some function in MT to easily to these 2-bit shift comparisons?

edit: corrected typo in bytes on suggestion of BW (next post)

User avatar
Bone White
Great Wyrm
Posts: 1124
Joined: Tue Aug 23, 2011 11:41 am
Location: Cornwall, UK

Re: Brainstorm request: dungeon builder 2 - The next step

Post by Bone White »

No but you could easily make one.

Also for the sake of sanity, why are the last two bit pairs in your post 01 and 01?

If the points went E NE N NW W SW S SE then the cardinal "points would be 10101010 and the diagonal points 01010101.

This makes it much easier to compare rotated rooms. I'd do something like store all the tiles with the first room facing either east or northeast, then do the following (sorta)

[code=php]<!-- Split the tile data into bits -->
for i = 0 to 7
 set(bit + i): substring(tileExits,i,i+1)
<!-- Find how rotated the first exit needs to be to make it northeast -->
for i = 0 to 3
 if(eval(bit + i*2) == 1): roomStartsEast = 1
 if(eval(bit + i*2) == 0): roomStartsNorthEast = 1
 if(roomStartsEast||roomStartsNorthEast == 1): rotationRequired = 90 * i
<!-- Walk the bits to rotate the room coordinates -->
for(rotationRequired / 90)
 bit9 = bit8
 bit8 = bit7
 bit7 = bit6
 bit6 = bit5
 bit5 = bit4
 bit4 = bit3
 bit3 = bit2
 bit2 = bit1
 bit1 = bit0
 bit0 = bit9

rotatedTileExits = bit7*10000000 + bit6*1000000 + bit5*100000 + bit4*10000 + bit3*1000 + bit2*100 + bit1*10 + bit0[/code]


This gives you rotatedTileExits and rotationRequired though bear in mind the rotationRequired might be incorrect because MapTool works the opposite way to everyone else.

A tile with an exit only east would start 1000000 and end up with 10000000 and rotationRequired == 0
A tile with an exit only northeast would start 0100000 and end up with 01000000 and rotationRequired == 0
A tile with an exit south would start 0000010 and end up with 10000000 and rotationRequired == 270

P.S. I realise that this isn't perfect - For example, a room that has an exit northwest and south (00010010) would change to (01001000 & 90) but would be identical to (10000100 & 270). You should be able to add an extra few lines to rotate any tile to have the highest bit value i.e. in bits, 10000100 is higher than 01001000, therefore use 100000100 & 270. I hope this last bit made sense.

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Brainstorm request: dungeon builder 2 - The next step

Post by wolph42 »

Ive corrected my typo. And for peets sake use a . notation as its very hard to read the bytes. im gonna read your post again.

and indeed make the exits sequential is better so i agree on 10101010 for cardinal and 01010101 for corner.

btw, what on earth do you mean with 'first room' ? Lets say you have a t-junction, aka t123 what exactly is 'the first room' is that 1, 2 or 3.
Shifting through the 2 bits and ending up with the highest value is a good idea though! I could write a seperate function that does only that so e.g
getHighest(00.00.00.10) would return 10.00.00.00. This way you'll always compare the same bit notations with eachother!

User avatar
Bone White
Great Wyrm
Posts: 1124
Joined: Tue Aug 23, 2011 11:41 am
Location: Cornwall, UK

Re: Brainstorm request: dungeon builder 2 - The next step

Post by Bone White »

wolph42 wrote:btw, what on earth do you mean with 'first room' ?
First exit.
wolph42 wrote:Lets say you have a t-junction, aka t123 what exactly is 'the first room' is that 1, 2 or 3.
In my code, I started at east, the first two bits, and went along the bit string.
wolph42 wrote:Shifting through the 2 bits and ending up with the highest value is a good idea though! I could write a seperate function that does only that so e.g
getHighest(00.00.00.10) would return 10.00.00.00. This way you'll always compare the same bit notations with eachother!
Just be careful of a NS corridoor 00.10.00.10 not being sorted to a corner corridor 10.10.00.00 but I'm sure you know that.

P.S. A bit is either 0 or 1. 00 is a pair of bits ;)

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Brainstorm request: dungeon builder 2 - The next step

Post by wolph42 »

Bone White wrote:
wolph42 wrote:btw, what on earth do you mean with 'first room' ?
First exit.
yes *that* I gathered, I meant what do you mean with *first*, its a cyclic notation, so there is no *first*
wolph42 wrote:Lets say you have a t-junction, aka t123 what exactly is 'the first room' is that 1, 2 or 3.
In my code, I started at east, the first two bits, and went along the bit string.
still not making sense (to me) here
wolph42 wrote:Shifting through the 2 bits and ending up with the highest value is a good idea though! I could write a seperate function that does only that so e.g
getHighest(00.00.00.10) would return 10.00.00.00. This way you'll always compare the same bit notations with eachother!
Just be careful of a NS corridoor 00.10.00.10 not being sorted to a corner corridor 10.10.00.00 but I'm sure you know that.
erm no you're wrong here, the corners are the even bits and the cardinal the odd bits. Also its cyclis so you can never end up with 10.10.00.00 , but you can (and should) end up with 10.00.10.00 which is an E-W cardinal hall, not with corners !

edit: AH I get it 10.10.00.00 is a hallway around the corner! Yes indeed, you have to be careful with that, but you do that by keeping the cyclic notation in mind. Now I fully get your remark!

P.S. A bit is either 0 or 1. 00 is a pair of bits ;)
im not following you, that is I *know* what a bit is, but I don't understand why you're making this remark, is it something I said?

As for the code, the getHighest can be done in two lines:

Code: Select all

<!-- input should start with string! e.g. "f10101010" -->
<!-- Split the tile data into bits -->
[h,count(4,"<br>"): set("b"+roll.count, substring(arg(0),roll.count*2+1,roll.count*2+3))]
<!-- return highest value -->
[h:macro.return    = strformat("f%08d",
    max(
        number(substring(arg(0),1)),
        number(strformat("%02d%02d%02d%02d",b1,b2,b3,b0)),
        number(strformat("%02d%02d%02d%02d",b2,b3,b0,b1)),
        number(strformat("%02d%02d%02d%02d",b3,b0,b1,b2))
    )
)]

 
the biggest bugger is to keep the '01' or '00' notation from being converted to '1' and '0'. fortunately strformat helps a lot in that!

Anyway, this way you always end up with ONE notation for a tile, no matter which way its facing.... now I have to think about flipping...

User avatar
Bone White
Great Wyrm
Posts: 1124
Joined: Tue Aug 23, 2011 11:41 am
Location: Cornwall, UK

Re: Brainstorm request: dungeon builder 2 - The next step

Post by Bone White »

I just thought it was peculiar why you called pairs of bits a single bit. By "first" I meant starting at the east cardinal point, which (I've been assuming) has been the first digit in the binary number.

assuming the order of bits goes: E NE . N NW . W SW . S SE (hereafter refrerred to as ab.cd.ef.gh)
horizontally flipped is ed.cb.ah.gf
vertically flipped is ah.gf.ed.cb
both flips is ef.gh.ab.cd

A simple pattern translation. :)

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Brainstorm request: dungeon builder 2 - The next step

Post by wolph42 »

I see. you meant in the notation ab.cd.ef.gh that 'a' == East. I thought you were talking about rotating a tile such that its *first* entrance was facing east, which made little sense to me.
Thanks for the flip notations. Can you confirm the following assumptions:
Given:
- rotational offsets are equal (so 'a tile with one exit facing E' == tile with one exit facing N')
- Fh=flipped hor.
- Fv=flipped ver.
then:

for an assymetrical tile:
Fh(T) != T
Fv(T) != T
Fh(T) == Fv(T)
Fhv(T) == T

for a symmetrical tile: Fh=Fv=Fhv=T

correct ?

edit: I was talking about a 2-bit shift as in shift the bits in the byte by two at the time. The actual word 'pair' i've never used until 5 words ago (5 depends a bit on how you count...). (I searched the page, and you're the only one talking about pairs).

User avatar
Bone White
Great Wyrm
Posts: 1124
Joined: Tue Aug 23, 2011 11:41 am
Location: Cornwall, UK

Re: Brainstorm request: dungeon builder 2 - The next step

Post by Bone White »

wolph42 wrote:I see. you meant in the notation ab.cd.ef.gh that 'a' == East. I thought you were talking about rotating a tile such that its *first* entrance was facing east, which made little sense to me.
Thanks for the flip notations. Can you confirm the following assumptions:
Given:
- rotational offsets are equal (so 'a tile with one exit facing E' == tile with one exit facing N')
- Fh=flipped hor.
- Fv=flipped ver.
then:

for an assymetrical tile:
Fh(T) != T
Fv(T) != T
Fh(T) == Fv(T)
Fhv(T) == T

for a symmetrical tile: Fh=Fv=Fhv=T

correct ?
Yes they're all correct, though I'm not sure what you'll be using that logic for.

Post Reply

Return to “MapTool”