InsanityPathfinder | The Customizable but Simple Pathfinder


InsanityPathfinder is a highly customizable but simple pathfinding class designed for advanced NPCs!

Get It On Roblox


What does it exactly do?

The class provides you with customizable movesets and path generation, and some special events to use for building NPCs designed for fighting or parkour.

How do we use it?

Plop the module into ReplicatedStorage, then…

Creating and using pathAgent as is:

local Insanity = require(Path.To.InsanityPathfinder)
local pathAgent = Insanity.new(Character)

pathAgent:CreatePath(TargetPosition)

pathAgent.Success:Connect(function()
    pathAgent:start()
end)

Running custom path generation with a custom moveset:

local Insanity = require(Path.To.InsanityPathfinder)

local Moveset = {["RUN"]=function(Humanoid, End: Vector3) 
    if Success then
        return true
    else   
        return false
    end
end)}
local PathGenerator = function(Path, Character, Target, Moveset, ErrorSignal)
    return {Position, Move}
end
local PostChecker = function(Character, Waypoint)
    return true
end

local pathAgent = Insanity.new(Character, Moveset, PathGenerator)

pathAgent:CreatePath(TargetPosition)
pathAgent.Success:Connect(function()
    pathAgent:start()
end)
Customizing the Stuff!

Customizing Movesets, PathGenerator, and the PostChecker

Movesets

The moveset is a table of character movement functions in which two functions are set in by default. Here is the two as an example:

moveset = {
		["JUMP"] = function(Humanoid: Humanoid, End: Vector3)
			local Success = nil
			Humanoid:MoveTo(End)
			Humanoid.Jump = true
			local Success = Humanoid.MoveToFinished:Wait()
			if Success then
				return true
			else
				return false
			end
		end,
		["WALK"] = function(Humanoid: Humanoid, End: Vector3)
			local Success = nil
			Humanoid:MoveTo(End)
			local Success = Humanoid.MoveToFinished:Wait()
			if Success then
				return true
			else
				return false
			end
		end,
		--[[ MOVES
			it should always return a true or false, depending if the agent accomplished the move
		]]
	},

PathGenerator

The PathGenerator is a function that handles all path generation. Here is an example from the defaults. Please note that the function’s arguments will be supplied by the pathAgent.

DefaultGenerator = function(Path, Character, Target, Moveset, ErrorSig)
		local Gen_Success = pcall(function()
            -- _TypeCheck comes from an internal function
            -- in the utilities module, please replace when 
            -- making your own generator
			Path:ComputeAsync(_TypeCheck(Character), Target)
		end)
		if not Gen_Success then
			ErrorSig:Fire()
			return
		end
		
		local TempWaypoints = Path:GetWaypoints()
		local ReturnNewWaypoint = {}
		for Pos, Waypoint in ipairs(TempWaypoints) do
			local NextWaypoint = TempWaypoints[Pos + 1] :: PathWaypoint
			if not NextWaypoint then
				continue
			end
			
			if (NextWaypoint.Position.Y - Waypoint.Position.Y) > 3 then
				NextWaypoint = {Position=NextWaypoint.Position, Move=Moveset["JUMP"]}
			else
				NextWaypoint = {Position=NextWaypoint.Position, Move=Moveset["WALK"]}
			end
			
			table.insert(ReturnNewWaypoint, NextWaypoint)
		end
		
		return ReturnNewWaypoint
	end
    --[[ CHECKERS
		1. the checker should always return a new table of waypoints.
		2. the new table of waypoints shoud have their indexes added by 1
		   (it should ignore the first waypoint since it's just the character's position)
		3. the new table of waypoints should contain tables in style of:
			{Position: Vector3, Moveset: function}
	]]

PostChecker

The PostChecker is a function that acts like a sanity check that returns true if the character had actually accomplished the target of the move. Here is the default one as an example:

DefaultPostChecker = function(Character, Waypoint)
		if (_TypeCheck(Character) - Waypoint.Position).Magnitude > 5 then
			return false
		end
		return true
	end
	--[[ POST-CHECKERS
		the post-checker acts as a sanity check after the move has been called and returned
		the checker should return a true or false, depending if the its confirmed that the attempt suceeded.
	]]

API Documentation


InsanityPathfinding.new(Character: Instance?, CustomMoveset: {string}?, CustomGenerator: string?, CustomPostChecker: string?, agentParameters: {string}?): pathAgent

The function used to make pathAgents.

Argument Info
Character The physical model of the agent.
*CustomMoveset A table of functions, able to be accessed by keys.
*CustomGenerator The path-generating function.
*CustomPostChecker The sanity check function.
*agentParameters The agentParameters

Not Required *

pathAgent

The object that handles all the custom pathfinding stuff, all the event signals… and other stuff…

Setting Purpose
Character The physical model of the agent.
Generator The path-generating function.
PostChecker The sanity check function.
Moveset A table of functions, able to be accessed by keys.
Event Purpose
Error Fires when the path generation fails.
Success Fires when the path generation succeeds.
Blocked Fires when the path gets blocked.
Offcourse Fires when the sanity check fails.
TargetReached Fires when the target has been reached.
Function Purpose
start() Starts the waypoint following.
stop() Stops the waypoint following.
27 Likes

Hi,
can you make a editable game demo place to check it out in action with some NPCS?

also what about any attacking NPCs commands when a player is in range?

thanks

2 Likes

is this an alternative to SimplePath?

because if so, i can see myself using this :grinning:

2 Likes

I never meant it to be an alternative for SimplePath
While the API part may be simple in my module, you’d have to write the path generation, moveset and post-checker yourself in order to create custom pathfinding.

Meanwhile, SimplePath is honestly just simple since it’s just based on PathfindingService only and it works without further scripting.

all in all, if you want to make wall-ridden npcs that scale up buildings, go for InsanityPathfinder. If you want to make walking (or running) npcs across long paths, then go for SimplePath.

3 Likes

I will definitely make an uncopylocked demo place about it soon enough,
but I don’t know what you meant in the second question though

2 Likes

second question, is can this, when the NPC is on a path , can there also be a player detection like in a range say if player is 15 blocks away, can it break out out the path and instead run code to attack a player… then if the player dies, will it continue back to moving around on paths…

a attacking npc that also does paths while it is not attacking a player

1 Like

since you write custom code for the pathfinding and a stop() function is provided to you by the API, you can definitely create a fighting NPC with everything you’ve described in your question.

1 Like

nice, looking forward to seeing it in the demo game! thanks!

1 Like

I am currently working with chickynoid and I need a good pathfinding implementation, I will give this resource a try once I have time as it looks interesting, and I am also intrigued by your claims.

1 Like

this is really cool, is it better than SimplePath?

1 Like

When is demo place coming out?

I currently have work (unrelated to Roblox) and unfortunately unable to release a new update or demo place. I will try to keep the project up, thank you.

Thank you, I couldn’t get it to work, I put the script in, set the things to a NPC character and set a goal and use your example script but the NPC just stay in 1 spot.

This doesn’t work, I removed this and manually :Start the thing and it worked, for some reason your sucess thing doesn’t work. Idk if it’s just me.

TargetReached is not working :sob: