Didn’t this guy like make 2 really bad community resources and have a very bad past?
but hey if this one is good then maybe this is the comeback of the century?
Didn’t this guy like make 2 really bad community resources and have a very bad past?
but hey if this one is good then maybe this is the comeback of the century?
Thanks for the feedback, I’m glad you find this post a good resource
Okay, a couple changes I would like to propose.
Client Folder:
Just remove it. There is no point in having a Module.get()
function on the client. It would be way easier to just do this, as the module already updates the player attributes:
player:GetAttributeChangedSignal(attributeName):Connect(function()
local value = player:GetAttribute(attributeName)
end)
Noob Compressor?
First of all, what a terrible name. Second, what does it even do? I get that it “compresses data”, but for what purpose? After editing the “EasyDatastore” module and removing the “noobCompressor” module, everything still works fine.
Seperate Autosave Script:
Why not just combine the autosave feature into the module? Also, I would recommend you use a RunService.Heartbeat
function instead of while true do
. This is more efficient and allows for other tasks to be ran in the module.
This leaves me with my last proposal:
Module Name:
Because it looks better, I would recommend changing the name to “EasyDatastore” or “EasyDatastore2”, with a capital E.
All of the above changes leave you with a standalone module. No children in sight!
I have gone ahead and made all of these changes myself.
I commented out any mentions of “noobCompressor” and adjusted the function to use the default data instead of the encoded/decoded/compressed data (I am not really sure what it did lol).
I removed any mention of the “get” event and altered the script to run on the server.
Combined the “autosave” script with the module at the bottom, changing the while true do
loop to a RunService.Heartbeat
function and calling any necesary functions. I then changed the module functions that deal with autosaving data to regular script functions, which will clean up the user experience when calling events with the module. I also adjusted the way that the the autosave function works. Before, the “autosave” script would only save a single player’s data every minute. This means that it would take 10 minutes to autosave everyone’s data once if there were 10 people in the game. I instead changed the function to loop through every player in the game and save everyone’s data every minute (or whatever the save frequency is set to).
Finally, I adjusted the name to have a capital E and placed it in ServerScriptService
, as it is far more secure there.
EDIT: Another thing I noticed with the documentation:
You shouldn’t require the module EVERY TIME a new player joins. You should instead require it once on the server and then manage it from there.
local EasyDatastore = require(ServerScriptService.EasyDatastore2)
Players.PlayerAdded:Connect(function(player)
local coins = EasyDatastore.set(player, "Coins", 10)
print(coins) -- 10
end)
EDIT-EDIT: Yet another thing:
The Module.subtract()
function does not check to ensure that the value will not result in a negative number.
What I would do is create a bool
parameter in the Module.subtract()
function called “canBeNegative” or something similar. If this is true, then don’t check if the value will result in a negative value, however, if it is false, check to make sure that the final updated value is not going to be negative.
function checkNegative(plr: Player, currencyName: string, amount: number): boolean
local currency = serverPlayersData[plr.UserId][currencyName]
if currency - amount < 0 then
return false
else
return true
end
end
function EasyDatastore.subtract(plr: Player, currencyName: string, amount: number, canBeNegative: boolean): number
local currency = EasyDatastore.get(plr, currencyName)
checkIsNum(currency, "subtract()", "currencyName")
checkIsNum(amount, "subtract()", "amount")
local negative = checkNegative(plr, currencyName, amount)
if canBeNegative or not negative then
return EasyDatastore.set(plr, currencyName, currency-amount)
else
return EasyDatastore.get(plr, currencyName)
end
end
EDIT-EDIT-EDIT: Types…
I noticed that with all of your functions you are not including types next to the parameters.
Doing this:
function Function(value: number, value2: string, value3: boolean): number
As opposed to this:
function Function(value, value2, value3)
Makes it a lot easier to understand what parameters to give functions, especially module functions.
Right now this is what the module shows when I call a function and pass in parameters:
If we add types to these parameters it suddenly becomes a lot more clear what should be passed in:
Here is the module with my applied edits:
EasyDatastore2.lua (13.3 KB)
Modules only run the code inside when its required. I want the autosave to run constantly even if its never required. For this reason I put it inside of a seperate script.
Noob compressor compressed the data to free up space in the datastores
Sure ill remove module.get()
Sure ill change the name
Sure ill change it
Sure ill change this
Some people might not want it to stop at 0.
Sure ill change this
It’s much safer using Profileservice with an easy wrapper on top of it than using this datastore at the current state. Especially for the “smart” features that completely lacks compared to Profileservice and datastore2, especially regarding safety of the data and session locking. If possible, please revise them to ensure effective safety for the people who use this in their game.
Thank you for the feedback on easydatastore. I hear you mention that EasyDatastore lacks in the fields of autosaving, session locking, and data security. If you could specify in which ways I can improve the current version, that would be most helpful. To clarify, how it currently works:
autosaving: Every 60 seconds, at spaced intervals (determined by currentPlayers/60), autosave the data if the user has made changes since the last autosave.
session locking: When a user joims the game, check if a session is already active. If it is, kick the player and delete the session. If its not, create a new session. When the user leaves the game delete the session with the final save.
data security.: The client can only access module.get(), but cannot affect any of the data. module.get() is needed to pass larger peices of data such as entire tables and dictionaires to the client. All module.get() does is ping a remote function for the server sided version of the module.
To my current understanding, these practices have been implemented effectively. If you have any feedback on how to improve them speficially, or the differing ways in which other modules manage these funcitonalities, I’d love to hear!
Do you still work on Furry Detector 2.0? If so, I think this would be a great fit to streamline your data storage paradigm.
Jokes aside, I’d recommend anyone reading check out other data modules. Dealing with player data can be finnicky and have serious consequences if mishandled. This isn’t an issue about this module being worse than the rest, but rather that when dealing with data storage you need to be confident that the code you’re relying on is robust and thoroughly tested. Considering how a significant portion of the 45 replies in this thread are about code malpractices and false claims made about the quality of this module, I think it’s worth looking into other options.
Aside from the popularly known DataStore2 by Kampfkarren and ProfileService by loleris, there are many options for DataStoreService wrappers that may give you more confidence that your data is being handled properly. One I’ve had my eye on recently is lapis by nezuo but I’d also strongly recommend looking through both the guide and related example code for the datastore wrapper you can find on the Roblox documentation.
If you’d like to seek out other modules aside from the ones I’ve listed, I recommend using the search terms “DataStore Wrapper” and “DataStore Module” here on the devforum to find a wide variety of different (and less controversial) data solutions.
I understand that it can be difficult to have confidence in new modules, but if you ignore EasyDatastore for that alone, you may be missing out!
@GRIMNO1RE I understand the serious nature of data management, and I also understand that confidence is key in such situations. I want to assert, however, that you should give EasyDatastore an opportunity. It has numerous valuable benefits for datastore collection.
Alternative modules such as Datastore2 and ProfileService are indeed excellent modules; however, there are also some considerations. EasyDatastore has the benefit of simplicity, which allows cleaner and more efficient code. Furthermore, the learning curve of both Datastore2 and ProfileService is generally higher. While there is the added benefit of more control over data, EasyDatastore is still designed to be highly scalable and reliable, competing with these known modules.
Despite its “easy” nature, EasyDatastore can be an excellent addition to complex, small, and even big games. In bigger games, teams can collaborate more effectively with a simpler data store library. It frees up space for bigger ideas and makes even those knowledgeable about datastores understand the functionality. Furthermore, the abstracted nature practically eliminates developer error. In modules like ProfileService that require lots of manual configuration, even small mistakes can make big differences in data integrity.
As you mentioned,
This can cause frustration and confusion among developers using more complex solutions. Furthermore, simplicity can speed development, clear up code, and make collaboration easier. For these reasons, I strongly believe EasyDatastore can be a valuable addition to the market.
As for my expertise, I have analyzed and learned about numerous best practices. I have implemented a variety of elements to ensure that data is managed reliably and that you can be confident in using EasyDatastore. However, like all things, there may still be mistakes. But this doesn’t mean we should completely abandon EasyDatastore. And with the acknowledgment of these mistakes, I still want to emphasize that EasyDatastore has been heavily tested.
EasyDatastore has undergone various forms of testing and is quite reliable. While the replies in the post can give the sense that there are constant issues, this is simply not true. Many of these replies are suggestions to further improve clarity for new developers and optimize the functionality. However, it’s important to acknowledge that this is a natural part of the growth of new modules.
So I encourage you to embrace EasyDatastore. Everything must start somewhere. Give it a chance! I’m excited to see where this project goes, and I hope you do too!
How do I access the table in my template and add a string to it?
You can access a table in the template with
Plr: The player model located in game.Players
“Name”: The name of your table
You can add a string to the table with
String: Whatever string value you want to change it to.
that doenst work either I tried that and it says argument #1 expects a string, but table was passed
If you are using module.get() you cannot pass a table but the string reference to the table.
For example if you set up your template as
Local template = {
[“MyTable”] = {}
}
You would do
Module.get(Plr, “MyTable”)
Not
Module.get(Plr, {})