Dungeon Architect

@MiDri please test with the new version (2.2.0) which will be updated in the marketplace in a day or two. I sent the request yesterday. As for removing the one of the two closed mesh between modules, I got this request from others as well. I’ll add a flag to remove or retain it

Is there documentation anywhere on the dungeon model and dungeon layout? A diagram showing how the XY grid works and how the rectangular bounds are formed and stored would be very helpful.

The new version (2.2.0) has a new query system that will hide the low level data structures in the model and give you a easier system to work with. are a list of functions in the query object of the grid builder which you can call from a blueprint

[FONT=Courier New]
GetCells
GetCellsOfType
GetCellDimension(int32 CellId, FVector& OutCenter, FVector& OutSize);
GetPathBetweenCells(int32 CellA, int32 CellB, TArray<int32>& OutResult, bool& bOutSuccess);
GetFurthestRooms(int32 &OutRoomA, int32 &OutRoomB);
GetCellAtLocation(const FVector& WorldLocation, int32& OutCellId, bool& bOutValid);
GetCellType(int32 CellId);
GetRandomCell();
GetRandomCellOfType(FCellType CellType);
GetRandomCellFromStream(FRandomStream& RandomStream);
GetRandomCellOfTypeFromStream(FCellType CellType, FRandomStream& RandomStream);
ContainsStairBetween(int32 CellA, int32 CellB);
ContainsDoorBetween(int32 CellA, int32 CellB);
GetStairBetween(int32 CellA, int32 CellB);
GetDoorBetween(int32 CellA, int32 CellB);
GetOpeningPointBetweenAdjacentCells(int32 CellA, int32 CellB);

I’ll add more on request

As I bought DA from your website I already have version 2.2 - those Query API example blueprints look very promissing. I’ll have a look into those to learn from them. Very nice!

And I’m really looking forward for the dungeon event listener sample. It sound like the solution for getting control over prefab rooms.
A mix of the snap builder algorithm (creating the prefab room inside a separatly themed level with door indicators) and the grid builder algorithm to connect to the random level with those prefab parts would be more convenient, I think.
But maybe this workaround with the dungeon event listener is enough …

Thanks for your fast answers and this outstanding plugin - there are so many things hidden inside it and I really dig the samples and videos you provide!

These functions look great. I need some basic info before I can use some of them, though.

Some basic questions I couldn’t find docs on:
What do Grid X and Y refer to in terms of the grid structure? Would (0,0) be the bottom leftmost cell on the grid?
What does Grid Cell Size refer to?
How would I determine how many cells are in the entire grid?

Is there a function which tells which dungeon floor a cell belongs to? I could use that to adjust the positions of the door into a runtime dungeon. Not elegant but it would work.

Hi guys! started using DA on a small indie project with a few friends. Really impressed by it so far and looking forward to doing more projects with it.

As far as custom selectors - we’re really curious about trying to get some more variety on levels…

I haven’t messed with blueprint spawners much but somethings we are looking for would be things like:

Corners - convex or concave corners.
Cells that are not 1x1. So maybe being able to get room center and creating a cell that is a 2x2.
Also something to mix the snapping system with the grid builder. Not sure how feasible it is - but it would be nice to use the grid system and randomly be able to pull in a level like the snap system as a volume. Not sure if that makes sense.

Oh credit where it’s due - project using DA of course, Fantasy Dungeon Kit, Skeleton Character Pack, and Gametextures.com



Sorry no info page yet - just the KS https://.kickstarter.com/projects/triverske/2070972665?token=6f6eb4c9

Hey !

Thanks for your answers !

Problem 1 (instancing ultimate rock pack): as i said in a previous post, don’t waste your time on this (unless you need to understand what happened), i solved it experimentally by modifying the collisions. I didn’t understand anything but the problem is solved for me :slight_smile:

Problem 2 (accessing c++ variable from BP): your assumption is the core of the problem :slight_smile:

Unfortunately i spawn the dungeons at runtime so no, i don’t have them placed in the level, it’s the problem. I need a way to set the DungeonCppCode variable at runtime !

If i had the hand on the code, i would probably declare a public (visibleanywhere, blueprintreadonly) pointer/ref to the ADungeon in the emitters and set it as “this” when adding the emitter to the dungeon.

Your DungeonMarkerEmitter.h code would become something like:


class DUNGEONARCHITECTRUNTIME_API UDungeonMarkerEmitter : public UObject
{
	...]

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Dungeon)
	AActor* ParentDungeon;

	...]
}

And when adding the emitter in my dungeon class (inheriting from ADungeon), my own code would become:


// emitter
FString StrEmptySpaceDAEmitter = "Class'/Game/DLCDaDungeons/EmptySpaceThemes/Rules/MarkerEmitter/BPM_EmptySpaceEmitter.BPM_EmptySpaceEmitter_C'";
UClass* UClassEmitter = LoadObject<UClass>(NULL, *StrEmptySpaceDAEmitter);

// create an object from this BP class
UDungeonMarkerEmitter* DAEmptySpaceEmitter = NewObject<UDungeonMarkerEmitter>(this, UClassEmitter);

// if ok, use it
if (DAEmptySpaceEmitter)
{
	MarkerEmitters.Add(DAEmptySpaceEmitter);
	DAEmptySpaceEmitter->ParentDungeon = this; // YEEHAAA !!!
}


That would be a way to expose the owner dungeon in the emitters BP, then i would just grab it, cast it to my own inheriting class and become king of the world.

But i don’t have the hand on your code^^ and maybe there is a simpler way to do this from BP without modifying the code (couldn’t reach the owner ADungeon from the emitter BP though, hence the post ^^)

Cheers

Thanks!

plugin, really enjoying it so far.

I’m having some problems using this in a multiplayer game. Simply adding it to the level doesn’t seem to work, I suspect because it’s generating the meshes at runtime and replication isn’t being accounted for. I end up getting spammed with error messages when my client player hits a collision on the dungeon. I get “LogNetPackageMap:Warning: UPackageMapClient::InternalLoadObject: Unable to resolve default guid from client: PathName: HierarchicalInstancedStaticMeshComponent_1237, ObjOuter: NULL” spammed across my server log.

Main question: What are we supposed to do to make replication work?

Hello,

Great idea !

It would be nice to share some useful emitters.

So 's one.

I have modified’s AdjacentCellEmitter to allow some walls (and wall separators) in the empty space:

it is in action:

https:///watch?v=dxsae7abmfA

The function i have added is a bit too long to simply share screenshots, so you can download the asset .

In case the link would die some day, i show the whole function screen by screen slowly at the end of the video, so you can remake it by pausing and copying the video.

This emitter seems to work but it’s not optimized nor complete (see video), so if anyone comes up with a more efficient or more complete way to do it, please don’t forget to share :slight_smile:
Cheers !

[QUOTE=;611041]
@demonseedgfx, @MiDri suggestion is a nice workaround. 's another approach that lets you rotate your dungeon at runtime by attaching all the dungeon objects to a root actor:

  1. Generate your dungeon
  2. Grab all your generated dungeon actors and attach them to some root actor (which you will rotate around the orbit)
  3. Rotate the root actor to rotate your dungeon

Amazing Service there. That looks like the perfect setup. Thanks

@uced, You can access your blueprint variables from C++ (link)

Alternatively, you can code up your marker emitter within C++ itself, if you don’t want C++ to blueprint communications.

You would derive from UDungeonMarkerEmitter

MyDungeonEmitter.h



class UMyDungeonEmitter : public UDungeonMarkerEmitter
{
	GENERATED_BODY()
public:
     virtual void EmitMarkers_Implementation(UDungeonBuilder* Builder, UDungeonModel* Model, UDungeonConfig* Config, UDungeonQuery* Query) override;

};


MyDungeonEmitter.cpp



#include "DA413X.h"	// pch
#include "MyDungeonEmitter.h"

void UMyDungeonEmitter::EmitMarkers_Implementation(UDungeonBuilder* Builder, UDungeonModel* Model, UDungeonConfig* Config, UDungeonQuery* Query)
{
   // your logic 
   // Emit markers like this
   
	FTransform transform;
	Builder->EmitMarker("MyMarkerName", transform);
}



This way your code class is statically types and you can reference and set the variables of this class from your code while adding the emitter to the dungeon actor



// create an object from this BP class
UMyDungeonEmitter* DAEmptySpaceEmitter = NewObject<UMyDungeonEmitter>(this);

// if ok, use it
if (DAEmptySpaceEmitter)
{
	MarkerEmitters.Add(DAEmptySpaceEmitter);
	DAEmptySpaceEmitter->MyAttribute = MyValue; // directly reference and set anything you like 
}


The cell locations start from the corner. They are saved in logical grid coordinates and later multiplied with the Grid Size (specified in the config) to get the world coordinates

This is super helpful!!! Thank you!!!

Wow, thanks for sharing - this is really cool and useful. I have been using’s EmptySpace emitters and your emitters would appear to be a very useful addition for many theme types. Looks like you have built some really nice themes too!!

@dave_sullivan You can create a DungeonEventListener blueprint and override the OnPostDungeonBuild event. In that event grab all the actors spawned in the dungeon and set the replicate parameter. I’ll provide a BP example tomorrow.

Looking really nice . Thanks for sharing

I just replicate the seed and call the build dungeon function on the client OnRep seed. That way I don’t have to replicate the individual actors.

As always, a spot on answer, it works super well !

Thanks again for you patience and first class help :slight_smile:

Thanks^^

I corrected a bug i found in my function.

I was emitting many times (as much as the distance covered ! Ouch !!) the same walls. I couldn’t see it while walls were 90° oriented (as they covered each other perfectly) but the horrible truth appeared when setting a random orientation !

So i added an array of vectors to check if anything has already been emitted at a location.

The array is cleared in the event graph and is the correction in the function:

The corrected asset has been reuploaded :slight_smile:

Cheers