Is there a way to make module scripts only run where they are required?

only can really describe this issue with code so

local function onRayHit(Cast, result, velocity, bullet)
	local hit = result.Instance
	local character = hit:FindFirstAncestorWhichIsA("Model")
	if character and character:FindFirstChild("Humanoid") then
		M.Damage()`Preformatted text`
	end
	delay(0, function()
		bulletCache:ReturnPart(bullet)
	end)
end

this is where i require the first module

local Talents = {}

Talents.Damage = function()
	local T1 = script.Parent.T1
	local T = game:GetService("ReplicatedStorage").Tals
	local TG = require(T:FindFirstChild(T1.Value))
	TG.Yes()
end


return Talents

this is the first module, had to put it into the tool so i could define stuff so it would work
it requires another module

local module = {}

module.Yes = function()
	if hit.Name == "Head" then
		character.Humanoid:TakeDamage(math.round((DmgV.Value * (gLevel.Value/10))*1.5))
	elseif hit.Name == "Torso" then
		character.Humanoid:TakeDamage(math.round((DmgV.Value * (gLevel.Value/10))))
	else
		character.Humanoid:TakeDamage(math.round((DmgV.Value * (gLevel.Value/10))*0.7))
	end
end

return module

and heres the module the module requires, but is there a way to make it so the code only runs in the first script? because i get this error
TestService: Exception thrown in your RayHit event handler: ReplicatedStorage.Tals.B:8: attempt to index nil with 'Nameā€™

Pretty sure its require(Module).Yes()

Iā€™m not sure what youā€™re asking, but you seem to have variables in the module.Yes function that arenā€™t properly defined. The error tells you that ā€˜hitā€™ is nil since it attempts to index it with ā€˜Nameā€™. You may need to pass these variables through the functions so they know what theyā€™re doing.

ModuleScripts already, by design, do not run unless required so Iā€™m not sure what you meant by whatā€™s in the title. Looks like you have a different problem that youā€™re confusing for a ModuleScript automatically executing. Consider using some Debugging Tools?

2 Likes

it thought the modules would ignore the varibles until it got required in the script where the varibles are defined

Basically looking for a way around this
(edit, also changed it so the first module isnt needed anymore)

local function onRayHit(Cast, result, velocity, bullet)
	local hit = result.Instance
	local character = hit:FindFirstAncestorWhichIsA("Model")
	if character and character:FindFirstChild("Humanoid") then
		local T = game:GetService("ReplicatedStorage").Tals
		local TG = require(T:FindFirstChild(tool.T1.Value))
		TG.Yes()
	end
	delay(0, function()
		bulletCache:ReturnPart(bullet)
	end)
end

Variables do not pass through functions unless explicitly defined in the same environment whether that be in the module script itself or if passed with the require. You should pass the hit through the TG.Yes() line.

Basically:

TG.Yes()
-- should be
TG.Yes(hit)

module.Yes = function()
-- should be
module.Yes = function(hit)

Before the conditional in module.Yes you should also add local character = hit:FindFirstAncestorWhichIsA("Model") or pass that variable over also so the function knows what the character variable is referencing.

alright this fixxed the hit and the character, but what should i do about DmgV.Value and gLevel.Value, there are only in the gun that fires the first require
(Edit heres the new module)

local module = {}

module.Yes = function(hit)
	local character = hit:FindFirstAncestorWhichIsA("Model")
	if hit.Name == "Head" then
		character.Humanoid:TakeDamage(math.round((DmgV.Value * (gLevel.Value/10))*1.5))
	elseif hit.Name == "Torso" then
		character.Humanoid:TakeDamage(math.round((DmgV.Value * (gLevel.Value/10))))
	else
		character.Humanoid:TakeDamage(math.round((DmgV.Value * (gLevel.Value/10))*0.7))
	end
end

return module

Then you should also define the gun that fires the require, assuming that you would be able to find both of the variables in that gun. Pass the instance of the gun and you can redefine the DmgV and gLevel in the module.

How would i get the player thats requiring the module script?

If itā€™s a local script, youā€™d need to do game.Players.LocalPlayer but Iā€™m not entirely sure how your scripts are structured so iā€™m assuming itā€™s a server script.

You can grab the playerā€™s character in this case by doing gun.Parent Assuming that gun is a Tool and being used by the player. Then you can use Players:GetPlayerFromCharacter(), which will return the Player instance from the character.

ok but now how would i define the gun since the second module is in replicated storage

Define it in the require. Pass it along so the module knows gun its acting on like how you passed hit.

Something like this?

local Talents = {}

Talents.Damage = function()
	local T1 = script.Parent.T1
	local T = game:GetService("ReplicatedStorage").Tals
	local TG = require(T:FindFirstChild(T1.Value))
	local D = script.Parent
	TG.Yes(hit, D)
end


return Talents

i tried it here and

local module = {}

module.Yes = function(hit, D)
	local character = hit:FindFirstAncestorWhichIsA("Model")
	local DmgV = D.Damage
	local gLevel = D.GunLevel
	if hit.Name == "Head" then
		character.Humanoid:TakeDamage(math.round((DmgV.Value * (gLevel.Value/10))*1.5))
	elseif hit.Name == "Torso" then
		character.Humanoid:TakeDamage(math.round((DmgV.Value * (gLevel.Value/10))))
	else
		character.Humanoid:TakeDamage(math.round((DmgV.Value * (gLevel.Value/10))*0.7))
	end
end

return module

get the error
TestService: Exception thrown in your RayHit event handler: ReplicatedStorage.Tals.B:6: attempt to index nil with 'Damageā€™

Weird. Where is the ā€œgunā€ in retrospect to the script when the ray is fired? I dont know why, but it seems that script.Parent is not present while the ray tries to define it. Iā€™m not sure whatā€™s going on here.

its in the player, as to fire the ray the gun must be equipped,
image

Oops, that was on me, forgot i stopped using the module script within the tool, anyways i got it to work with

local function onRayHit(Cast, result, velocity, bullet)
	local hit = result.Instance
	local character = hit:FindFirstAncestorWhichIsA("Model")
	if character and character:FindFirstChild("Humanoid") then
		local T = game:GetService("ReplicatedStorage").Tals
		local TG = require(T:FindFirstChild(tool.T1.Value))
		TG.Yes(hit, tool)
	end
	delay(0, function()
		bulletCache:ReturnPart(bullet)
	end)
end

and

local module = {}

module.Yes = function(hit, tool)
	local character = hit:FindFirstAncestorWhichIsA("Model")
	local DmgV = tool.Damage
	local gLevel = tool.GunLevel
	if hit.Name == "Head" then
		character.Humanoid:TakeDamage(math.round((DmgV.Value * (gLevel.Value/10))*1.5))
	elseif hit.Name == "Torso" then
		character.Humanoid:TakeDamage(math.round((DmgV.Value * (gLevel.Value/10))))
	else
		character.Humanoid:TakeDamage(math.round((DmgV.Value * (gLevel.Value/10))*0.7))
	end
end

return module

one last question, is there anyway i can make this better? / more optimized without losing functionality