Im calling a module script named Match on server script:
local COUNTDOWN_TIME = 30 -- Countdown time in seconds
local MINIMUM_PLAYER_COUNT_PERCENTAGE = 0 -- The minimum players percentage for starting the match
local Players = game:GetService("Players")
local Settings = require(game.ReplicatedStorage.LobbySettings)
local KeyConstants = require(game.ReplicatedStorage.KeyConstants)
local PlayerCount = 9 -- The current player count in the server
local Countdown = false -- If countdown is on
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CountdownEvent = ReplicatedStorage:WaitForChild("CountdownEvent") -- args: {time,visible}
local WaitForPlayersEvent = ReplicatedStorage:WaitForChild("WaitForPlayersEvent") -- args: {playerCount, visible}
local AppliedRoleEvent = ReplicatedStorage:WaitForChild("AppliedRoleEvent")
local Match = require(game.ReplicatedStorage.Match)
Players.PlayerAdded:Connect(function(player)
player.CharacterAppearanceLoaded:Connect(function(character)
PlayerCount += 1
OnPlayerCountChange()
end)
end)
Players.PlayerRemoving:Connect(function(player)
PlayerCount -= 1
OnPlayerCountChange()
end)
function OnPlayerCountChange()
if PlayerCount/Settings.MaxPlayers > MINIMUM_PLAYER_COUNT_PERCENTAGE then
-- start countdown if not already counting
if not Countdown then
Countdown = true
WaitForPlayersEvent:FireAllClients(PlayerCount,false)
InitiateCountdown()
end
else
Countdown = false
CountdownEvent:FireAllClients(time,false)
WaitForPlayersEvent:FireAllClients(PlayerCount,true)
end
end
function InitiateCountdown()
local time = COUNTDOWN_TIME
while(Countdown) do
time -= 1
if PlayerCount >= Settings.MaxPlayers and time > 10 then
time = 10
end
CountdownEvent:FireAllClients(time,true)
print("Countdown: ",time)
print("players count: ",PlayerCount)
if(time == 0) then
Countdown = false
CountdownEvent:FireAllClients(time,false)
StartGame()
end
task.wait(1)
end
-- countdown is false, meaning stopped or canceled
end
function StartGame()
local match = Match.new()
local roles = Match:GenerateRoles()
for _,innocent in ipairs(roles.Innocent) do
AppliedRoleEvent:FireClient(innocent.Player,KeyConstants.InnocentKey)
end
for _,murderer in ipairs(roles.Murderer) do
AppliedRoleEvent:FireClient(murderer.Player,KeyConstants.MurdererKey)
end
for _,sheriff in ipairs(roles.Sheriff) do
AppliedRoleEvent:FireClient(sheriff.Player,KeyConstants.ShriffKey)
end
end
Match module script:
local Match = {}
Match.__index = Match
local Players = game:GetService("Players")
local PlayerProperties = require(game.ReplicatedStorage.PlayerProperties)
function Match.new()
local match = {}
setmetatable(match,Match)
match.AllPlayers = PlayerProperties:GetAllPlayersAsProperties()
task.wait()
print("players:",match.AllPlayers)
return match
end
function Match:GenerateRoles()
local roles ={
Innocent = {},
Murderer = {},
Sheriff = {}
}
local MurdererCount = 1
local SheriffCount = 1
-- TODO multiple
local totalWeight = self:CalculateTotalWeight()
local random = math.random(1,100) -- a number between 1 to 100
local sum = 0
-- currently sheriff and murderer is same weight
local i = 1
while sum/totalWeight < random / 100 and i ~= #self.AllPlayers do
sum+= self.AllPlayers[i].Weight
i += 1
end
i -= 1
roles.Murderer = {self.AllPlayers[i]}
-- for sheriff
local withoutMurder = table.clone(self.AllPlayers)
withoutMurder = withoutMurder.remove(withoutMurder,i)
for _, p in ipairs(roles.Murderer) do
totalWeight -= p.Weight
end
i = 1
random = math.random(1,100)
sum = 0
while sum/totalWeight < random / 100 and i ~= #withoutMurder do
sum+= withoutMurder[i].Weight
i += 1
end
i-= 1
roles.Sheriff = {withoutMurder[i]}
roles.Innocent = table.remove(withoutMurder,i)
return roles
end
function Match:CalculateTotalWeight()
local total = 0
for _, properties in ipairs(self.AllPlayers) do
total += properties.Weight
end
return total
end
return Match
PlayerProperties module script:
local PlayerProperties = {}
local Players = game:GetService("Players")
function PlayerProperties:GetPlayerWeight(player : Player)
return 1
end
function PlayerProperties:SetWeightToPlayer(player : Player,weight)
end
function PlayerProperties:GetAllPlayersAsProperties()
local players = Players:GetPlayers()
local allPlayers = {}
for _, p in ipairs(players) do
local properties = {
Player = p,
Weight = self:GetPlayerWeight(p)
}
table.insert(allPlayers,properties)
end
return allPlayers
end
return PlayerProperties
The server console prints “in calc” and errors on the ipairs of the CalculateTotalWeight, saying self.AllPlayers is nil. But does not print the players on the new() function.
in other hand, the client console prints the players from the new() function but does not error…
and from some reason I had to place task.wait() after the initializeation of the AllPlayers so it wouldnt be nil.
I really have no clue whats going on, it seems that calling a module script from a module script is async, and that it calls it from a client side.
May anyone explain to me why this happens?

