So I’ve been making my own custom A* pathfinding algorithm, which works, but I have no idea how to optimize it properly.
I’ve tried a couple of things, but I don’t really have a good idea on how to use them properly, such as Luau or natives.
Yes, I did use bindable functions so it would return something in return.
I’m honestly kind of lost on where to go with this lol, so I’m just here to ask how and what I should change for better performance.
Here’s the PF_algorithm script i guess.
--!native
local module = {}
local Func = require(script.Parent.Parent.Second.module)--Components
@native
function module:A_star(Start_Pos, End_Pos, PF)
print("- - - - - A* - - - - -")
task.desynchronize()
local Grid = Func:Create_Grid(PF)
local open, closed = {}, {}
local start = Func:Get_closest_node(Start_Pos, Grid)
local goal = Func:Get_closest_node(End_Pos, Grid)
start.Parent = start
start.G_cost = 0
start.H_cost = Func:Dist(start, goal)
start.F_cost = start.G_cost + start.H_cost + Func:Is_Type(start)
table.insert(open, start)
while #open ~= 0 do
local current = open[1]
table.remove(open, table.find(open, current))
table.insert(closed, current)
if current == goal then
print("- - - A* has found the path! - - -")
task.synchronize()
return Func:Reconstruct_path(start, goal, closed)
end
for _, neighbor in ipairs(Func:get_neighbors(current, Grid)) do
if table.find(closed, neighbor) then
continue
end
local in_open = table.find(open, neighbor)
if not in_open then
neighbor.G_cost = Func:Dist(neighbor, start)
neighbor.H_cost = Func:Dist(neighbor, goal)
neighbor.F_cost = neighbor.G_cost + neighbor.H_cost + Func:Is_Type(neighbor)
neighbor.Parent = current
table.insert(open, neighbor)
else
-- UPDATE VERTEX
local cost_to_neighbor = current.G_cost + Func:Dist(current, neighbor)
if neighbor.G_cost > cost_to_neighbor then
neighbor.G_cost = cost_to_neighbor
neighbor.F_cost = neighbor.G_cost + neighbor.H_cost + Func:Is_Type(neighbor)
neighbor.Parent = current
if table.find(open, neighbor) then
table.remove(open, table.find(open, neighbor))
end
table.insert(open, neighbor)
end
end
end
open = Func:Sort_table(open)
end
print("- - - A* has not found the path! - - -")
task.synchronize()
return {}
end
return module
And here are the secondary functions that PF_algorithm uses.
--!native
local module = {}
@native
function module:Place_Waypoint(Position, Action, Label)
local new_waypoint = PathWaypoint.new(Position, Enum.PathWaypointAction[Action], Label)
return new_waypoint
end
@native
function module:get_neighbors(Node, grid)
task.desynchronize()
local Neighbors = {}
for _, N in ipairs(grid) do
local distance = (Node.Part.Position - N.Part.Position).Magnitude
if N ~= Node and distance < Node.Part.Size.X*2 then
table.insert(Neighbors, N)
end
end
return Neighbors
end
@native
function module:is_in_sight(Node1, Node2, PF)
task.desynchronize()
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = {PF}
local RAY = workspace:Raycast(Node1.Part.Position, (Node2.Part.Position-Node1.Part.Position), params)
local Success = pcall(function()
local A = RAY.Instance
end)
if Success then
return false
else
return true
end
end
@native
function module:Dist(Node1, Node2)
return (Node2.Part.Position - Node1.Part.Position).Magnitude
end
@native
function module:Sort_table(Table)
task.desynchronize()
if #Table ~= 0 then
table.sort(Table, function(a, b)
return a.F_cost < b.F_cost
end)
return Table
else
return Table
end
end
@native
function module:Get_closest_node(Pos, grid)
local min = 99999
local temp = {}
for _, node in ipairs(grid) do
local distance = (node.Part.Position - Pos).Magnitude
if distance < min then
min = distance
table.insert(temp, node)
end
end
return temp[#temp]
end
@native
function module:Is_Type(node)
task.desynchronize()
if node.Part:GetAttribute("Type") == "Jump" or node.Part:GetAttribute("Type") == "Custom" then
return 10
else
return 0
end
end
@native
function module:Create_Grid(PF)
local Grid = {}
for _, part in ipairs(PF:GetChildren()) do
table.insert(Grid, {["Part"] = part, ["Parent"] = nil, ["F_cost"] = 0, ["G_cost"] = 0, ["H_cost"] = 0})
end
return Grid
end
@native
function module:Pos_in_sight(Pos1, Pos2)
local RAY = workspace:Raycast(Pos1, (Pos2-Pos1))
local success = pcall(function()
local A = RAY.Instance
end)
if success then
return false
else
return true
end
end
@native
function module:Reconstruct_path(start, goal, closed)
local PATH = {}
local temp = {}
local current = goal
repeat
local waypoint = module:Place_Waypoint(current.Part.Position, current.Part:GetAttribute("Type"), current.Part:GetAttribute("Label"))
table.insert(temp, waypoint)
current = current.Parent
until current == start
local funni = #temp
repeat
table.insert(PATH, temp[funni])
funni -= 1
until #PATH == #temp
return PATH
end
return module