Easy Datastore V2 | The easiest DataStore on Roblox

First impressions: AWESOME. The post is well formatted and thought out. Everything is described in a “hype” sort of way, making it extremely appealing. (I would update the logo a bit but whatever lol). Everything is relatable and explained thoroughly. This is a true quality post. Now let’s check out the module…


Upon opening the module in studio and testing it out, there are a few things I notice right off the bat.

Organization

Nothing about the module is what most would consider “standard” coding practice :rofl:, however, if it works, it works.

For V3 I would recommend going through and removing many of the large gaps between functions and sections. It is easier to read makes things less confusing. I do love that the template and config are all in 1 place though.

Integer Methods

Another thing I noticed was a feature to call Module.add, Module.subtract, Module.multiply, etc. when dealing with integer values, however, I see no way that the module actually checks for the value to be an integer. This likely wouldn’t cause huge issues, and it’s entirely possible that I completely missed that section, but upon first impressions of the module it seems confusing.

Documentation

As mentioned above, there are several other features to the module besides just Module.set and Module.get. These are likely useful, otherwise they probably wouldn’t be a part of the module (lol), but there isn’t a place that they are described and explained. Setting up a page dedicated to documentation might be helpful in the future. (Maybe with V3? :slightly_smiling_face: )


I would also like to address some of the concerns already mentioned.

Autosave

(@DasKairo) - While I do agree with the statement (maybe not the sarcasm…), this does seem like a very janky way to create a global loop. Using while loops can be great in certain circumstances, but inside of a ServerScript handling potentially thousands of pieces of data seems like it could be reengineered.

Usage

(@OneEDM) - I also agree (partially) with this statement. Modules like ProfileService have been used and tested in several games, however, none of them started that way. The creators of these modules released them with similar popularity to this module. They relied on other developers over time to test and experiment with their module, which is exactly what the next step is for Easy Datastore.


Conclusions

This module has extreme potential. It is extremely attractive to newer developers because of it’s simplicity and claims to work just as well as ProfileService and DataStoreV2.

Although I have yet to test it against ProfileService, DataStoreV2, and similar DataStore modules, based on what I have played with it does seem to work decently. I see great potential in this project and can’t wait for updates.

I will keep experimenting and testing this module and let you know of any issues I come across.

QUICK EDIT: Change the title of the post to be shorter and more descriptive. Don’t ask a question about your own module, as it makes it seem like you yourself don’t know whether or not it’s better. Maybe something like “Easy Datastore V2 | The easiest DataStore on Roblox”

2 Likes

Thanks for using my module noob compressor for Easy Datastore! I see a lot
of potential in the simplicity this datastore module offers! Let me know if you experience any issues with compression!

1 Like

I am really happy to hear you find the post exciting and well made. I agree with the title and I went ahead and renamed it.

Why I added “extra functions” such as module.add()
I feel as though these extra functions can clarify code that uses the module.

Without module.add() you must do:

local module = require(EasyDatastore2)
local currentCoins = module.get(plr, "coins")
module.set(plr, “coins”, currentCoins+10)

Which can make code confusing and having redundant steps.

With module.add you can just do:

local module = require(EasyDatastore2)
module.add(plr, “coins”, 10)

Which is clear and consise.

Changes I am planning to make:

  • organizing the code

  • locking integer functions (& double) to numbers only, and issuing a warning if they attempt to pass invalid object types.

  • removing spacing in the code

  • adding more comments to explain purposes

  • removing JSON functions (as roblox apparently does that automatically)

  • creating a dedicated page to documentation

Conclusion

Thank you for the feedback and words of affirmation. This feedback has been carefully considered and will be implemented. I’m very exciting to see your results in your testing, as this is exactly what I wanted when making the resource open. My module is very robust and I am excited to see if you can crack it!

1 Like

Everything is working great so far, however, one of your big selling points is being able to seamlessly cross the client-server boundary.

As of now, I don’t see a way to access the module from the client unless it is in a place where the client can access it, which would then cause the module to not function properly and lead to potential security flaws.

I am not sure if I have this set up correctly, so please correct me if I am wrong, but I have placed the module in ServerScriptService, as that is where data would be safest. If this is correct, how can you call Module.get from the client?

I placed my module in the workspace and I’m pretty sure it is safe to do this since:

  • deleting the module on the client side doesn’t stop the server-sided version
  • the module associated with the client side simply calls a remote event. All of the data is managed on the server-side version.

although I am not sure if there is something I am missing or a gap in my knowledge. I don’t think there is a security risk of having a server script in the workspace since the client can’t manipulate it meaningfully. And it doesn’t matter if hackers can see the source code since the source code is open source anyways.

1 Like

also if you intend to use the module and you want to set up a event for when a value is changed (such as displaying coins) you can do this through the attributes.

For example this code changes the value of a coins display everytime its value is updated:

local plr = game.Players.LocalPlayer
local gui = script.parent.textLabel
plr:GetAttributeChangedSignal("coins"):Connect(function()
	gui.Text = plr:GetAttribute("coins")
end)

This will not work on complex data however like tables and dictonaries.

1 Like

Hello I just finished my updates.

Here is the new documentation

I also reformatted the code and added coments.

1 Like

The updates look great! One thing I noticed with the module.clear() function is that you aren’t checking to ensure that the “currencyName” value would be a number.

function EasyDatastore.clear(plr, currencyName)
	EasyDatastore.set(plr, currencyName, 0) -- 'clears' value to 0.
	return 0
end

For example, if I have a template like this:

local template = {
	
	Coins = 10,
	CustomName = ""
	
}

And I call module.clear() and pass in “CustomName”, the module will set my CustomName property to 0, making it a number and not a string.

What you should do (probably) is something like this:

function EasyDatastore.clear(plr, currencyName)
	local currency = EasyDatastore.get(plr, currencyName)
	checkIsNum(currency, "clear()", "currency")
	EasyDatastore.set(plr, currencyName, 0) -- 'clears' value to 0.
	return 0
end

It is pretty much the same idea as you have with the other math functions.

So far everything works really well and am increasingly surprised at the capabilities this module has. I will keep testing it and report back issues or bugs.

Thank you for your time and dedication to this project, as I can see many people using this in the future!

Is there supposed to be an emoji before every Returns new value, or is it just my device that’s not showing it?

There should be an icon there. I don’t know why it wont show up for you.

1 Like

I fixed the emoji to be compatible on all devices. I also corrected some typos and added the module.clear to the documentation.

2 Likes

Dude no one will trust this if you try to say its as good as ProfileService and DataStore2. I was thinking i would try if i was a new dev if the call was only “make it simple” with fewer lines of code as possible, but anyways the module itself does not reflect that call.

  • You said I wouldnt need documentation and you throw me a weird documentation.

  • The examples in this post are not enough to cover how to use the module also, like, i should write the template table ANYWHERE?

  • “No more long documentation! only 2 lines of code” :: fake news

3 Likes

I understand the frustration and lack of clarify I provided. Here is how it works:

  1. You fill out the template table located inside of the easydatastore module.

Here is a chart that expresses the pros and cons of the modules:

1 Like

I’ve updated the documentation and I hope its easier to understand now. Do you understand it better?

1 Like

This isn’t my resource. As other comments have stated though this developer has a mixed track record which I did not look into when making my own comment. My main point is that just because people are familiar with other modules doesn’t immediately mean that this one is inferior. Rereading the OPs original post, they did say it was on-par with other services which cannot be easily proven so it makes more sense why OneEDM said what they said.

Creating modules like this is an up-hill battle especially when most of the community is unwilling, but in fairness why change something that works perfectly for you already? That’s something that needs considered when making a resource like this, I feel like this resource doesn’t add enough to the DataStore module scope to make it more useable over ProfileService.

I apologize for what I originally said about OneEDM, it itself wasn’t nice, but my generalized point of acceptance of a new resource still stands. The OP should also remove points that make it seem like they’re directly on-par with other DataStore modules as it may be misleading.

1 Like

Easy datastore is indeed on par with Datastore2 and ProfileService as it implements many best practices like caching, session locking, etc.

Also you should be wary or making bold, subjective, and ignorant claims such as it “not adding to the datastore scoop.” Easy datastore is a easy to settup, easy, clear, and consise module to code with, and should be considered a serious competitor.

I appreciate your mention that we should consider new modules and I agree. What I want to emphasize with the rest of your feedback though is that it is balant insults and not constructive critism as you are claiming negative aspects of my module without actually proving this.

Its not fair to me as the developer for you to say that my module does not “live up to its apparent better competition” when you have no proof or teating on the module and likely barely used it.

1 Like

Another thing that I would like to mention with ProfileService:

ProfileService is not meant to be super easy to use stand-alone. “It gives you the freedom to write your own data interface”. The idea is that you can use it to create your own system for data saving. The module only manages saving and accessing profiles.

DataStore2 is explained as a “wrapper module”, mostly saving “duplicates of your data”. The big win with ProfileService over DataStore2 is it is able protect against “item duplication exploits” because it is an “extension module”.


All this to say, EasyDatastore is great for smaller games, newer developers, or inexperienced programmers as it manages everything for you. Because the module creates it’s own system for managing data using player attributes, you can easily get attribute changes on the client without any prior setup, as the module updates the attributes every time a value is changed.

Being able to do Module:set() and Module:get() is very similar to how DataStore2 works, where you have setter and getter functions, however, everything is pre-configured, proving EasyDatastore “easier” than setting up DataStore2.


There are still tests to be done with the module, however.

The way that the module works:

  • Does it work similarly to ProfileService or DataStore2 when saving and loading data?

  • Is the client able to change values in the data table?

“Battle testing”:

  • Does the module protect against item duplication exploits?

  • Does the module protect against spam setting/getting (true session-locking)?

  • Does the module protect against failures with getting data (retry functions)?

  • Etc.


There is still lots to be tested against and answered before we can call this module “complete”, however, as it stands right now, it seems to work really well!

I’m pleased to answer any EasyDatastore-related queries, and I appreciate your skepticism.

Limitations: I created EasyDatastore because I considered Datastore2 and ProfileService to be overly challenging due to their departure from conventional modular standards, which has resulted in knowledge gaps about how they now operate.

Simplicity: Simplicity in game development speeds up the process and creates mental space for more new ideas. It promotes teamwork, improves script clarity, and facilitates debugging. However, leaning too heavily on simplicity might result in complacency and overlooking. This raises the question: Does increasing complexity result in more control? While profile services and datastores provide developers with more “control” over the data structures, EasyDatastore retains configurations that can be readily altered within the script as well as direct code manipulation.

Audience: EasyDatastore’s accessibility is not restricted to new developers or small games. Its simplicity and dependability make it suitable for projects of all sizes. EasyDatastore can handle all data types provided by ProfileService and Datastore2, making it ideal for large-scale games. Its easy architecture encourages collaboration among several developers, making it ideal for larger projects with complicated requirements.

Workings: EasyDatastore acts similarly to ProfileService and Datastore, however it is a standalone solution. While it serves the same purpose as data storage services and addresses common concerns such as data corruption and server crashes, it is a unique module. EasyDatastore is reliable and designed for developers of all sizes, having been built on proven best practices and developed through feedback. With the release of EasyDatastore V1, useful insights were obtained, resulting in enhancements such as autosaving and session locking, which improved functionality and usability.

Security: EasyDatastore limits client access to only reading data via the get method, which ensures security. The server still has the power to alter values and access set functions. This setup ensures data integrity and prevents unauthorized changes. Furthermore, session locking reduces item duplication by controlling access to resources during data operations.

Reliability: EasyDatastore protects data through multiple mechanisms:

  • Anti-corruption: Using updateAsync, EasyDatastore ensures that new data does not overwrite existing data, preventing data corruption.

  • Session locking: It inhibits the creation of new sessions while old ones are active, ensuring data integrity throughout transactions.

  • Data recovery during run-time: EasyDatastore uses autosaves to restore the most recent data whenever corruption is discovered, ensuring ongoing functioning.

  • Error handling EasyDatastore handles problems by making several tries to get data. It defaults to retry data retrieval five times, but you can change this in the data script.

  • Meaningful saves: EasyDatastore saves data only when changes are made, avoiding resource utilization and wasteful write operations.


In conclusion, despite the potential limitations of simplicity, EasyDatastore strikes a balance by offering options and allowing direct code changes. Its adaptable data template accepts any data types (excluding objects), which increases flexibility. EasyDatastore’s simplicity promotes clarity and collaboration in programming, making it useful for games of all sizes, from large-scale productions to smaller indie ventures. Overall, EasyDatastore is a wonderful asset for game creation across the board.


Sources:

  • ChatGPT-inspired writing format
  • Grammarly & Quillbot grammar checker
  • Quillbot paraphrase
1 Like

I would agree that the accessibility isn’t limited, I would argue that the use case is limited (slightly). As explained above, it’s pre-configured. All I am saying is that most larger games will likely want to develop their own system of managing data, as it is private, custom, and modifiable. This is not to say that EasyDatastore can’t be used in large production games, it’s just stating the fact that larger game developers may want to rely on a custom data management system with DataStore solutions like ProfileService, letting them manage data however they wish.

Could you link this post? I would like to test the differences of each version, if possible.

This is true, however, I find the Module:get() function on the client useless. Not because it wouldn’t be useful, but because it requires you to store the module in the workspace and because the module automatically creates and updates attributes inside of the player, which the client can access instead of the module. This would also improve security, as the client is unable to access the module at all in this case.

Essentially, in my opinion, I would get rid of client compatibility of the module. The only thing the client should ever need from the module is the player’s data, which is replicated and stored in the player’s attributes anyway. The client can just update client values based on updates to the attribute.

Not entirely sure why you included this lol.

I used the format chatgpt uses as I presume it is based on a significant amount of training data. For example chatgpt uses data from users to improve its capabilities.

I noticed that chatgpt started listing the number of paragraphs above each paragraph so now Im doing that too.

1 Like