how does the datastore get the value then. the client cant access datastores.
Yes, I was going to edit but I will just reply here.
As I included as an edit, if I needed to send info from the client, it would be done with sanity checks just like every other developer should do.
…
The server get’s it not the client.
using GetAsync()?? datastoreservice:GetAsync() when the game starts. This gets all the data from the previous session.
Then when you buy something from the game the server adds it to a cache table if your not using value objects
This thread has gone on a bit of a tangent.
My approach is to keep data in ModuleScripts, because it means I don’t have to search through directories to get the values I’m looking for (like going through folders to find the value object, to then return the value). This can be harder to manage if you don’t organise it properly - but then again, the same applies to value objects.
You don’t need to use OOP to store data or variables, you can just keep it all in tables or dictionaries. However, a benefit of using object values and updating them on the server is that they automatically replicate. If you want more control over this, then keeping variables in scripts or at least not visible to the client would be the way to go, because then you can fire a RemoteEvent whenever you want and update the value stored on the client.
To cover what has been talked about in this thread, the security is almost exactly the same. Whatever the client can see, they can edit - this means any local variables, any local objects (value objects included). While, yes, you can obfuscate and do all of these methods to make it harder to understand your code for exploiters, it isn’t foolproof and you’d do better to not rely on that. Having a good server-client validation system is the key for security.
Hope this helped. Would advise the other people in this thread to stop derailing it from the original intention of the post. At this point, what you’re talking about it barely helpful to OP and it’s best to be discussed in DMs. Let’s keep this on topic.
The datastore has the value from the previous session saved Using SetAsync() or updateAsync
Are you asking how to get the data when the game starts or in midgame?
Basically when a item is bought add a string value which corresponds to the item name into the folder which saves the players items (IF YOU WANNA DO IT MIDGAME)
And if you wanna see how to have the item bought with proper security and value objects refer to my above posts please.
You should use ValueObjects when you can instead of seeing them as inferior compared to tables. They automatically replicate one-way, so you don’t have to continuously send the client their data in order for them to know they’ve received an update. This eases your remote event load and creates less bloat.
Additionally, use tables for things that need to be represented in a more complex way, such as items on your base, an inventory, etc. Use ValueObjects for more simpler values like Coins or Wins. This is how I approach a question like this.
I do agree that its gone off a bit. I got a bit carried away correcting them.
As for your script. I do like the layout modules have. The issue is security, but like a remote they can be secured. I agree that string is much better.
Im going to leave any public messages from @0Shank now, Should you wish to continue trying to explain how you magically get client script info on the server PM me.
Unless you want to peform methods on your objects (or not have to worry about replication), ValueBases are the best thing here.
Embrace ValueBases, they are the most powerful way to hold simple data, while keeping it nice and serialised in Roblox’s data engine. As well as this, you get automatic one-way replication and Changed events
OOP is only required if you need to have on-board functions in the tables.
Sorry but it seems like you blantly ignored all of my posts.
Let me combine all of them here since you decide to do this:
[Server] Hey Coolshank8 based of the datastore the amount of coins we should start of at is 500. Let me make a value object called Coins set to 500.
[CoolShank] Hey server: I want to buy a weapon the name of it is SilentShard.
Coolshank8 Sneakily changes his amount of coins on the client to 50000 for the value object
Server [Ok let me check how much money you have]
Well you have 500 coins based on my data. Sorry but the siletshard costs 30 thousand coins. So request declined.
Client[Thinking didn’t i change my stats…]
[client rage quits cause his exploit didn’t work]
Server ok so this dude has 500 coins. Lets set the amount of coins in the datastore to 500!
next time client joins
[server] you have 500 coins
In my cases I would only use OOP if making with int values or things like that would confuse me, if its a simple thing then I put those on the server storage and does changes on them from there.
Ive explained it multiple times, if you want me to teach you the basics of client and server communication then message me privately, this is the last public message from me on this topic, Should you wish to continue this conversation then PM.
No i’m not asking to teach me the client and server model. I don’t know where you got that idea from.
I am simply stating that value objects aren’t bad for security.
You shouldn’t be trusting the client. When a server starts, player data is retrieved from a DataStore with :GetAsync(), and kept on the server. When it is time to update a money UI for example, you just send them the amount of money they have, and that’s it. If a player wants to buy an item for example, you compare the amount of money the have based on data on the server, and process the transaction.
Besides, I saw you mentioning the security of your scripts through encryption, that is just bad practice. Exploiters can access anything on the client, so they would see the names of your remotes and fire the remotes themselves as well. “Encrypting” the names of objects or data being passed to the server through a remote does not solve anything, it is literally just security through obscurity. For example, naming remotes with seemingly a bunch of random characters instead of Remote1 just takes a little more time for the exploiter to figure out what the remote is used for. I suggest you to read this very helpful post, which could help you clear any other misunderstandings you may have.
edit: wording
I don’t think client has access to anything server-sided (ServerScriptService, ServerStorage, etc.). If I recall correctly, that was patched a while ago.
I want to give my two cents here, since there seems to be a lot of debate going on and misconceptions being passed around.
Storing information in objects may technically be less secure than storing information in tables, but any security difference here isn’t notable enough to avoid using objects altogether. As others have mentioned, objects actually have their own benefits; if there’s player data that should be easily accessible by the player’s UI, storing that data within ReplicatedStorage would be ideal so long as you’re not relying on the client to manipulate that data.
Storing information within scripts has a time and place, as well. Tables are generally more capable than objects for storing information, and in most situations they’re definitely the better choice to go with. Tables are also a lot more powerful than Instances in almost all regards.
Finally, a couple notes on OOP: It’s been implied here that simply creating a table with information inside it is OOP. This is . . . Maybe technically partially correct? However, when people talk about OOP, creating a table with information isn’t really what comes to mind—rather, OOP usually refers to classes and inheritance, which I’ve barely seen mentioned on this thread. It’s a bit confusing here, as Luau essentially uses tables for OOP, but simply creating a table and putting some numbers in it is object-oriented programming itself—at least not in a way that’s commonly accepted. A table with data and nothing else is just a table.
Yah this is what I mean. As long as you aren’t acutally using the client to set the value of an value object on the server.
In a matter a fact this isn’t just a problem with value objects you should never do this.
The thing I like about tables for storing data is not having that extra deserilization approach with value objects in folders for table like data.
This is why I did a complete overhaul and switched my game for table data. However that doesn’t make value objects less secure.
Even with the table approach if I relied on the client to directly manitpulate the tables it would be a security flaw.
Yep, absolutely. Relying on the client to do anything except for play the game is always a security flaw–even with RemoteFunctions
and RemoteEvents
, it’s critically important to do sanity checks. This always holds true, no matter what the situation is.
I use tables and modules for basically everything–in my current game; there’s exactly (1) actual script in my game, and everything else is module-based; all items, abilities, NPCs, etc. are OOP-based, so I definitely feel you on using tables. That said, I still store a lot of data about the game itself in folders–things like entity/player data, information about the current session–simply because it’s convenient and makes it easier for clients to read the things they should be reading. For example, If their health (represented by an IntValue in ReplicatedStorage) changes, the client can access this change immediately, without the worry of them being able to make changes that replicate back to the server. Nothing has to be called, and there’s still a minimal security risk. It’s nice
OOP is when you bundle functions together. If you’re saving data, I do not recommend the usage of this paradigm. It is expensive, to say the least, but respectively very very useful for select few things.
What specifically are you trying to achieve is the most important question.