It will check all of these different positions if they’re further away than the last check.
Meaning if I try to generate while doing that it will add hints to random positions around the map and lead the player in circles, which I don’t want to do. By hints I mean subtle things that point the player in the correct direction, for example an arrow or some footprints on the floor, both would of course be facing towards the end of the maze.
Don’t you have something like a hitbox for a chunk of section you copy and paste? And why don’t you like store all the informations on a table and get the path for exit then place the hints?
No, well you do clone a model from somewhere and place it on workspace.
Just when you place your rooms you probs know if the room/hall has ended or if it continues and you also have defined the exit so you probs know the hall where the exit.
So what I am saying is when. Ever you place these halls why not store some infos in a table like ‘exit’, ‘ended’, ‘connected halls’ and seek for the path from that? Unless this is what u meant by making a huge tree.
I see what you are saying but the exit position is not predetermined. The exit is placed after the halls are generated. I see how you’re saying to link hallways to each other if they are connected, and I could try this, however it might become quite the large table due to the sheer size of the generation I am doing.
You can always shrink the table by eliminating ended hallways that you don’t need or some sort but also you should be able to just edit the table if it has an exit or not once you place the exit.
Keep in mind I am using junctions which have two separate possible links, However those are a lot rarer than the other variations due to there only being one variation, when the other halltypes have multiple variations.
Give me a moment to try this out.
Edit: Intellisense broke. This is going to take a bit longer than expected.
Pick random points where you will place your hints and put them in a table
Load your hints at around each point in the table
I haven’t scripted in a while and I’m not good at pathfinding whatsoever so I won’t be able to just give the code
I’ve been researching procedural generation for the better part of a year. It’s very challenging. But here’s what I’d do:
You have your nodes, so you can calculate how far away a node is from the exit. Then you can just decide, if a node is X nodes away from the exit, place a sign.
Uh, the issue right now is that I can’t get these nodes you speak of since my table layout’s loader for some reason stops working after a junction is hit.
If I manage to figure that out then I should be able to easily do the rest.
If you want I can DM you the functions used for generation
(So you can better understand what’s going on in the backend, I don’t want to send it here as I plan to use this system in a fully fledged game.)
So it’s a data problem. You’re using T-junctions. That means you can store your data as a ‘Binary Search Tree’. From there, it’s not so difficult to find things like distances.
Here’s some of my old code. Use at own risk
--[[
local TreeNode = require(game.ReplicatedStorage["N-ary tree"])
-- Example usage
local root = TreeNode.new("Root")
local child1 = TreeNode.new("Child 1")
local child2 = TreeNode.new("Child 2")
local child3 = TreeNode.new("Child 3")
local child4 = TreeNode.new("Child 4")
local child5 = TreeNode.new("Child 5")
root:addChild(child1)
root:addChild(child2)
child1:addChild(child3)
child3:addChild(child4)
child2:addChild(child5)
-- Perform tree traversal
print("Preorder Traversal:")
root:preorderTraversal()
print("Postorder Traversal:")
root:postorderTraversal()
root:levelOrderTraversal()
]]
-- Define a basic N-ary tree node structure
local TreeNode = {}
TreeNode.__index = TreeNode
function TreeNode.new(value)
local self = setmetatable({}, TreeNode)
self.value = value
self.children = {}
return self
end
function TreeNode:addChild(childNode)
table.insert(self.children, childNode)
end
-- Tree traversal functions with indentation
function TreeNode:preorderTraversal(indent)
indent = indent or 0
print(string.rep(" ", indent) .. self.value) -- Indent based on depth
for _, child in ipairs(self.children) do
child:preorderTraversal(indent + 1)
end
end
function TreeNode:postorderTraversal(indent)
indent = indent or 0
for _, child in ipairs(self.children) do
child:postorderTraversal(indent + 1)
end
print(string.rep(" ", indent) .. self.value) -- Indent based on depth
end
-- Method to count the number of children for a node
function TreeNode:getChildCount()
return #self.children
end
-- Method to check if a node is a leaf (has no children)
function TreeNode:isLeaf()
return #self.children == 0
end
-- Method to check if a node is the root of the tree
function TreeNode:isRoot()
return not self.parent
end
-- Method to get the depth of a node in the tree
function TreeNode:getDepth()
if not self.parent then
return 0
else
return 1 + self.parent:getDepth()
end
end
-- Method to find a node with a specific value in the tree
function TreeNode:findNode(targetValue)
if self.value == targetValue then
return self
else
for _, child in ipairs(self.children) do
local result = child:findNode(targetValue)
if result then
return result
end
end
return nil
end
end
-- Method to remove a child node from the current node
function TreeNode:removeChild(childNode)
for i, child in ipairs(self.children) do
if child == childNode then
table.remove(self.children, i)
childNode.parent = nil -- Clear the parent reference for the removed child
return true -- Child node removed successfully
end
end
return false -- Child node not found
end
-- Level order traversal with level information
function TreeNode:levelOrderTraversal()
local queue = {{self, 0}} -- Initialize the queue with the root node and its level
while #queue > 0 do
local currentEntry = table.remove(queue, 1)
local current = currentEntry[1]
local level = currentEntry[2]
print("Level " .. level .. ": " .. current.value) -- Print level and value
for _, child in ipairs(current.children) do
table.insert(queue, {child, level + 1}) -- Enqueue child nodes with increased level
end
end
end
return TreeNode
You are correct, I do sort of need this done soon, but if you’re going to help it’d be better if we moved to messages instead since messages are more confidential than public topics. (Obviously)
As I keep kinda hinting at throughout this entire thread, I don’t want to leak any of my server stuff.
While this is way above my script knowledge, a couple of things come to mind which may help you do this. Firstly, when you create the maze, I’m assuming you’re using objects from some kind of storage. Perhaps make an alternate model that has arrows or hints that you can randomly place using some kind of random number generator when it’s being formed.
The other idea which I feel is way more complicated is once the maze is done (and before the player has control of their character) use the pathfinding service to create a path (similar to an NPC find its way) from the start to the finish and count the number of path points into an array. Then find the position of that point and the cframe of whatever it’s spawned on and replace that part of the model with a new model containing the hints.
For anyone who needs to do something like this, what I did is I made a table which spawns 2 entry tables and passes them to a function.
In that function, it generates the hallways and puts the hallway assets under this entry table. Once the script reaches a T-Junction, it creates a new entry table under the first entry table and passes that to the same function, effectively creating a loop and DataTree you can iterate through to get the path to the exit.
To avoid it going to dead ends, you can have the iterate function to get the path to the end check if a hallway its iterating through abruptly ends without reaching the exit designation.
You can redo this every time you reach an entry table.
(P.S. Thank you Exercitus for the inspiration for this method with his N-ary module.)