Thanks for the reply, and that’s the answer I expected really. Nevertheless, I really like the idea of this module, and am seriously considering using it in my game.
I’ve been somewhat iffy about steering away from other DataStore implementations that aren’t DataStore2, but I think I’m sold. The biggest gripe I’ve had about DataStore2 is that I can’t use Merely’s SoftShutdownService, which this implementation is very good at. Most have struggled to steer me away from it due to the fact that they usually have “warnings”, but loleris being the great salesman he is, definitely convinced me otherwise. The documentation explains the myths and misconceptions about a system like this perfectly. I’m definitely going to migrate my DataStores to ProfileService, and you should too.
Hey, this is absolutely fantastic! I have been using it for a while. Great work.
I have 2 questions though
- Is there any way to wipe data besides changing the key?
- How many values can I store in the ProfileTemplate array before it’s too much?
Thanks for the help.
When there are datastore outages (like today) and you go to retrieve the profile. Will it be returned as nil?
I don’t know about live games, but during the outages, it gave me HTTP 500 warnings (IIRC) from ProfileService in Studio. I assume it then kept attempting to load, since after I waited for awhile, it loaded my data.
In conclusion: ProfileService is reliable.
The only time you should have issues is if Roblox accidentally gives you nil when there’s valid data stored somewhere. Many Roblox games experienced this issue a couple of years back for a day or so. That kind of thing is out of the control of anyone.
It will yield indefinetly until a profile is loaded. nil
is returned for other kinds of rare exceptions after which you should kick the player.
How do you use WipeProfileAsync?
So previously I wrote an interface to serialize/deserialize my data to Folders and ValueBases, and to update their keys in their respective tables in Profile.Data
as the ValueBases are updated. Now I realize instead of trying to update Profile.Data
as my ValueBases change, I can just serialize everything once when their profile is released like so:
profile:ListenToRelease(function()
local data = leaderstatsToTable(player.PlayerData)
profile.Data = data
profileCache[player] = nil
player:Kick()
end)
So my question is, serialization is a valid use of ListenToRelease, right? The first time I read this documentation:
After
Profile:ListenToRelease()
is triggered, it is too late to changeProfile.Data
for the final time. As long as the profile is active (Profile:IsActive()
==true
), you should store all profile related data immediately after it becomes available. An item trading operation between two profiles must happen without any yielding after it is confirmed that both profiles are active.
I was confused on whether I was allowed to modify Profile.Data
in ListenToRelease
.
Also, in the first line of ListenToRelease
I printed Profile:IsActive()
and it printed false. So, as per the IsActive
documentation:
Returns
true
while the profile is session-locked and saving of changes toProfile.Data
is guaranteed.
This worries me further that I’m doing something wrong. Am I allowed to serialize data in ListenToRelease
?
You’re not allowed to - profile release can happen unexpectedly, issued by another server - that’s why :ListenToRelease can’t be used for final saving.
ProfileService forces you to keep your data saved in a form that, in case the server crashes or some other problem occurs, will protect player’s data with minimal data loss.
Presumably there are no issues with ProfileService in the event of an outage like DataStore2 experienced, where data became out of sync due to OrderDataStores not being affected by the recent issue?
When Roblox performs a rollback, is player data just reverted to whatever version they restored to?
https://devforum.roblox.com/t/datastores-incident-report/829962/1
Yup. ProfileService uses one key per profile, so it’s going to be compatible with Roblox’s own versioning systems.
Didn’t get any reports so far for data loss with ProfileService.
hi, first off, I love your module! It is very intuitive and well made. Secondly, is there a way to detect changes to certain values such as a .Changed equivalent?
Since ProfileService is not a change signal provider, you’ll either need to create your own get / set interface or simply update Profile.Data when your value object triggers .Changed
Wow! You’ve successfully sold this to me (thanks for making it Open Source by the way)! I’ve used DataStore2 for a while, and as it seems that Ordered Backups are soon no longer going to be necessary whenever the new API changes happen. This is part of my reasoning behind switching to ProfileService. Most of the things DataStore2 offers that ProfileService has I am fine writing by myself and would prefer to do that anyways (serialization, etc).
My only question is about detecting issues with Roblox’s datastores. DataStore2 has :IsBackup() which appears to work in most cases (but not in the last incident it seems). This just means that the current store is a temporary one and does not save at all to prevent issues. How does ProfileService specifically react to datastore saving issues like the recent one (does it return nil, etc), and is there anything else you would recommend for handling events like this (especially with regard to Robux purchases)?
Thanks!
ProfileService basically IS the module that handles DataStore issues, given the developer has properly understood the documentation for the module.
Developer product purachase callbacks should be confirmed only when you know the player data has been saved - this can be done by utilizing Profile.MetaData.MetaTags
and Profile.MetaData.MetaTagsLatest
- see documentation for more info about them.
Ah. Thanks for the specifics on MetaTags. From how I understand it, if the datastore itself fails to load, the profile will return nil. DataStore2 allows you to set a max number of tries and specifically informs you if it cannot load the data. From my understanding, ProfileService returns nil and to notify players of issues I should use the critical state signal.
If for some reason datastores are completely failing and ProfileService cannot access saved profile information, it would simply return nil. Please correct me if I am wrong.
However, you listed Kicking the player as the best option for when :LoadProfileAsync() returns nil. If datastores are down, wouldn’t the players automatically get kicked upon joining the server?
The specific case that I am seeking to answer is about notifying players that their data is having issues saving and loading, and notifying them when they join (and letting them join) instead of kicking them.
How would I go about doing this, and do I understand this fully or is there something I am missing?
P.S. Thanks for the quick reply on purchases. You have been very helpful.
EDIT: It seems that it will load indefinitely. I apologize for not seeing that you already answered my question. I will be building this eventuality into my handler. Thanks again for the module!
Quick question: does ProfileService encrypt data, and if not, would this be something worth doing myself? I saw something else do it a while back and am wondering if it would be something I would want to do.
Do you mean encrypting or encoding? Encrypting shouldn’t be necessary because you shouldn’t be storing confidential information about players in DataStores. Encoding also shouldn’t be necessary since the character limit is around 4 million now, and even a good building system would have trouble reaching that.