ModuleScript Question

Hello all,

i am coming up with a roadblock with a modulescript.
what i would like to achieve is:

i want the module script to know what “Player” is. i have a regular script, and it can find each player and their character and such through Players.PlayerAdded and such…

how would i send this information about the local player from a legacy script to a module script? is that achievable? if not, how can i have the module script ((an example, this doesn’t need to be the solution if you have a better way)) create a function immediately upon being required… like;

????????:Connect(function(player)

can someone explain this to me? or, more helpfully, give me a code example of how it would be done? (i am not going to provide my script as i don’t want people knowing how my game works and so i’m not tempted to copy/paste it into my game.)

1 Like

Depending on what your ModuleScript does, you can connect a specific event which calls a method from your ModuleScript, or reference a specific value from it, and work from there. I came up with this pseudo-code for overwriting a character variable each time a LocalPlayer respawns, but you could realistically implement this in any fashion you’d like:

-- legacy script
local ModuleScript = require(script.ModuleScript);

game:GetService("Players").LocalPlayer.CharacterAdded:Connect(function(newCharacter: Model)
	ModuleScript:DoThing(newCharacter);
end)

-- module script
moduleScript = {};

local Character = nil;

function ModuleScript:DoThing(newCharacter: Model)
	Character = newCharacter;
end

return moduleScript;

@soIar_punk 's method is correct.

local module = {}
module.__index = module
module.Player = nil

function module:ChangePlayer(newPlayer: Player)
    self.Player = newPlayer
end

return module




To answer the question about functions to run on module requirement:
You can make an Init function and call it when the module is required. Init is a naming convention intended to reference functions that are to run once, and only once, to initialise the script.

local module = {}
module.Player = nil
module.__index = module

function module:Init(player: Player)
    self.Player = player
end

return module
local module = require(path_to_module)
module:Init(player)

Simplest explanation I can come up with…

--script
local module = require(path.to.module)
Players.PlayerAdded:Connect(module.myFunc)

--modulescript 
local module = {}

module.myFunc = function(player)
    print(player.Name)
end

When the PlayerAdded event fires it passes the player as an argument.
Connect() identifies which function to run when this happens.
As we have required the module already we just identify which function in the module we want to use.
The module.myFunc expects 1 argument which we have called ‘player’. We could typecast this so the linter knows this should be an actual Player type, by writing:
module.myFunc = function(player:Player) but isn’t essential.

We can also call the module function in other code by:

--script 
local module = require(path.to.module)

local player = game.Players[1] --for example, this will be nil if no one has joined yet!
module.myFunc(player)

that makes sense, but when i incorporate that into my script, it says “index Nil with Character”

local function FM(Player)
local Character = Player.Character
local Humanoid = Character:FindFirstChild(“Humanoid”)
local HRP = Character:FindFirstChild(“HumanoidRootPart”)

by the way, it is being triggered from a legacy script when the player’s humanoid dies.

can someone explain whats happening?

I’m pretty sure that’s because Player is equal to nil which means it doesn’t exist. Can you show us the code that is calling the function? Is it running on a local script or normal script?

this is how my code is being called.

–variables.
print(“functional.”)
local remote1 = game:GetService(“ReplicatedStorage”).RemoteEventF:WaitForChild(“ReplicateS1”)
local remote2 = game:GetService(“ReplicatedStorage”).RemoteEventF:WaitForChild(“ReplicateS2”)

local Players = game:GetService(“Players”)

Players.PlayerAdded:Connect(function(player)
–function is present to define who each player is.
player.CharacterAdded:Connect(function(character)
–function is present to define if the player’s character died.
character:WaitForChild(“Humanoid”).Died:Connect(function(died)
print(“Humanoid has Died.”)
local Var = math.random(1,1)

	--rolling to see if finality mode will activate.
	if Var == 1 then
		print("Finality.")
		local Svar = math.random(1,2)
			if Svar ~= 1 then
				remote1:FireClient(player)
				require(game:GetService("StarterPlayer").StarterCharacterScripts["Finality Modes."].Spear["1stStateSS"])
			end
			
			if Svar == 1 then
				remote2:FireClient(player)
				require(game:GetService("StarterPlayer").StarterCharacterScripts["Finality Modes."].Spear["2ndStateSS"])
			end
		end	
		-- the following is if finality mode has not been activated.
		if Var ~= 1 then
			print("Finality mode has not been activated.")
		return end
	end)
end)

end)

i dont know why its half on, just ignore it ig

and, it is being called by a legacy script in SSS

hello? whats going wrong?? can someone help?

I have added a few specific notes to your code.

--variables.
print("functional.")
local remote1 = game:GetService("ReplicatedStorage").RemoteEventF:WaitForChild("ReplicateS1")
local remote2 = game:GetService("ReplicatedStorage").RemoteEventF:WaitForChild("ReplicateS2")

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local human = character:FindFirstChildWhichIsA("Humanoid") or character:WaitForChild("Humanoid") --If humanoid has not loaded we wait for it
		--character:WaitForChild("Humanoid").Died:Connect(function(died) --If "Humanoid" had already loaded the WaitFoirChild Event won't fire.
		human.Died:Connect(function(died)
			print("Humanoid has Died.")
			local Var = math.random(1,1) --???

			if Var == 1 then
				print("Finality.")
				local Svar = math.random(1,2)
				if Svar ~= 1 then
					remote1:FireClient(player)
					require(game:GetService("StarterPlayer").StarterCharacterScripts["Finality Modes."].Spear["1stStateSS"]) --[[What is this doing??
					You can do this and the module code will run, but...
					1. This will not be specific to any player as it will run on the server (this server script is the one requiring it).
					2. It will only run once (any other humanoid.died events will simply point to the same module, NOT run it again)
					]]
				end

				if Svar == 1 then
					remote2:FireClient(player)
					require(game:GetService("StarterPlayer").StarterCharacterScripts["Finality Modes."].Spear["2ndStateSS"])
				end
			--end	
				--if Var ~= 1 then --May as well use an 'else' here
			else
				print("Finality mode has not been activated.")
				--return --unnecessary as it returns nothing to nowhere and is on the last line
			end
		end)
	end)
end)

I am not sure what your intention is with the remote events and requires, I assume you want the client to run some specific code? In which case you would listen for the remote on the client and then require/run the modulescript functions from the client (local script).

im not having a problem with that script, im having an error come up when the module script for 1st state which cannot understand what the player is.

whenever i call the module script, ( the script is earlier in chat) player = nil for some reason. specificly, when i call the character. this is what i need help on.

(also, math.randon(1,1) was changed to be easier for testing…)

I assume your main language isn’t luau due to all the semi-colons.

1 Like

stay on topic please. i still haven’t solved this.

Your problem has already been solved. You just don’t know it. Using self in Luau you can pass preexisting data through different unrelated scopes:

local myModule = {}

myModule.__index = myModule

function myModule.new(player)
    local self = setmetatable({}, myModule)
    
    self.Player = player

    return self
end

function myModule:Method1() -- note colon instead
    print(self.Player)
end

return myModule

Simplest OOP code in the world.

image
ive tried something like this. im still getting the same error when i run this code.
the player is nil. the player’s character is nil. it is being called from a legacy script. i want to know why it is nil and how to fix it.

It is difficult to help you with your problem without knowing how you’ve tried to approach any possible solutions so far. Could you try and supply your relevant scripts and a brief description on what you are currently doing?

ok, i would be happy to give a full explanation. but i have a question… how do i add LUAU script material into the little box thing so i look cool and so you can understand anything