The most likely one is that the player managed to join during the requires, which means that the :Connect() isn’t done until after the player exists. You can add a print before that (print(#game:GetService("Players"):GetPlayers())) to verify this.
The other alternative is that the requires never return, to make sure this isn’t the case just open the scripts you require and make sure that they don’t have an infinite loop (that isn’t in a function)
Looks like your first theory is correct. But how do I apply it to something like this, where it is more vital that they are required? Would I just put the requires inside the player function?
local Commands = require(script.Parent.Parent.Config.Commands)
local Settings = require(script.Parent.Parent.Config.Settings)
game.Players.PlayerAdded:Connect(function(player)
print("test")
player.Chatted:Connect(function(message)
print("Test0")
if string.sub(message, 1, #Settings.Prefix) == Settings.Prefix then
print("Test0.5")
local command = string.sub(message, #Settings.Prefix + 1)
local args = {}
for argument in string.gmatch(command, "%S+") do
table.insert(args, argument)
end
local cmd = args[1]
table.remove(args, 1)
for commandName, commandInfo in pairs(Commands) do
print("Test1")
if commandInfo.AdminLevel == "Guest" or (Settings.GroupRanksEnabled and player:GetRankInGroup(Settings.GroupId) >= Settings.GroupRanks[commandInfo.AdminLevel].grouprank) then
print("TestA")
for _, cmdAlias in pairs(commandInfo.Commands) do
if string.lower(cmdAlias) == string.lower(cmd) then
print("TestB")
commandInfo.Function(player, args)
break
end
end
end
end
end
end)
end)
Is this on a local script? if it is then that might be the problem (which I faced before ;-; ) because I think that it takes time for the game to set up the local side (even after the player is already joined), so meanwhile doing that the local script “missed” the game.Players.PlayerAdded event that is already passed that time period.
I think that maybe you put the game.Players.PlayerAdded event in a server script, and also created a RemoteEvent, so that when the PlayerAdded event is triggered in the server side, it can send the info back to the client
local Commands -- Define them
local Settings
task.spawn(function() -- Do this async
Commands = require(script.Parent.Parent.Config.Commands)
Settings = require(script.Parent.Parent.Config.Settings)
end)
game.Players.PlayerAdded:Connect(function(player)
print("test")
... -- Rest of your code. You shouldn't have to make sure that they actually exist inside here
-- as the function above should be finish really quick. it might be worth doing so though
end)
However, this is an issue exclusive to studio (as long as it is a server script) as the server needs to fully start before any players can join, which means every script that has .PlayerAdded:Connect() has ample time to connect.
Edit: I was pretty tired when writing this and as such the code is far from the best way to do it. See @YasuYoshida’s solution for better implementation.
Your problem is what’s called a race condition, which is what @ifkpop has described. However, the solution provided is not the correct way to fix your problem. The best solution is to run the code for all existing players and any player that joins afterwards, which looks like this:
local function onPlayerAdded(player: Player)
print(`{player} has joined!`)
end
local Players = game:GetService("Players")
for _,player in Players:GetPlayers() do
task.spawn(onPlayerAdded, player)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Using this pattern ensures that the onPlayerAdded function will run for every player. In your case it would look like this:
local Commands = require(script.Parent.Admin.Config.Commands)
local Settings = require(script.Parent.Admin.Config.Settings)
local function onPlayerAdded(player: Player)
print("test")
end
local Players = game:GetService("Players")
for _,player in Players:GetPlayers() do
task.spawn(onPlayerAdded, player)
end
Players.PlayerAdded:Connect(onPlayerAdded)