So I was just messing around with @loleris’s ProfileService Module and wrote my :Get() function but when I require it the PlayerAdded function don’t fire.
DataManager Script-
local Rs = game:GetService("ReplicatedStorage");
local Players = game:GetService("Players");
local ProfileService = require(script:WaitForChild("ProfileService"));
local ProfileStore = ProfileService.GetProfileStore(
"Player",
{
Cash = 0
}
);
local Profiles = {};
local function MakeLeaderstats(player)
local profile = Profiles[player];
local leaderstats = Instance.new("Folder", player);
leaderstats.Name = "leaderstats";
local Cash = Instance.new("IntValue", leaderstats);
Cash.Name = "Cash"
Cash.Value = profile.Data.Cash
local thread = coroutine.wrap(function()
while true do
Cash.Value = profile.Data.Cash
game:GetService("RunService").Heartbeat:Wait();
end
end)
thread();
end
function OnPlayerAdded(player)
local profile = ProfileStore:LoadProfileAsync(
"Player_" .. player.UserId,
"ForceLoad"
);
profile:Reconcile();
if profile ~= nil then
profile:ListenToRelease(function()
Profiles[player] = nil;
player:Kick();
end)
if player:IsDescendantOf(Players) then
Profiles[player] = profile;
MakeLeaderstats(player);
else
profile:Release();
end
else
player:Kick();
end;
end;
for _,player in ipairs(Players:GetPlayers()) do
coroutine.wrap(OnPlayerAdded)(player)
end
Players.PlayerAdded:Connect(OnPlayerAdded);
Players.PlayerRemoving:Connect(function(player)
local profile = Profiles[player];
if profile ~= nil then
profile:Release();
Profiles[player] = nil;
player:Kick();
end
end)
local DataManager = {};
function DataManager:Get(player)
local profile = Profiles[player];
if profile then
return profile.Data;
end;
end;
return DataManager;
Script that is not working-
local ProfileService = require(game.ReplicatedStorage:WaitForChild("DataManager"));
game.Players.PlayerAdded:Connect(function(player)
print(player.Name) -- Doesn't fire
print(ProfileService:Get(player).Cash) --Doesn't fire
end)
Is it because I have playerAdded event already the module?
Note: If I attach it to a ClickDetector Even for example it woks for some reason.
Script that works-
local part = game.Workspace:WaitForChild("Part");
local ClickDetector = part:WaitForChild("ClickDetector");
local ProfileService = require(game.ReplicatedStorage.DataManager)
print("Yes")
ClickDetector.MouseClick:Connect(function(player)
local Data = ProfileService:Get(player); -- works
Data.Cash += 100 --works
end)
The most obvious answer I can think of is that by the time ProfileService is loaded into the script, it yields the thread so the PlayerAdded isn’t connected till then and you already join the game. Don’t know if this is the reason, but I have seen it happen in someone else’s code too previously and although not a good fix, they put it in a spawn block so it doesn’t yield the thread.
local ProfileService = require(game.ReplicatedStorage:WaitForChild("DataManager"));
game.Players.PlayerAdded:Connect(function(player)
print(player.Name) -- Doesn't fire
print(ProfileService:Get(player).Cash) --Doesn't fire
end)
With
local ProfileService
coroutine.wrap(function()
ProfileService = require(game.ReplicatedStorage:WaitForChild("DataManager"));
end)()
game.Players.PlayerAdded:Connect(function(player)
if not ProfileService then repeat wait() until ProfileService end
print(player.Name) -- Doesn't fire
print(ProfileService:Get(player).Cash) --Doesn't fire
end)
local ProfileService
coroutine.wrap(function()
ProfileService = require(game.ReplicatedStorage:WaitForChild("DataManager"));
end)()
game.Players.PlayerAdded:Connect(function(player)
if not ProfileService then
repeat wait()
print("something") -- this prints infinitely
until ProfileService
end
print(player.Name) -- Doesn't fire
print(ProfileService:Get(player).Cash) --Doesn't fire
end)
Try without the :WaitForChild(). I don’t see why it is needed since this is a server script, and the ReplicatedStorage’s children should be loaded already when using the dot operator.
Try this:
local Players = game:GetService('Players')
local Replicated = game:GetService('ReplicatedStorage')
local Module = require(Replicated.DataManager)
Players.PlayerAdded:Connect(function(Player)
-- Code.
end)
The reason why it might not fire is because WaitForChild yields the thread until a result is ready, it will yield infinitely if the specified object is not found, the default time-out is 5 seconds (unless you change it yourself).
PlayerAdded doesn’t fire in Studio because the player added event fires Before your script is instanced. When you play the game, the player added event will fire, so you should test your ‘player added’ code there.
The documentation for ProfileService states you should iterate through every player before connecting the PlayerAdded event to make sure you “initialize” their data.``
local RunService = game:GetService("RunService")
local DataTemplate = {
Coins = 0,
Pets = {},
LastPlayed = os.time(),
LoginCount = 0
}
local ProfileService = require(script.Parent.ProfileService)
local PlayerProfileStore = ProfileService.GetProfileStore("Data", DataTemplate)
local Profiles = {}
local function PlayerAdded(Player)
local Profile = PlayerProfileStore:LoadProfileAsync("Player_" .. Player.UserId, "ForceLoad")
if Profile ~= nil then
Profile:Reconcile() -- Fill in missing variables from ProfileTemplate (optional)
Profile:ListenToRelease(function()
Profiles[Player] = nil
Player:Kick()
end)
if Player:IsDescendantOf(Players) == true then
Profiles[Player] = Profile
Profile.Data.LoginCount += 1
print(Player.Name .. " has logged in " .. tostring(Profile.Data.LoginCount) .. " time" .. ((Profile.Data.LoginCount > 1) and "s" or ""))
else
Profile:Release()
end
else
Player:Kick()
end
end
for _, Player in ipairs(Players:GetPlayers()) do
coroutine.wrap(PlayerAdded)(Player)
end
Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(function(Player)
local Profile = Profiles[Player]
if Profile ~= nil then
Profile:Release()
end
end)
return Profiles
Yes, that will make sure to call the function on all the players currently in game and that is the solution since normally, scripts run first before anything but in your case, they run a bit after when a player joins.