It worked previously, but recently it broke, and it would not detect when a player joined the game. I simply fixed this, by tying in the function it was supposed to call with my leaderboard script when a player joins the game.
However, this has me wondering - can you even call events in ModuleScripts (outside of a function being called)? As I said before, it was done in the past, but somewhat recently this was changed for me.
It still doesn’t do anything. The solution was to change OnPlayerAdded from a local function to a FlagStandManager.OnPlayerAdded function (as you initially suggested and what I did, except with a : instead of . ) and have it called from a separate server script. Not a big deal, but I wanted to keep this to one script, so I came here to ask if it’s even possible to have a lone event listened, outside the module functions, and have it actually work.
local FlagStandManager = {}
-- ROBLOX Services
local Players = game:GetService("Players")
-- Game Services
local Configurations = require(game.ServerStorage.Configurations)
-- Local Variables
local FlagObjects = {}
local FlagCarriers = {}
local Events = game.ReplicatedStorage.serverSidedRemotes
local CaptureFlag = Events.CaptureFlag
local ReturnFlag = Events.ReturnFlag
-- Local Functions
local MakeFlag
local function DestroyFlag(flagObject)
flagObject.Flag:Destroy()
for player, object in pairs(FlagCarriers) do
if object == flagObject then
FlagCarriers[player] = nil
end
end
end
local function OnCarrierDied(player)
local flagObject = FlagCarriers[player]
if flagObject then
local flagPole = flagObject.FlagPole
local flagBanner = flagObject.FlagBanner
flagPole.CanCollide = false
flagBanner.CanCollide = false
flagPole.Anchored = true
flagBanner.Anchored = true
flagObject.PickedUp = false
FlagCarriers[player] = nil
if Configurations.RETURN_FLAG_ON_DROP then
wait(Configurations.FLAG_RESPAWN_TIME)
if not flagObject.AtSpawn and not flagObject.PickedUp then
DestroyFlag(flagObject)
MakeFlag(flagObject)
ReturnFlag:Fire(flagObject.FlagBanner.BrickColor)
end
end
end
end
local function PickupFlag(player, flagObject)
FlagCarriers[player] = flagObject
flagObject.AtSpawn = false
flagObject.PickedUp = true
local torso
if player.Character.Humanoid.RigType == Enum.HumanoidRigType.R6 then
torso = player.Character:FindFirstChild('Torso')
else
torso = player.Character:FindFirstChild('UpperTorso')
end
local flagPole = flagObject.FlagPole
local flagBanner = flagObject.FlagBanner
flagPole.Anchored = false
flagBanner.Anchored = false
flagPole.CanCollide = false
flagBanner.CanCollide = false
local weld = Instance.new('Weld', flagPole)
weld.Name = 'PlayerFlagWeld'
weld.Part0 = flagPole
weld.Part1 = torso
weld.C0 = CFrame.new(0,0,-1)
end
local function BindFlagTouched(flagObject)
local flagPole = flagObject.FlagPole
local flagBanner = flagObject.FlagBanner
flagPole.Touched:Connect(function(otherPart)
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if not player then return end
if not player.Character then return end
local humanoid = player.Character:FindFirstChild('Humanoid')
if not humanoid then return end
if humanoid.Health <= 0 then return end
if flagBanner.BrickColor ~= player.TeamColor and not flagObject.PickedUp then
PickupFlag(player, flagObject)
Events.StoleFlag:Fire(player)
elseif flagBanner.BrickColor == player.TeamColor and not flagObject.AtSpawn and Configurations.FLAG_RETURN_ON_TOUCH then
DestroyFlag(flagObject)
MakeFlag(flagObject)
ReturnFlag:Fire(flagObject.FlagBanner.BrickColor)
end
end)
end
function MakeFlag(flagObject)
flagObject.Flag = flagObject.FlagCopy:Clone()
flagObject.Flag.Parent = flagObject.FlagContainer
flagObject.FlagPole = flagObject.Flag.FlagPole
flagObject.FlagBanner = flagObject.Flag.FlagBanner
flagObject.FlagBanner.CanCollide = false
flagObject.AtSpawn = true
flagObject.PickedUp = false
BindFlagTouched(flagObject)
end
local function BindBaseTouched(flagObject)
local flagBase = flagObject.FlagBase
flagBase.Touched:Connect(function(otherPart)
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if not player then return end
if flagBase.BrickColor == player.TeamColor and FlagCarriers[player] then
CaptureFlag:Fire(player)
local otherFlag = FlagCarriers[player]
DestroyFlag(otherFlag)
MakeFlag(otherFlag)
end
end)
end
function FlagStandManager.OnPlayerAdded(player)
print("this should work.")
player.CharacterAdded:Connect(function(character)
print("this should work too.")
character:WaitForChild('Humanoid').Died:Connect(function() OnCarrierDied(player) end)
end)
player.CharacterRemoving:Connect(function()
print("this should work, three!")
OnCarrierDied(player)
end)
end
-- Public Functions
function FlagStandManager:Init(container)
local flagObject = {}
local success, message = pcall(function()
flagObject.AtSpawn = true
flagObject.PickedUp = false
flagObject.TeamColor = container.FlagStand.BrickColor
flagObject.Flag = container.Flag
flagObject.FlagPole = container.Flag.FlagPole
flagObject.FlagBanner = container.Flag.FlagBanner
flagObject.FlagBase = container.FlagStand
flagObject.FlagCopy = container.Flag:Clone()
flagObject.FlagContainer = container
end)
if not success then
warn("Flag object not built correctly. Please load fresh template to see how flag stand is expected to be made.")
end
BindBaseTouched(flagObject)
DestroyFlag(flagObject)
MakeFlag(flagObject)
table.insert(FlagObjects, flagObject)
end
-- Event Bindings
--Players.PlayerAdded:Connect(OnPlayerAdded)
return FlagStandManager
Here’s the original, not working code
local FlagStandManager = {}
-- ROBLOX Services
local Players = game:GetService("Players")
-- Game Services
local Configurations = require(game.ServerStorage.Configurations)
-- Local Variables
local FlagObjects = {}
local FlagCarriers = {}
local Events = game.ReplicatedStorage.serverSidedRemotes
local CaptureFlag = Events.CaptureFlag
local ReturnFlag = Events.ReturnFlag
-- Local Functions
local MakeFlag
local function DestroyFlag(flagObject)
flagObject.Flag:Destroy()
for player, object in pairs(FlagCarriers) do
if object == flagObject then
FlagCarriers[player] = nil
end
end
end
local function OnCarrierDied(player)
local flagObject = FlagCarriers[player]
if flagObject then
local flagPole = flagObject.FlagPole
local flagBanner = flagObject.FlagBanner
flagPole.CanCollide = false
flagBanner.CanCollide = false
flagPole.Anchored = true
flagBanner.Anchored = true
flagObject.PickedUp = false
FlagCarriers[player] = nil
if Configurations.RETURN_FLAG_ON_DROP then
wait(Configurations.FLAG_RESPAWN_TIME)
if not flagObject.AtSpawn and not flagObject.PickedUp then
DestroyFlag(flagObject)
MakeFlag(flagObject)
ReturnFlag:Fire(flagObject.FlagBanner.BrickColor)
end
end
end
end
local function PickupFlag(player, flagObject)
FlagCarriers[player] = flagObject
flagObject.AtSpawn = false
flagObject.PickedUp = true
local torso
if player.Character.Humanoid.RigType == Enum.HumanoidRigType.R6 then
torso = player.Character:FindFirstChild('Torso')
else
torso = player.Character:FindFirstChild('UpperTorso')
end
local flagPole = flagObject.FlagPole
local flagBanner = flagObject.FlagBanner
flagPole.Anchored = false
flagBanner.Anchored = false
flagPole.CanCollide = false
flagBanner.CanCollide = false
local weld = Instance.new('Weld', flagPole)
weld.Name = 'PlayerFlagWeld'
weld.Part0 = flagPole
weld.Part1 = torso
weld.C0 = CFrame.new(0,0,-1)
end
local function BindFlagTouched(flagObject)
local flagPole = flagObject.FlagPole
local flagBanner = flagObject.FlagBanner
flagPole.Touched:Connect(function(otherPart)
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if not player then return end
if not player.Character then return end
local humanoid = player.Character:FindFirstChild('Humanoid')
if not humanoid then return end
if humanoid.Health <= 0 then return end
if flagBanner.BrickColor ~= player.TeamColor and not flagObject.PickedUp then
PickupFlag(player, flagObject)
Events.StoleFlag:Fire(player)
elseif flagBanner.BrickColor == player.TeamColor and not flagObject.AtSpawn and Configurations.FLAG_RETURN_ON_TOUCH then
DestroyFlag(flagObject)
MakeFlag(flagObject)
ReturnFlag:Fire(flagObject.FlagBanner.BrickColor)
end
end)
end
function MakeFlag(flagObject)
flagObject.Flag = flagObject.FlagCopy:Clone()
flagObject.Flag.Parent = flagObject.FlagContainer
flagObject.FlagPole = flagObject.Flag.FlagPole
flagObject.FlagBanner = flagObject.Flag.FlagBanner
flagObject.FlagBanner.CanCollide = false
flagObject.AtSpawn = true
flagObject.PickedUp = false
BindFlagTouched(flagObject)
end
local function BindBaseTouched(flagObject)
local flagBase = flagObject.FlagBase
flagBase.Touched:Connect(function(otherPart)
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if not player then return end
if flagBase.BrickColor == player.TeamColor and FlagCarriers[player] then
CaptureFlag:Fire(player)
local otherFlag = FlagCarriers[player]
DestroyFlag(otherFlag)
MakeFlag(otherFlag)
end
end)
end
local function OnPlayerAdded(player)
print("this should work.")
player.CharacterAdded:Connect(function(character)
print("this should work too.")
character:WaitForChild('Humanoid').Died:Connect(function() OnCarrierDied(player) end)
end)
player.CharacterRemoving:Connect(function()
print("this should work, three!")
OnCarrierDied(player)
end)
end
-- Public Functions
function FlagStandManager:Init(container)
local flagObject = {}
local success, message = pcall(function()
flagObject.AtSpawn = true
flagObject.PickedUp = false
flagObject.TeamColor = container.FlagStand.BrickColor
flagObject.Flag = container.Flag
flagObject.FlagPole = container.Flag.FlagPole
flagObject.FlagBanner = container.Flag.FlagBanner
flagObject.FlagBase = container.FlagStand
flagObject.FlagCopy = container.Flag:Clone()
flagObject.FlagContainer = container
end)
if not success then
warn("Flag object not built correctly. Please load fresh template to see how flag stand is expected to be made.")
end
BindBaseTouched(flagObject)
DestroyFlag(flagObject)
MakeFlag(flagObject)
table.insert(FlagObjects, flagObject)
end
-- Event Bindings
Players.PlayerAdded:Connect(OnPlayerAdded)
return FlagStandManager
I think the problem here is that when you require this script, the player has already joined. The connection is indeed functional. It’s just that the player had joined before it was created. PlayerAdded doesn’t account for that. It only accounts for new players, not pre-existing players.
You’d fix this issue with something like this:
-- This loop will account for any players who have already joined
for _, player in ipairs(Players:GetPlayers()) do
task.spawn(onPlayerAdded, player)
end
-- Any new players will be handled as normal.
Players.PlayerAdded:Connect(onPlayerAdded)