Dungeonify - Large templated structure generator with quotas and restrictions

So I made a thing that took me like, 4 8 12 14 hours to make (question mark?) and I’ve tried this time and time again and failed miserably so I sat down, turned off my lights, skipped dinner, breakfast and lunch, and I worked on this.

it would’ve taken a lot less time to make but i was being considerate because making this was pretty hard so i made this for others to enjoy so they dont have to endure the suffering i had to go through

…big mistake.

Features

It do dis ting:

And dis udder ting (loops):

it do dis (1530 blocks and ZERO collision), does it very fast too:

it also go hie:


Notable Features

  • Literally cannot collide with anything.
  • Super fast. Super super fast. Could be even faster via """"""multithreading"""""" but I couldn't figure it out.
    • 13 seconds with one Heartbeat yielding function per iteration. for 1,302 pieces.
    • 0.5 seconds with no yielding function for 203 pieces (very dangerous, please keep the yielding function)
  • Supports a piece of any size as long as the bounding box size is accurate.
  • Based off of Attachments (in all honesty, they're just parts), The module will look for objects named "Snap" with a number following it.
  • Automatically walls off unbranched places.
  • Follows quotas. If there needs to be a specific quota of pieces met, it will keep refreshing the dungeon until the quota is met.
  • Modular, use require in order to use.
  • Supplies it's own errors and assertions. If you manage to fish out a natural error, then colour me surprised.
  • Supports restrictions. Be sure to impose loose restrictions otherwise it will take more time to make it just right.
  • Supports custom hitboxes. (i think, probably just a side-effect of my bad coding hehe)
  • Fuzzy. Custom properties are not case sensitive and is not required to be plural.
  • Supports heights.

Warnings

  • Attachments are strictly named. Weird names like Snap0.4 or SnapA will not work.

  • If you wish to support walling off for a piece, have the name being correspondant to the joint with the word wall following, i.e. “Snap4” and “Snap4Wall”, “Snap82” and “Snap82Wall.”

  • Attempts to pass an impossible quota/restriction pair will error.

  • Attempts to pass an impossible restriction or quota via MaxPieces or MinPieces will error.

  • Attempts to pass an impossible quota via MaxPieces or MinPieces will also error.

  • Addends are not mandatory, however they are added to the Part-Statistic measurings. If you want an addend to be necessary, put in the Quota.

  • Long loops are bound to be a thing. The stricter the quota and restriction, the longer it will take to get a satisfactory map.

  • Every piece has to be modeled and it must have a primary part that signifies where it’s going to be connected from.


Acknowledgements / Credits

  • @InfinityDesign for helping me come up with grid-based solution (which in the end, i didn’t use)

  • @megukoo for support.

  • @eLunate for help and being mean.

  • @EgoMoose for his RotatedRegion3 module.


If you find any bugs or anything that could be potentially harmful to a game, please let me know. I’ll get on it fast since I have an abundance of free time.

Take the model here!

Place file showing the module:

prodgen.rbxl (36.7 KB)

As per @RuizuKun_Dev’s request, here is the source on github for all you mobile users.

154 Likes

Can you provide a usage example? I.e. a place file with a simple setup.

7 Likes

Wow, this is very impressive, and the module pack provided is actually pretty clean for such a complicated creation.

Love seeing EgoMoose’s work used in projects. That man deserves Top Contributor.

8 Likes

Very nice work! I am slowly getting into it myself. Best of luck to you.

2 Likes

Am i the only one here struggling to use this?
Other than my trouble Great job i think it looks very cool.

2 Likes

(and @LawViking)

Added a place file to show off the module. Sorry 'bout that. :stuck_out_tongue:

6 Likes

[Ack,Annoying 30 character limit,]

Thank you very much!

2 Likes

Hey, this is really good, but I wanted to be able to call :Generate() from the server, so that all players could see the dungeon, and not only LocalPlayer, but whenever I try to do it through the server, nothing happens, I may be blind or not understand where this is restricted to Local, can you help me?

2 Likes

Updated. Code used :IsLoaded() and .Loaded:Wait(), completely removing the opportunity to be used in the server. I also used RenderStepped instead of Heartbeat. All of those problems should be addressed and fixed. Sorry about that.

4 Likes

Yah, no problem, didn’t know about :IsLoaded() and .Loaded:wait()(I’m not very good at programming yet), I really liked what you did, it’s like a procedural Generation, without many rules, I created some, it’s getting really cool. Thank you very much :smiley:

2 Likes

some changes in it and i got something like this:

Dungeon

Everytime i play :smiley:

3 Likes

That’s so cool! Great job, I love it!

As for @RuizuKun_Dev, sure, I guess. Edited the post with the source on Github. Never made a repository before, so I probably screwed it up.

3 Likes

You did mess it up quite a bit, but don’t worry about it, I’ll help you create the right format (using Rojo) for you when I wake up tomorrow in DMs.

Thank you so much for sharing this and satisfying my request :grin:

This is a really cool module and I usually like to read code on my iPad which explains my request on almost every single interesting Resource posted.

3 Likes

I have 2 Questions:

  • Will the module do it’s best to not crash into other parts besides it’self (ex: Terrain, Buildings)

  • Can you set a Minimum/Maximum for a specific piece?

2 Likes

No. It only maintains mindfulness for it’s own generated parts. For every section I place, it would have to check for every. single. object. in the workspace. Furthermore, Dungeonify places down segments (even if they collide) first, converts all cached parts (specifically, hitboxes. Dungeonify has to use models so it can use GetBoundingBox) to region3. Now, imagine that for every single part. Even for models.

I wasn’t supposed to go on a tangent. Anywho,

For large-scale maps, that would be not-so-good. Instead, I would recommend using a test place to create your dungeons and then porting it into your game and positioning it accordingly.

Yes, you can. You can impose both a quota (minimum) and a restriction (maximum) for the same piece, however, as I said on Warning 7:

So, be mindful of what you want to generate, the more precision you want, the longer it will take. Generally though, it shouldn’t have a hard time generating.

1 Like

This could be done much easier, adding a few lines when creating a new piece, and adding one:

For i,v in pairs (Pierce:GetChildren()) do
local touching = v:GetTouchingParts()
   if touching then
   --Sets as error, delete that piece and recalculate to continue to another location
   end
end

or something like that xD


:frowning:

1 Like

Create a hitbox part in the size of the piece, just like you already do in the script, which is cancollide = true, after checking if it collides with something, changes it to cancollide = false, if it is colliding, recalculates the path, or simply closes with a wall and continues elsewhere, if the collide_table = nil then proceed to the next piece.

all these steps you have already programmed, just check if there is something colliding and redirect to the function that will solve :smiley: Voilà

Then we’re leading back to our first issue, I’d have to check for every. single. part in the workspace.


See, I was going to say that. But then I realized: I use Region3. I use a whitelist. I could simply just… turn off that whitelist through a setting. I’ll go add that now. :stuck_out_tongue:

1 Like

xD it will work lol
(30 charss)