so basically, I’m making an obby game. Mainly the issue is when you spawn in, it’ll not load the data in time it seems , and with that issue, comes the issue of randomly spawning the character in a different place in the obby periodically e.g here’s the script
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function()
task.wait()
local Data = DataService:GetPlayerData(player)
if Data then
print("no lols")
player.RespawnLocation = workspace.Checkpoints[Data.Levels]
elseif not Data then
print("lols")
player.RespawnLocation = workspace.Checkpoints["0"]
end
Players.RespawnTime = 0.1
end)
end)
Here’s the issue in video format
Also, it indeed did print “lol”
Now, I want to list some things I believe might also be the issue, but my brain has yet to come up with a solution with-
The main issue seems to be that the script in the module is running slower than the one in the server (this is an assumption). So, it never does what it needs to do in time which makes the data load slower and, boom the server runs without allowing the module script to work before it. (edited)
I think this boils down to trying to set the respawn location using the character added event. Surely you need to set the respawn location before the character is loaded so using character added is too late.
You could simply set the respawn location in the player added event and then update the respawn location whenever the data changes rather than waiting for the character event.
The difference now is that I keep getting set to the first spawn point (which was the goal if you didn’t have any data, so it’s a step forward), but the issue still stands in which the character does have data, but I believe the module script is moving slower than the server script, and I don’t really know how to delay it until the data is loaded.
If you want ultimate control of the respawn mechanics then you can turn Players.CharacterAutoLoads to false. You would then need to call Player:LoadCharacter() for any spawning behaviour to happen but this would allow you to wait for whatever you want before a player spawns / respawns.
There is also the situation where the character loads before the player added event finishes running (not sure if this is possible but lets assume it is). In this case you would need to use SetPrimaryPartCFrame when the player first joins the server.
The main issue still stands, the data seems to be loading/working slower than the server script. I’ll show you the module script, but at this point I sincerely don’t know what to do, or if I have to make a retry function (which I don’t know how to do, but I’ll attempt it).
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local ProfileService = require(ServerStorage:WaitForChild("Modules"):FindFirstChild("ProfileService"))
local ProfileTemplate = {
Levels = 0,
Deaths = 0,
}
local GameProfileStore = ProfileService.GetProfileStore("Player", ProfileTemplate)
local Profiles = {} -- All player profiles that are stored.
local function onPlayerAdded(player)
local ProfileStore = GameProfileStore:LoadProfileAsync(
"Player_" .. player.UserId,
"ForceLoad"
)
if ProfileStore then
ProfileStore:ListenToRelease(function()
Profiles[player] = nil
player:Kick("How are you still in game?")
end)
if player:IsDescendantOf(Players) then
Profiles[player] = ProfileStore
else
ProfileStore:Release()
end
else
player:Kick()
end
end
local function OnPlayerRemoving(player)
local Profile = Profiles[player]
if Profile then
Profile:Release()
end
end
game.Players.PlayerAdded:Connect(function(player)
onPlayerAdded(player)
end)
game.Players.PlayerRemoving:Connect(function(player)
OnPlayerRemoving(player)
end)
I attempted these suggestions,
now giving me errors
local function onPlayerAdded(player)
Players.CharacterAutoLoads = false
local ProfileStore = GameProfileStore:LoadProfileAsync(
"Player_" .. player.UserId,
"ForceLoad"
)
if ProfileStore then
player.RespawnLocation = workspace.Checkpoints[Profiles[player].Data.Levels]
player:LoadCharacter()
ProfileStore:ListenToRelease(function()
Profiles[player] = nil
player:Kick("How are you still in game?")
end)
if player:IsDescendantOf(Players) then
Profiles[player] = ProfileStore
else
ProfileStore:Release()
end
else
player:Kick()
end
end
local function OnPlayerRemoving(player)
local Profile = Profiles[player]
if Profile then
Profile:Release()
end
end
game.Players.PlayerAdded:Connect(function(player)
onPlayerAdded(player)
end)
game.Players.PlayerRemoving:Connect(function(player)
OnPlayerRemoving(player)
end)
for _, Checkpoints in pairs(workspace.Checkpoints:GetChildren()) do
Checkpoints.Touched:Connect(function(Hit)
if Hit and Hit.Parent:FindFirstChild("Humanoid") then
local player = Players:GetPlayerFromCharacter(Hit.Parent)
player.RespawnLocation = Checkpoints.Parent[Profiles[player].Data.Levels]
if tonumber(Checkpoints.Name) == Profiles[player].Data.Levels + 1 then
print(Profiles[player].Data.Levels)
Profiles[player].Data.Levels += 1
end
end
end)
end
It’s just getting confusing. I understand what you want me to do, but it’s not working out for me.
You seem to be doing things in the wrong order that’s why you get this error. You need to initialise the profile cache (Profiles[player] = ProfileStore) before you try reading from it to set the respawn location.
I’ve written in some tweaks that I think should fix things.
Code Tweaks
local RESPAWN_TIME = 10
local GameProfileStore -- add reference here
local Profiles = {}
game.Players.CharacterAutoLoads = false
local function spawnPlayer(player)
local Profile = Profiles[player]
if not Profile then
warn("No profile for player", player)
return
end
player.RespawnLocation = workspace.Checkpoints[Profile.Data.Levels]
player:LoadCharacter()
end
local function onCharacterAdded(player, character)
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
wait(RESPAWN_TIME)
spawnPlayer(player)
end)
end
local function onPlayerAdded(player)
local Profile = GameProfileStore:LoadProfileAsync(
"Player_" .. player.UserId,
"ForceLoad"
)
if not Profile then
player:Kick()
end
Profile:ListenToRelease(function()
Profiles[player] = nil
player:Kick("Profile released...")
end)
if player:IsDescendantOf(game.Players) then
Profiles[player] = Profile
else
Profile:Release()
end
player.CharacterAdded:Connect(function(character)
onCharacterAdded(player, character)
end)
if player.Character then
onCharacterAdded(player, player.Character)
end
spawnPlayer(player)
end
local function OnPlayerRemoving(player)
local Profile = Profiles[player]
if Profile then
Profile:Release()
end
end
game.Players.PlayerAdded:Connect(function(player)
onPlayerAdded(player)
end)
for _, player in game.Players:GetPlayers() do
onPlayerAdded(player)
end
game.Players.PlayerRemoving:Connect(function(player)
OnPlayerRemoving(player)
end)
for _, Checkpoints in pairs(workspace.Checkpoints:GetChildren()) do
Checkpoints.Touched:Connect(function(Hit)
if Hit and Hit.Parent:FindFirstChild("Humanoid") then
local player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if not player then
return
end
local Profile = Profiles[player]
player.RespawnLocation = Checkpoints.Parent[Profile .Data.Levels]
if tonumber(Checkpoints.Name) == Profile.Data.Levels + 1 then
print(Profile.Data.Levels)
Profile.Data.Levels += 1
end
end
end)
end