ProfileService making player unable to rejoin quickly

I’m currently using ProfileService to save data in a test place, and players are unable to rejoin the game quickly without being kicked by my ProfileService manager module.

Code:


Which point in the code is causing the kick? There are a number of kick statements in there.
You could also try wrapping your profileloadasync in a pcall and repeat to ensure it is fetching the profile.

Ok, so the profile service still uses the regular datastore (just provides some fancy functions/shortcuts for you to use). The only way the two servers can talk to each other to know whether the profile has been loaded elsewhere is to change something on the datastore for the other one to pick up. When saving data it can take a few seconds to update, so if a player is rejoining very rapidly the server they are joining may be picking up old data, where the profile hasn’t been released.
The plr:IsDescendantOf(Players) will return false because the previous line has just kicked them.

profile:ListenToRelease(function()
			Profiles[plr] = nil
print("Profile was released")
			plr:Kick()
		end)
		if plr:IsDescendantOf(Players) then
			Profiles[plr] = profile
		else
			profile:Release()
		end
		profile:Reconcile()

In theory the forceload should allow the server to pick up the info regardless and thus not activate the listen to release function. But I could be wrong, that module is pretty big to read through!
I think adding something like a task.wait(2) when the player joins before running the profile:ListenToRelease() could be sufficient.
See also:

If the player rejoins the game quickly, their data in the old server is still active and ends up getting used in the new server. ProfileService releases the data from the old server, which also indicates to the new server that the data loaded is out dated.

You must kick the player if they have out dated data because that is a way that players duplicate items through trading, quickly leaving and rejoining.

This is intentional and should stay as is.

1 Like

I think @inoobe_xi explains why it’s a bad idea, but it depends on your game, as it might not be a problem.
You could place the listen to release into a repeat until attempt==3 loop before kicking them, to reduce the likelihood of a kick although this would still require task.wait(x) to avoid too many calls to datastore too rapidly.

This is most likely why. Your code in the :Get() function only checks once for the players profile, and doesn’t wait for it to be loaded.

Their documentation suggests doing something along the lines of this:

local profile = Profiles[player]

while not profile and player:IsDescendantOf(Players) do
   profile = Profiles[player]
end

return profile

Here. Go down to the GetPlayerProfileAsync function. As I said, the reason your Get() function is returning no profile is likely because you’re calling it before the profile can be loaded. Doing the code I gave you will wait until the profile has loaded then return it, if the player is still in game.

1 Like

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