Save your player data with ProfileService! (DataStore Module)

Wanted to use this module, I have some questions though:

  • Is there a readable way of using serialization? For instance, in DataStore2 the saved data can get serialized, but when reading the data its deserialized.

  • Is there anything I would need to do with BindToClose? Or is it done automatically?

  • For replication, would I need to do:

    profile.Data.Coins = 100
    leaderstats.Coins.Value = 100
    

    Or do I need to use some OnUpdate function?

  • Is it advised to ALWAYS Release profiles and ListenToHopReady() before teleporting?

  • Is it safe to use more than 1 profile at once? (for place specific data)

  • Do you still need to perform this check:

    if profile.Data.Cash == nil then
        profile.Data.Cash = 0
    end
    

    …if you use profile:Reconcile()?

ProfileService discourages serialization, especially when DataStore keys have a limit of 4 megabytes.

Check the module source to answer questions like that. Yes - ProfileService does this automatically.

The official ProfileService replication solution combo is ReplicaService. If it’s too advanced for you, then you’ll have to make up your own code that both updates Profile.Data and replicates to clients.

Not using :ListenToHopReady() could only result in slightly longer load times after teleportation. You’ll have to set up teleportation in your game and test it yourself.

Yes. Also ProfileService is NOT going to work for multi-server access at the same time - one profile will only be loaded on one server at a time.

You don’t have to check this if you’re using :Reconcile().

3 Likes

Thank you for the answers!

Also to clear up some confusion, when I said

I meant, is it safe to load more than 1 profile for a single player. The reason for this is that my game uses multiple places, and each one has a small set of data that is only needed in that place.

I dont know if its worth setting up a different profile per place, or just adding a table to the main profile for each place. (given that Im not hitting the datastore limits anytime soon, my current data table includes everything and uses only 2013 characters)

So is doing something like

profile.Data.Coins = 100
player.leaderstats.Coins.Value = profile.Data.Coins

Considered incorrect usage of ProfileService? Or is this completely fine?

1 Like

You can do both of those things you’re talking about. I would personally not exceed 2 profiles per player, though.

3 Likes

question, I might be missing something but does this support deep copying? like if I remove a variable/key in the defaultstats/template it’ll also get removed in the data?

was trying to remove the ‘What’ variable on the default profile template but it seems to not work so i went ahead and used an module that i found that deep copies everything for me
image

See this, @LucasTutoriaisSaimo have already explained it few posts above, hope this helps!

1 Like

Oh, thanks! I thought it had some hidden stuff that does it for me.

How would I go about listing all the profiles (like all saved)? Since I would like to see everyone’s data and ensure that everything is correct.

Something like this:

local profiles = someMagicalFunction()
for _, profile in pairs(profiles) do
    print(profile.Data)
end

Thousands (or millions, for some games) of player data would be too large of a thing to load all at once. The closest thing to what you’re asking for was only released recently, but it’s purpose is still not for things like finding data of all players:

If you can list out the profile keys, then you can load actual profiles themselves via :LoadProfileAsync() by passing in the profile keys.

2 Likes

Same issue, but I would like to erase all data. Creating a new datastore does not solve the issue, because the old one would still be present - and take up memory.

How do you recommend someone access the player profiles across multiple scripts? Using _G? My data manager is in a module so if I wanted to access the profiles I would have to require the module in that script, should I put the profiles table in _G/shared?

It is best practice to make specific functions to edit data than it is having a public-read variable. However, if you really need it, then you can just define Profiles as a variable within the module like this:

module.Profiles = {}

My DataManager manages all data and will probably be very long, my thought process was that if I require this long module in another script just to use a simple table of profiles that it contains seemed very unnecessary because I would be requiring the whole module when I just needed to access the Profiles table.

Hi, currently running into an issue with ProfileService!

This is my code. In this case, player is Player_-1 and tier is equal to 1.

    print(Profiles)
    local profile = Profiles[player]
    profile.Data.SubTiers[tier] += 1
    print(Profiles)

When I print Profiles the first time, this is the data section that is outputted.
BUG1

When I print it the second time, the value has gone up as desired! The problem is, for some reason all other players in the game are also having the same value replicated, and I’m having a real headache working out why this is replicating, as I have made sure that this code is only being ran once and only for one profile.

BUG2

Any advice would be greatly appreciated :slight_smile:

4 Likes

A) You’ve set the same profile reference to multiple players
B) You’ve set the same member “SubTiers” table reference to multiple profiles - in this case you need to deepcopy before setting a template table to a new profile.

3 Likes

I completely forgot that tables are done by reference by default in lua… xD Thank you so much! This caused me such a headache.

Whenever I join, it kicks me because of ListenToRelease. This is happening every time. How do I fix this?

Hello, first I have to say I love this resource, it makes working with datastores so much simpler!

Question though, I was wondering how to properly erase the data of a specified profile. I’ve investigated ProfileStore:WipeProfileAsync(profileKey), but it only seems to work on already released profiles. Does clearing the Profile.Data table suffice (and then later calling Profile:Reconcile to fill it with the default values again), or should I be using a different method?

Yeah! :WipeProfileAsync() was made solely for GDPR compliance. To restart active profiles you can either grab them remotely with :LoadProfileAsync() or set them to an empty table and optionally reconcile on the server that currently owns the profile.

If you’re in the development testing phase, you could just change your ProfileStore name which will restart data for everyone.

3 Likes

Or use DataStore Editor from sleitnick - where you can edit,download and delete data. It costs robux but it is definitely worth buying.

1 Like