local Services = require(game.ReplicatedStorage.Utils.Services).new():GetServices()
local PlayerDataHandler = {}
local dataTemplate = {
Coins = 100,
Rebirths = 0,
Level = 1,
Exp = 0,
Need = 100,
Rasa = "Human",
Location = "Spawn",
}
local ProfileService = require(Services.ServerScriptService.Libs.ProfileService)
local ProfileStore = ProfileService.GetProfileStore(
"PlayerProfile",
dataTemplate
)
local Profiles = {}
local function PlayerAdded(player)
local profile = ProfileStore:LoadProfileAsync("Player"..player.UserId)
if profile then
profile:AddUserId(player.UserId)
profile:Reconcile()
profile:ListenToRelease(function()
Profiles[player] = nil
player:Kick()
end)
if not player:IsDescendantOf(Services.Players) then
profile:Release()
else
Profiles[player] = profile
print(Profiles[player].Data)
end
else
player:Kick()
end
end
function PlayerDataHandler:Init()
for _, player in Services.Players:GetPlayers() do
task.spawn(PlayerAdded, player)
end
Services.Players.PlayerAdded:Connect(PlayerAdded)
Services.Players.PlayerRemoving:Connect(function(player)
if Profiles[player] then
Profiles[player]:Release()
end
end)
end
local function GetProfile(player)
assert(Profiles[player], string.format("Profile does not exist for %s", player.UserId))
return Profiles[player]
end
function PlayerDataHandler:Get(player, key)
local profile = GetProfile(player)
assert(profile.Data[key], string.format("Data does not exist for key %s", key))
return profile.Data[key]
end
function PlayerDataHandler:Set(player, key, value)
local profile = GetProfile(player)
assert(profile.Data[key], string.format("Data does not exist for key %s", key))
assert(type(profile.Data[key]) == type(value))
profile.Data[key] = value
end
function PlayerDataHandler:Update(player, key, callback)
local profile = GetProfile(player)
local oldData = self:Get(player, key)
local newData = callback(oldData)
self:Set(player, key, newData)
end
return PlayerDataHandler
Script:
local Services = require(game.ReplicatedStorage.Utils.Services).new():GetServices()
local PlayerDataHandler = require(Services.ServerScriptService.PlayerData:WaitForChild("PlayerDataHandler"))
PlayerDataHandler:Init()
Function: (dont work)
RemoteFunctions.GetData.OnServerInvoke = function(player: Player)
local data = -- Function to load
return data
end
You set the profiles as a local table inside of your ProfileHandler module. This means you canât access the profile table from any other script. This is as easy as attaching the profiles table to the module so that you can access it from any other script, or just have an entirely different module that handles all the profiles which is what I prefer.
First method:
PlayerDataHandler.Profiles = {} -- Allowing the table to be viewed from other scripts
Second method:
local ProfileManager = {}
ProfileManager.Profiles = {} -- same thing but separate module
return ProfileManager
RemoteFunctions.GetData.OnServerInvoke = function(player: Player)
local Profiles = PlayerDataHandler.Profiles[player]
local profile = Profiles.Data
if not profile then return end
print(profile)
return profile
end
local data = RemoteFunctions.GetData:InvokeServer(Player)
error: ServerScriptService.Remotes:13: attempt to index nil with âDataâ
local Services = require(game.ReplicatedStorage.Utils.Services).new():GetServices()
local PlayerDataHandler = {}
local dataTemplate = {
Coins = 100,
Rebirths = 0,
Level = 1,
Exp = 0,
Need = 100,
Rasa = "Human",
Location = "Spawn",
}
local ProfileService = require(Services.ServerScriptService.Libs.ProfileService)
local ProfileStore = ProfileService.GetProfileStore(
"PlayerProfile",
dataTemplate
)
PlayerDataHandler.Profiles = {}
local function PlayerAdded(player: Player)
local profile = ProfileStore:LoadProfileAsync("Player"..player.UserId)
if profile then
profile:AddUserId(player.UserId)
profile:Reconcile()
profile:ListenToRelease(function()
PlayerDataHandler.Profiles[player] = nil
player:Kick()
end)
if not player:IsDescendantOf(Services.Players) then
profile:Release()
else
PlayerDataHandler.Profiles[player] = profile
print(profile.Data)
end
else
player:Kick()
end
end
function PlayerDataHandler:Init()
for _, player in Services.Players:GetPlayers() do
task.spawn(PlayerAdded, player)
end
Services.Players.PlayerAdded:Connect(PlayerAdded)
Services.Players.PlayerRemoving:Connect(function(player: Player)
if PlayerDataHandler.Profiles[player] then
PlayerDataHandler.Profiles[player]:Release()
end
end)
end
local function GetProfile(player: Player)
assert(PlayerDataHandler.Profiles[player], string.format("Profile does not exist for %s", player.UserId))
return PlayerDataHandler.Profiles[player]
end
function PlayerDataHandler:Get(player: Player, key: string)
local profile = GetProfile(player)
assert(profile.Data[key], string.format("Data does not exist for key %s", key))
return profile.Data[key]
end
function PlayerDataHandler:Set(player: Player, key: string, value: number)
local profile = GetProfile(player)
assert(profile.Data[key], string.format("Data does not exist for key %s", key))
assert(type(profile.Data[key]) == type(value))
profile.Data[key] = value
end
function PlayerDataHandler:Update(player: Player, key: string, callback: (any) -> any)
local profile = GetProfile(player)
local oldData = self:Get(player, key)
local newData = callback(oldData)
self:Set(player, key, newData)
end
return PlayerDataHandler
RemoteFunctions.GetData.OnServerInvoke = function(player: Player)
local Profiles = PlayerDataHandler.Profiles[player]
print(Profiles)
local profile = Profiles.Data
if not profile then return end
print(profile)
return profile
end
local data = RemoteFunctions.GetData:InvokeServer(Player)
local Services = require(game.ReplicatedStorage.Utils.Services).new():GetServices()
local PlayerDataHandler = require(Services.ServerScriptService.PlayerData:WaitForChild("PlayerDataHandler"))
PlayerDataHandler:Init()
Can you do print checks on your services util to see if they are properly returning because thatâs the only thing that was the only other change I made on my end.