Any way to have a 2D minimap of a 3D dungeon?

Anonymous 5 years ago • updated by Daedalus 5 years ago 17
I thought about using the seed value to regenerate the 3D map in 2D, but I don't think that will allow for the multiple floor layouts.  (This is at runtime, by the way)

Any suggestions?  I'd like to have a 2D version of the map you're on, with 'fog of war' so you can only see areas you've been to, but I'm not sure what's the best way to go about this.
Under review
Do you need to create a minimap for a multi-floor dungeon?
Correct, I would need some kind of minimap for a multi-floor dungeon.

I was thinking something along the lines of doing it floor-by-floor, and fading between the floor you're on when you go up a level (I could even put some kind of trigger at the top and bottom of stairs/ladders so the minimap doesn't even need to track floors, it'll just get an event or something that tells it to crossfade map data).

Any ideas?
You could use PhysicalMap.GetObjectsOfZone(int zone) to get all the GameObjects of a floor. Then you could use those to draw your minimap and fade it when you reach another floor. 
How resource-intensive is that?  I was also reading in your documentation that you guys might be using that to split up areas of a map later, so I'm looking for something that will work now and shouldn't break later.

Is regenerating the map in 2D a bad idea?  If I did it with a 2D generator then I could get doors, etc. and mark them up separately on the minimap (unless GetObjectsOfZone can detect that (or I can search for tags or names from the result)).

I'll look into the PhysicalMap call in the mean time, though.  I'm just curious if there's a better way (for now, and for the long term) way of doing it.

You're right, in the future that method will be used for Zones (another upcoming feature), so if you need a do-and-forget solution, that's not what you want to be using. I don't know how resource-intensive is that, Daedalus is a relatively 'young' package, so maybe we'll take the chance with your question and try to find the best way to implement a minimap. Anyway, keep in mind that every time you generate a map, you have a VirtualMap which holds all the information you need; we then use that to draw the actual graphics (through PhysicalMap). Maybe you can find your own way to handle those information to draw a minimap. We'll give it a shot asap, but please keep us posted since it's a very interesting topic.
I'll take a look through the VirtualMap and see if I can find something useable (or, alternatively, I might do GetObjectsOfZone to prototype, and then try to duplicate the results using VirtualMap).  I'll definitely update this thread if I get something working, but if you guys get something going first that'd be totally awesome too.

Thanks!  Your support is awesome!
Hello, here is an idea on how to do what you are asking.

First, a few notes. The GeneratorBehaviour script creates an array of VirtualMaps, which are then coupled with an Interpreter and then fed to a PhysicalMap to at last create the actual map you see. The combination of VirtualMap and Interpreter is all you need to define, logically, a map. The PhysicalMap exists to basically 'render' the map to screen, instancing the objects.

This means that if you obtain the array of VirtualMaps from the GeneratorBehaviour script,  take each single VirtualMap, couple it with the same Interpreter and then pass both to a new PhysicalMap (2D to make a minimap), you can make the new PhysicalMap mirror the dungeon's PhysicalMap. This new PhysicalMap will also represent just one of the storeys, as each VirtualMap in the array is one storey.

Note also that, instead of separating all VirtualMaps, you could do the same by using a 3D, multi-storey PhysicalMap that uses sprites as prefabs, then move the camera of your minimap so that you can see only one of the floors.

Hope this helps, we have not tested this yet but it should be working. Let us know if you progress! Thanks.

- Michele
I've been working on this over the weekend, and I've got a semi-working approach that probably isn't as nice as what you guys just posted.

Essentially, since the PhysicalMap holds all of the items, I go through and create arrays of the things I want to display on the map (in this case, Walls, Columns, Doors, and Floors). 
Then I use PhysicalMap.GetObjectsOfType(SelectionObjectType) to get that particular type of object. 

Now, we've got all of those types, so we have to sort them by floor.  This will vary depending on how tall your floor is, but once you've worked out the formula it's pretty much ready to go.

Then you just need some way to render it, which was actually more difficult than creating the object arrays.

Anyway, that's just a really long way of saying that it's working now.  Thanks for nudging me into the right direction!
Actually, I'm having some issues trying to sort things by floor accurately.  I'm not sure if it's my formula, or if there's 1 or 2 random ghost objects in some generations.

I'll keep you guys posted.
Good job on the progression! The method you use is good as well. If you have issues with that last part and you give us more information, we may be able to help (i.e.: what objects are not sorted correctly? and what formula are you using?).

- Michele
I think part of my problem can be mapped to the ladders and stairs.  I don't think they count as "Floor" in SelectionObjectType if you're past the first floor.

I see that internally you have a CellType for Ladder and Ladder2 -- any idea what those map to under the SelectionObjectType?

It could be something on my end, but I'm pretty sure that they don't map to SelectionObjectType.Floor.
You are right. You can see the mapping by opening SelectionManager.py, and the ladders are not considered. For now, you can add them to the Floor selectionobjecttype, or add a specific Ladder selectionobjecttype as follows:

selectionDict[SelectionObjectType.Ladder] = new VirtualCell.CellType[2]{

Remember also to add Ladder to the SelectionObjectType.cs enumerator.

We'll add this in the next release, too. Thanks for the heads up! :)

- Michele

Thanks!  I'm glad I wasn't going crazy.  I'll give this a go when I get back and let you guys know how it goes.
Alright, I've tested this for a bit.  

I decided to split the ladder definitions up for added flexibility (especially since Ladders take up 1 floor tile and Stairs take up 2).  No problems there.

The issue that I have now is that I'm not 100% sure how ladders and stairs are sorted when using PhysicalMap.GetObjectsOfZone.  In my initial tests, it seems like they are part of the floor below the current floor, but that doesn't actually seem to work until you're on a floor greater than one.  For reference, here's how I'm trying to decide what floor to check for the ladders/stairs on:

(Floor > 0) ? Floor - 1 : Floor

Using that, if I'm on floor two or greater, they show up just fine, but if I'm on floor 1, they still don't show up in any of the GetObjectOfZone arrays.  If I don't subtract one from the Floor if the Floor is greater than zero, then the ladders/stairs never show up on any floors.

Any ideas? (And thanks for your help thus far!)
Any ideas?  I'm still having issues with this.

Sorry for not answering earlier, but holidays came up.

The stairs between two floors always belong to the floor below. You can check that it works if you use the Generator Debugger (Window drop down menu -> Generator Debugger), select your dungeon and click on any "Select Storey X" button.
Note that the bottom floor is always labeled 0, so if you have 4 floors, they will correspond to zones 0,1,2 and 3.
So, if you do GetObjectsOfZone(0) you should get the ladders between floor 0 and 1.

I hope this can clarify it fot you!

- Michele