hello! i’m new to using profileservice (literally just started using it yesterday) and i’ve hit a bit of a roadblock—my code that fetches the data profile of a player when updating/setting/getting is erroring, saying that the profile doesn’t exist for the player in question. on paper it should work, but i’m not sure where I’m going wrong
ModuleScript code (handles the basic profileservice functions and setup)
ModuleScript
local PlayerDataHandler = {}
local ProfileService = require(game.ServerScriptService.ProfileService)
local Players = game:GetService("Players")
local DataTemplate = {
Cash = 0,
Position = {
X = 0,
Y = 0,
Z = 0
},
Inventory = {}
}
local ProfileStore = ProfileService.GetProfileStore(
"PlayerProfile",
DataTemplate
)
local Profiles = {}
local function onPlayerAdded(player : Player)
local profile = ProfileStore:LoadProfileAsync(`Player_{player.UserId}`) -- Gets the profile of the player who joins
if profile then
profile:AddUserId(player.UserId) -- Adds user ID to profile
profile:Reconcile() -- Adds missing variables from DataTemplate to the profile
profile:ListenToRelease(function()
Profiles[player] = nil -- On :Release(), set the profile of the character to nil
player:Kick()
end)
if not player:IsDescendantOf(Players) then
profile:Release()
else
Profiles[player] = profile
print(`Successfully loaded player {player}'s data`)
print(Profiles[player].Data)
end
else
player:Kick()
end
end
local function onPlayerRemoved(player : Player)
if Profiles[player] then
Profiles[player]:Release()
end
end
function PlayerDataHandler:Init()
for _, player in Players:GetPlayers() do
task.spawn(onPlayerAdded, player)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoved)
end
local function getProfile(player : Player)
assert(Profiles[player], `Profile does not exist for {player.UserId}`)
return Profiles[player]
end
-- Getter/Setter methods
function PlayerDataHandler:GetKey(player : player, key)
-- If there's no data for the corresponding key, throw error
local profile = getProfile(player)
assert(profile.Data[key], `Data does not exist for key {key}`)
return profile.Data[key]
end
function PlayerDataHandler:SetKey(player : player, key, value)
-- If there's no data for the corresponding key, throw error
local profile = getProfile(player)
assert(profile.Data[key], `Data does not exist for key {key}`)
-- If the type of value we want to set does not match the type of the key, throw error
assert(type(profile.Data[key]) == type(value), `New key type does not match type of old key {key}`)
profile.Data[key] = value
end
function PlayerDataHandler:Update(player : player, key, callback)
local profile = getProfile(player)
local oldData = self:GetKey(player, key)
local newData = callback(oldData) -- Gives the old data as a parameter into the callback function
self:SetKey(player, key, newData)
end
return PlayerDataHandler
and here’s the script that’s writing to the data profile, my goal is to save the character’s position when they leave and load it when they join back
PositionSave
local PlayerDataHandler = require(game.ServerScriptService.PlayerDataHandler)
local Players = game:GetService("Players")
PlayerDataHandler:Init()
local function saveCharacterPosition(player : Player)
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart : Part = character:WaitForChild("HumanoidRootPart")
PlayerDataHandler:Update(player, "Position", function(savedPosition)
local newPosition : Vector3 = humanoidRootPart.Position
for coordinate, value in savedPosition do
-- Iterate over every currently saved coordinate and write the corresponding new coordinate's value to it
coordinate[value] = newPosition[coordinate]
end
print(`Saved new position: {newPosition["X"]}, {newPosition["Y"]}, {newPosition["Z"]}`)
return savedPosition
end)
end
local function loadCharacterPosition(player : Player)
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart : Part = character:WaitForChild("HumanoidRootPart")
local savedPosition = PlayerDataHandler:GetKey(player, "Position")
humanoidRootPart.Position = Vector3.new(savedPosition.X, savedPosition.Y, savedPosition.Z)
print(`Loaded player {player} at position {savedPosition}`)
end
Players.PlayerRemoving:Connect(saveCharacterPosition)
Players.PlayerAdded:Connect(loadCharacterPosition)
thanks in advance!