When using require(), regular script doesn't run

local Commands = require(script.Parent.Admin.Config.Commands)
local Settings = require(script.Parent.Admin.Config.Settings)

game.Players.PlayerAdded:Connect(function(player)
	print("test")
end)

This will not print “test” when I use the two require()s , but when I get rid of require()s it works perfectly fine.

I am… entirely lost on what’s happening here.

1 Like

There can be two explanations to this.

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

This is a server script, but thank you for your input!

1 Like

You could to something like this I think:

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.

2 Likes

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)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.