Why won't this code work in a modulescript?

I wrote some code for an NPC that chases the player, and it seemed to be working fine.

However when I stored the functions for the NPC in a modulescript, and used them in a serverscript, the script just broke.

I don’t know why, and I’m a bit of a noob when it comes to modulescripts so yeah

Code below:

-- Modulescript
local NPC = {}

function NPC:getTarget(attackDist)
	
	local char
	local charRootPart
	local target
	
	local minimumDist = attackDist

	for i,v in pairs (workspace:GetDescendants()) do
		
		if v:IsA("Humanoid") then
			
			char = v.Parent
			charRootPart = v.RootPart
						
			print(char)
			print(charRootPart)
		
			if (charRootPart.Position - NPC.Torso.Position).magnitude < minimumDist then
				target = charRootPart
				minimumDist = charRootPart.Position
				
			end
			
		end
	end
	
	return target
end


function NPC:getPath(PathfindingService, humanoid)
	
	local target = NPC.getTarget()
	
	if target then
		
		local path = PathfindingService:CreatePath()
		
		path:ComputeAsync(NPC.Torso.Position, target.Position)
		
		local waypoints = path:GetWaypoints()
		local distance		

		for _, waypoints in pairs (waypoints) do

			humanoid:MoveTo(waypoints.Position)
			
			while distance do
				
				distance = (waypoints.Position - NPC.Torso.Position).magnitude
				wait()
				
			 end
			
		end
	end
	
end
return NPC

and the serverscript:

-- Server script

local NPC = workspace.NPC
local humanoid = NPC.Humanoid

local PathfindingService = game:GetService("PathfindingService")
local attackDist = 50

local playerDetected = false
local NPC_Functions = require(script.Parent.NPC_Functions)

NPC_Functions:getTarget(attackDist)

wait()

NPC_Functions:getPath(PathfindingService, humanoid)

If anybody could help, I would appreciate it

In order to create methods for NPC you have to initalise it as a table first. i.e. local NPC = {}

I actually did that, but that line of code doesn’t appear here for some reason

Where you do define NPC? Reading your code you are using NPC as a model and a table.

I defined NPC at the start of the script as a table

Then how are you using NPC.Torso? You will need to define the model as NPCModel or something else to be able to get the Torso.

They’ve presented two scripts. A lot clearer if they split them up instead of putting them in one code block.

Yeah I forgot about that, I did that just now.

But the script still doesn’t work and there’s a new problem now, the script doesn’t find my character but instead finds NPC’s humanoid and thinks the NPC is the target instead of my player’s character

If you want it to only follow players you should use player service. Otherwise set a filter to make sure the NPC can’t target it’s self.

This will never end by the way. You never set distance to anything that would be considered false. Not sure if that’s the intention but there’s clearer ways to make an infinite loop if that’s what you want. I probably would’ve bound it to an event like Heartbeat instead.

Are there any errors or anything else to help point towards a problem. Generally if things “don’t work” there’s either an error or if you’re lucky studio picks up a potential issue and underlines it.

Well I keep getting this error:
16:10:01.596 - Workspace.NPC.NPC_Functions:20: attempt to index nil with ‘Torso’

Also this is the line of code where everything goes wrong:

if (charRootPart.Position - npcModel.Torso.Position).magnitude < minimumDist then

Okay so there’s several fundamental issues.

You’ve confused the NPC model and the module by trying to index the NPC torso in the module script even though you never passed either function the NPC model.

You also call getTarget with a dot instead of a colon and don’t give it the attackDist argument, so that will fail as minimumDist is set to nil.

The first call to getTarget in the server script seems pointless as you don’t use the result from it, whereas I’d expect you to maybe get the result from getTarget and pass it as a parameter to getPath.

You’ve very clearly chopped this out into a module script and left everything as if it was still inside the server script. It’s just not going to work - your module can only see the parameters and variables you pass to it.

I recommend renaming the module to create a clearer distinction being NPC (model) and NPC (module) within the module as well as in the server script.

1 Like

Alright, I’ll try doing that now, thanks for the suggestions