Save your player data with ProfileService! (DataStore Module)

Hello! i was wondering what is wrong with my script? im trying to save the givewarn function but nothing is working.

The datamanager

local Players = game:GetService("Players")
local ProfileService = require(game.ReplicatedStorage.ProfileService)
local BindableEvent = game.ReplicatedStorage:WaitForChild("RemoteEvents"):WaitForChild("SaidBadWord")

local ProfileStore = ProfileService.GetProfileStore(
    "Player",
    {
        Warnings = 0;
        Timemute = 0;
    }
)

local Profiles = {}
local function GiveWarn(player, amount)
    print("Working")
    local data = Profiles[player]
    if data ~= nil then
        player.Values.Warnings.Value = player.Values.Warnings.Value + 1
    else print(player .. ' was not found.') end
end


local function onPlayerAdded(player)
    local profile = ProfileStore:LoadProfileAsync(
        "Player_"..player.UserId,
        "ForceLoad"
    )

    if profile then
        profile:ListenToRelease(function()
            Profiles[player] = nil
            player:Kick()
        end)
        if player:IsDescendantOf(Players) then
            Profiles[player] = profile
            GiveWarn()    
        else
            profile:Release()
        end
    else
        player:Kick()
    end
end



local function onPlayerRemoving(player)
    local profile = Profiles[player]
    if profile then
        profile:Release()
    end
end

Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoving)
BindableEvent.Event:Connect(GiveWarn(1))

local DataManager = {}

function DataManager:Get(player)
    local profile = Profiles[player]
    if Profiles[player] then
        return profile.Data
    end
end


return DataManager

My output

 10:55:40.828  [ProfileService]: Roblox API services available - data will be saved  -  Server - ProfileService:2307
  10:55:41.280  Working  -  Server - DataManager:16
  10:55:41.280  ReplicatedStorage.DataManager:20: attempt to concatenate nil with string

The else line here will error if player is nil because you can’t concatenate a nil value with a string so I recommend replacing the print function with this

print("data was not found.")

Then, you run the GiveWarn function argument without passing any arguments, causing an error on the print function as i said earlier

1 Like

Hi! it fixed my errors but now im having a issue by it not saving the value

You should update the code sample:

for _, player in ipairs(Players:GetPlayers()) do
    coroutine.wrap(PlayerAdded)(player)
end

for _, player in ipairs(Players:GetPlayers()) do
    task.spawn(PlayerAdded, player)
end
2 Likes

probably because you dont set the actual data

Hello is there any use of session lock on trade but not cross server only on 2 players trading on same server
Example : trade

Been playing around with Global Updates.

Having a strange issue where sometimes the updates just get lost in thin air – I’d send an update to an alt account, get the alt account to join and leave the game to test, and the update just never gets registered.

Not sure if this is a bug or not, but I’m also positive I’m implementing it the way it’s supposed to be implemented.

Edit: Realized the global update could be getting resolved whilst the alt is not in game (is this possible?)

Hello there!
I’m trying out this module and using the “Basic code example” and i just changed some printings and names, and put an return Profiles at the end.
Now, i tried setting a leaderstats value to Profiles[player].Data.Money but even though studio detects it exists, when i try testing it it says: Tried to index nil with Data.

local Profiles = require(game.ServerScriptService.EpikProfileManager) --Profiles is the table where i store the profile lol

game:GetService("Players").PlayerAdded:Connect(player)
local leaderstats = Instance.new("Folder")
leaderstats.Parent = player
leaderstats.Name = "leaderstats"

local Money = Instance.new("IntValue")
Money.Parent = leaderstats
Money.Name = "Money"
Money.Value = Profiles[player].Data.Money --This is the error line. Tried to index nil with Data?

I would be grateful if anyone told me why this isn’t working.
PD: I tried getting help in a Scripting Support topic but nobody helped :skull:

erm… can someone explain it all in a simple way for me? I’m new to scripting so I don’t understand much…



I’m getting an error when I put in “Repeat” as my NRH. Are ForceLoad and Steal the only handlers now or just a mistake?

1 Like

Put very simply, ProfileService is a module that you use for saving player data. Some benefits of it are that you can have session locking (presumably to prevent item duplication and other things I believe), and DS2 support. (Backups/versioning in case your players lose their data / have issues with data).

If you’re new to scripting, I suggest checking out this playlist by AlvinBlox on how to code. You can watch this video for a tutorial on how to use ProfileService.

1 Like

Is it possible to make a global leaderboard?

ProfileService doesn’t have ordered datastores.

What you can do however, is save the player’s ProfileService Data to a seperate OrderedDataStore.

1 Like

Hey, I used one of y’alls samples and the listentorelease is kicking the player. I’m new to ProfileService, what does this mean?

function metaData:add(player, tester)
    local profile = profileservice:LoadProfileAsync("Player_" .. player.UserId)
	if profile ~= nil then
		profile:AddUserId(player.UserId);
		profile:Reconcile()
		profile:ListenToRelease(function()
			player:Kick("listentorelease")
		end)
		if player:IsDescendantOf(game.Players) then
			data[player] = profile;
		else
			profile:Release();
		end
	else
		player:Kick("not nil")
	end
	
	return data[player].Data;
end```

Whats the maximum load time when NOT using :ListenToHopReady()? Im considering sacrificing faster load times for teleport failure handling.

Before teleporting, you release the profile and call :ListenToHopReady(), and then teleport. But if the teleport fails, you are stuck with a released profile. Loading the profile again after every teleport failure doesnt seem like a good idea.

So I wanted to just remove the part where the profile gets released and listens to hop ready, and just teleport immediately, leaving the PlayerRemoved connection to release the profile.

Why not just making it retry the teleport if the teleport fails?

I guess thats a good point, but I dont think its that simple.

I didnt mention it in my original reply, but my game has a server list, so you can pick which server you want to join. What if the server is full and you try to join? It would just keep infinitely retrying. Or what if the server shuts down by the time you try to join it?

So Ive done some testing.

I removed the :ListenToHopReady(), removed the part that released the profile before teleporting, and set the profile data to random numbers while it was active.

When teleporting, it took no longer than 3 seconds to load the profile, and it seems to load your data correctly as well.

So it seems like this is safe to do, but I dont know what would happen on a larger scale though, with more players.

Is it alright if I save their data into their profile table right when they leave? This might be unreliable or whatever but it worked perfect when my game peaked 2k players and now when I average around 500-600.

Still waiting on any type of support to this since it’s stated profileservice could be a guild profile manager.