Why can't i access the module/function?

I am trying to combat system but i am having trouble with the local script. I made a module that creates status for the player so that you can check if the player has permission to attack. But it won’t check because it’s not able to find the module correctly.

local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local CombatFolder = ReplicatedStorage:FindFirstChild("Combat")
local M1 = CombatFolder:FindFirstChild("M1")

local Player = game.Players.LocalPlayer
local Character = Player.Character
local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")

task.wait()

local StatusScript = Character:FindFirstChild("StatusModule")
local StatusModule = require(StatusScript)

local Debounce = false
local LastTimeClicked = tick()

local Combo = 0

function HitboxCreate(Parent, Size, PositionPart)
	
	local Hitbox = Instance.new("Part")
	Hitbox.Parent = Parent
	Hitbox.Position = PositionPart.Position
	Hitbox.Size = Size
	Hitbox.CanCollide = false
	Hitbox.Transparency = 0.5
	Hitbox.Anchored = true
	Hitbox.BrickColor = BrickColor.new(255, 0, 0)
	
	return Hitbox
	
end

UserInputService.InputBegan:Connect(function(Input, gameProcessedEvent)
	if gameProcessedEvent then return end
	
	if Input.UserInputType == Enum.UserInputType.MouseButton1 then
		
		local StatusInfo = StatusModule.CheckStatus()
		local PlayerStatus = StatusInfo[Character]
		
		if PlayerStatus["Blocking"] == true then return end		
		if Debounce then return end
		
		Debounce = true
		
		if tick() - LastTimeClicked > 0.8 or Combo == 5 then
			
			Combo = 1
			
		else 
			
			Combo += 1
			
		end
		
		LastTimeClicked = tick()
		
		local HitBox = HitboxCreate(Character, Vector3.new(5, 5, 5), HumanoidRootPart)
		
		delay(.1, function()
			
			HitBox:Destroy()
			
		end)
		
		HitBox.Touched:Connect(function(Hit)
			
			if Hit.Parent:FindFirstChild("Humanoid") and Hit.Parent ~= Character then
				
				local DB = false
				local Humanoid = Hit.Parent:FindFirstChild("Humanoid")
				
				if DB then return end
				
				DB = true
				
				M1:FireServer()
				
				HitBox:Destroy()
				
				DB = false
				
			end
			
		end)
		
		Debounce = false

	end
	
	
end)

You should probably try using CharacterAdded:Wait() for the player’s character and WaitForChild.
Does it error on the StatusScript variable line? It might just be delay between the server and client. Does said module exist inside the character too?

1 Like

The modul does not need to be stored in the character, it needs to be put in replicated storage

local RS = game:GetService("ReplicatedStorage")
local Settings_RS = require(RS.MODULES.Settings_RS)

Local Script



local Players =  game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local PlayerGui = LocalPlayer.PlayerGui

local RS = game:GetService("ReplicatedStorage")
local Settings_RS = require(RS.Settings_RS)

local Character = workspace:WaitForChild(LocalPlayer.Name)
local Backpack = LocalPlayer.Backpack 
local HRP = Character:WaitForChild("HumanoidRootPart")
local Hum = Character:WaitForChild("Humanoid")
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()  
1 Like

It does not matter where a modulescript is. It can be in a tool or a character and still require()'d.

It’s more like it it can require the module but the information is not there, And the module script is in the character. I already tried it and it doesn’t work. It might be the delay between the server and the client since i already did checked it in a serverscript and it work perfectly fine.

Wouldn’t i access just one module script for every player then, Wouldn’t the variable Blocking be shared by every player?

Then in this case you’d replace
Character:FindFirstChild("StatusModule") with Character:WaitForChild("StatusModule"), and replacing player.Character with player.CharacterAdded:Wait() or player.Character to insure sync no? Your post says that the issue is the script saying it cannot find the ModuleScript in the player, and not possibly something in your ModuleScript itself.

What information in specific?

Change this to local Character = Player.Character or Player.CharacterAdded:Wait()

Change this to local StatusScript = Character:WaitForChild("StatusModule")

Im suspecting that this script isnt waiting for an accurate character model to fully load, which causes problems, please follow up with any errors, warnings you get!

(Generally objects within the Character have a delay to their loading time as the character model itself has a NetworkOwner by default)

You may have other objects named Combat and find first child is using that one first. Or it has not loaded yet so using :WaitForChild() is also a good idea.

Could you attach the error message as well?

The information I am referring to is not being able to get any information out of the module, I wrote a print for the module to see if the functions were still in it and a print for the PlayerStatus. I tried it from a server script and it did work correctly having the right information, But when i tried it in a local script it came out as nil.

The first two are the information that is missing and the last one is the error.

12:51:14.419  {}  -  Client - CombatInput:52
12:51:14.419  nil  -  Client - CombatInput:53
12:51:14.419  Workspace.NoobNezey.CombatInput:55: attempt to index nil with 'Blocking'  -  Client - CombatInput:55

Correct to use Character:WaitForChild("StatusModule") but this will enter an infinite loop if never found because the command was to wait. To overcome this you can provide a value to the second parameter which is the amount of seconds to continue waiting for the child, i.e.

local StatusScript = Character:WaitForChild("StatusModule", 5); -- this will give up waiting after 5 seconds and not cause forever loops
if not StatusScript then return end; -- we have run away at this point, no point continuing without core aspects of the code to follow

Never, ever, ever, ever, EVER!!! Assume returns, always check returns, ALWAYS! Otherwise any code afterwards can be doing stuff like:

nil:CallFunction(); -- you can't do that
nil = 10; -- you also cant do that!
2 Likes

need WaitForChild

-- Local Script
local Players =  game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local PlayerGui = LocalPlayer.PlayerGui

local Backpack = LocalPlayer.Backpack 
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local HRP = Character:WaitForChild("HumanoidRootPart")
local Hum = Character:WaitForChild("Humanoid")

local StatusScript = Character:WaitForChild("StatusModule")
local StatusModule = require(StatusScript)

where is your script located? StarterPlayerScripts or StarterCharacterScripts

It doesn’t matter really, it does if the code is working, but the above wont work.

-- Local Script
local Players =  game:GetService("Players");
local LocalPlayer = Players and Players.LocalPlayer;  -- checks Players is not nil first
local PlayerGui = LocalPlayer and LocalPlayer.PlayerGui; -- checks LocalPlayer is not nil first, etc...
local Backpack = PlayerGui and LocalPlayer.Backpack;
local Character = Backpack and LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait();
local HRP =  Character and Character:WaitForChild("HumanoidRootPart",5);
local Hum = HRP and Character:WaitForChild("Humanoid";5);

local StatusScript = Hum and Character:WaitForChild("StatusModule",5);
local StatusModule = StatusScript and require(StatusScript);

if not StatusModule then return end; -- concatenated calls above will not call anything after 'and' if anything is nil, so at this point the same 'nil' will propagate and reach here.
1 Like

Again just to reiterate, no checks on the inputs. So parent could be nil but you continue to parent the new hitbox to nil. ALWAYS! check inputs in function scope, and ALWAYS! check returns in the scope of the calling code!

function HitboxCreate(Parent, Size, PositionPart)
	
	local Hitbox = nil; -- set to nil the thing we want to return, this reduces confusion with multiple return branches
	if not Parent then return Hitbox end; -- i.e. nil
	if not Size or not Size:IsA("Vector3") then return Hitbox end; -- you provide a fixed allocated vector3 so seems illogical to check it. However, if the allocation fails, or the calling code changes in the future this function will not require changing
	if not PositionPart or not PositionPart:IsA("BasePart") then return Hitbox end; -- the same nil above

	Hitbox = Instance.new("Part"); -- now we attempt to allocate Hitbox
	if not Hitbox then return Hitbox end; -- must check it before indexing it though! Computer memory can run out easily with unchecked memory leaks, and Roblox could easily break at any point in time!

	-- rest of code
	-- ...

	return Hitbox; -- we always return the same thing, easier to understand and read

And also the return is unchecked here (i.e. the calling code):

		local HitBox = HitboxCreate(Character, Vector3.new(5, 5, 5), HumanoidRootPart)
		-- if HitBox is nil then the function call below is nil:Destroy() which is absurd, how do you destroy nothing!!
		delay(.1, function()
			
			HitBox:Destroy()
			
		end)