The example file place from which I had copied the code from works perfectly fine. However, this error is thrown when I try to run the game.
After doing some debugging, I had noticed the code I had copied from which worked perfectly fine in it’s own place but lags a lot when copied and pasted into my own place.
You are expecting too much out of scripting support lol.
Anyways, make sure the goal is reached to ensure the path has a solution in the first place before tracing back the path.
And ensuring the while condition follows the general psuedo code:
While currentPath ~= start do
--find path
One time I printed it out and it just went back and forth between start and goal because I messed up the while condition, I suggest putting a wait() and printing it out to make sure the logic follows.
I highly recommend this resource, the best visual A star tutorial on the web:
And looking at the path construction psuedo code:
The code to reconstruct paths is simple: follow the arrows backwards from the goal to the start. A path is a sequence of edges, but often it’s easier to store the nodes:
current = goal
path = []
while current != start:
path.append(current)
current = came_from[current]
path.append(start) # optional
path.reverse() # optional
Shameless self bump
Studio freezes whenever I try to print out the previous node, adding wait() to the while loop does little to help this either.
Strangely enough, when I published the file I had copied the code from, that place begins to experience a lot of lag as well.
Then I have no clue what cameFrom is supposed to be.
And I seriously don’t understand why you can’t just download the place file.
--local OpenList = workspace:WaitForChild("Path"):GetChildren()
local OpenList = {}
local CloseList = {}
local Grid = {}
-- Rows and columns in a grid
local Rows = 100
local Columns = 100
local Start_Node
local End_Node
local Path = {}
-- Module
local NodeModule = require(script:WaitForChild("NodeModule"))
local function SetUp() -- Createa a grid to use for pathfinding
for x = 1, Rows do
Grid[x] = {}
for y = 1, Columns do
local IsPath = true -- 1,1 and 100,100 are not path nodes as they are the start and end
if x == 1 and y == 1 then -- Starting node
IsPath = false
end
if x == Rows and y == Columns then -- End node
IsPath = false
end
Grid[x][y] = NodeModule.new(x, y, IsPath) -- Construct an object class for the node called Grid[x][y]
end
end
for x = 1, Rows do
for y = 1, Columns do
Grid[x][y]:Show() -- VIsualize the node
Grid[x][y]:AddNeighbours(Grid)
end
if x%5 == 0 then
-- e.g: 10%5 = 0, or 15%5 = 0, so multiples of 5
-- I have no idea why you need this
wait(0.1)
end
end
end
local function RemoveFromTable(OpenList, CurrentNode)
for i = 1, #OpenList do
if OpenList[i] == CurrentNode then
-- if its the current node remove it
table.remove(OpenList, i)
break
end
end
end
local function Is_Valid_Neighbour(List, NeighbourNode)
for i = 1, #List do
if List[i] == NeighbourNode then
return true
end
end
return false
end
local function Start()
Start_Node = Grid[1][1]
End_Node = Grid[Rows][Columns]
table.insert(OpenList, Start_Node)
while #OpenList > 0 do
wait()
if #OpenList > 0 then
local Min = 1
for i = 1, #OpenList do
if OpenList[i].f < OpenList[Min].f then -- Still dont really understand this bit
Min = i
end
end
-- Get the current node
-- let the currentNode equal the node with the least f value
local CurrentNode = OpenList[Min]
-- if currentNode is the goal
if CurrentNode == End_Node then
break
end
RemoveFromTable(OpenList, CurrentNode)
table.insert(CloseList, CurrentNode)
local Neighbours = CurrentNode.neighbours
for i = 1, #Neighbours do
-- Neighbour is one object, Neighbours is the table
local Neighbour = Neighbours[i]
local NewPath = false
if not Is_Valid_Neighbour(CloseList, Neighbours) and not Neighbour.Wall then
local _TempG = CurrentNode.g + 1
if Is_Valid_Neighbour(OpenList, Neighbour) then
if _TempG < Neighbour.g then -- if current node g is less than neighbour node g, but what does that mean?
Neighbour.g = _TempG
NewPath = true
end
else
Neighbour.g = _TempG
NewPath = true
table.insert(OpenList, Neighbour)
end
end
if NewPath then
Neighbour:Heuristic(End_Node)
Neighbour.f = Neighbour.g + Neighbour.h
Neighbour.previous = CurrentNode
end
end
-- visualize the nodes
for i = 1, #CloseList do
CloseList[i]:ShowClosed()
end
for i = 1, #OpenList do
OpenList[i]:ShowOpen()
end
Path = {}
local Temp = CurrentNode
table.insert(Path, Temp) -- insert path node into the table
local Value = 1
while Temp.previous do -- Insert path nodes into path table
-- exhaused allowed exectuion time
Value += 1
table.insert(Path, Temp.previous)
Temp = Temp.previous
end
for i = 1, #Path do
Path[i]:ShowPath()
end
end
end
end
SetUp()
wait(1)
Start()
Because it’s a lot of work, I’m busy with an A star pathfinding commision right now at the moment in fact enough to get paid for.
I suggest looking at this excellent community resource which formats the A star path finding better and modularizing it according to the RedBlob games A star path finding article with the aformentioned data structures PriorityQueue.
If you don’t have a cameFrom dictionary then you might need to add on.