For example, instead of directly adding the button to the DataStore like what you did here:
if v:IsA("GuiButton") then
table.insert(v)
end
You can do something like this:
if v:IsA("GuiButton") then
local ButtonTable = {}
table.insert(ButtonTable, v.Name)
table.insert(ButtonTable, v.Text)
--etc.. Instead replace with the properties you need to store inside the table. Store the table inside the DataStore btw.
end
Hmmm, oh and i forgot to say, i’m not that good in datastores, like i know just how to store values and that’s it, i even needed to watch a tutorial, so uhhhh, i need to learn more about datastores…
Yes, I was like you and I personally hate datastores honestly.
You must also take things like security and multiserver editting cuz you never want to lose player data right?
I recommend instead of you making datastores look into something like a external module (ProfileService, DataStore v2). There are multiple tutorials on this and I use something like this with ProfileService:
Look into those and also look into methods of serialization. Just searching it up will bring tons of videos and forums!
-- ProfileTemplate table is what empty profiles will default to.
-- Updating the template will not include missing template values
-- in existing player profiles!
local ProfileTemplate = {
Cash = 0,
Items = {},
LogInTimes = 0,
}
----- Loaded Modules -----
local ProfileService = require(game.ServerScriptService.ProfileService)
----- Private Variables -----
local Players = game:GetService("Players")
local ProfileStore = ProfileService.GetProfileStore(
"PlayerData",
ProfileTemplate
)
local Profiles = {} -- [player] = profile
----- Private Functions -----
local function GiveCash(profile, amount)
-- If "Cash" was not defined in the ProfileTemplate at game launch,
-- you will have to perform the following:
if profile.Data.Cash == nil then
profile.Data.Cash = 0
end
-- Increment the "Cash" value:
profile.Data.Cash = profile.Data.Cash + amount
end
local function DoSomethingWithALoadedProfile(player, profile)
profile.Data.LogInTimes = profile.Data.LogInTimes + 1
print(player.Name .. " has logged in " .. tostring(profile.Data.LogInTimes)
.. " time" .. ((profile.Data.LogInTimes > 1) and "s" or ""))
GiveCash(profile, 100)
print(player.Name .. " owns " .. tostring(profile.Data.Cash) .. " now!")
end
local function PlayerAdded(player)
local profile = ProfileStore:LoadProfileAsync("Player_" .. player.UserId)
if profile ~= nil then
profile:AddUserId(player.UserId) -- GDPR compliance
profile:Reconcile() -- Fill in missing variables from ProfileTemplate (optional)
profile:ListenToRelease(function()
Profiles[player] = nil
-- The profile could've been loaded on another Roblox server:
player:Kick()
end)
if player:IsDescendantOf(Players) == true then
Profiles[player] = profile
-- A profile has been successfully loaded:
DoSomethingWithALoadedProfile(player, profile)
else
-- Player left before the profile loaded:
profile:Release()
end
else
-- The profile couldn't be loaded possibly due to other
-- Roblox servers trying to load this profile at the same time:
player:Kick()
end
end
----- Initialize -----
-- In case Players have joined the server earlier than this script ran:
for _, player in ipairs(Players:GetPlayers()) do
task.spawn(PlayerAdded, player)
end
----- Connections -----
Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(function(player)
local profile = Profiles[player]
if profile ~= nil then
profile:Release()
end
end)
Haha
Use a tutorial here as I cant fully explain this in details. All I know is that these functions go inside of a script called:
These functions connect the Profile Service, and it is like the connection hub for profile service.
I recommend you use a vid tho as the documentation tutorials on ProfileService is pretty confusing especially for beginners.
There are TONS of videos out there, so you can use those
Now to access the ProfileStore, there is a script called:
This script holds the phyiscal “Profiles” or Player Data for the entire server. To access you must get in the table of profiles inside the Manager:
In here, you also add functions such as Client reading (NOT EDITTING) and Write:
return Manager.Profiles[Player].Data
end
local function RecursiveSearchAndEdit(Table, Index, Value, Set)
for i,v in pairs(Table) do
if i == Index then
print(Table[i])
if type(Table[i]) == "number" then
if Set == true then
Table[i] = Value
else
Table[i] += Value
end
elseif type(Table[i]) == "boolean" or type(Table[i]) == "string" then
Table[i] = Value
end
end
if typeof(v) == "table" then
RecursiveSearchAndEdit(v,Index,Value,Set)
end
end
end
function Manager.Write(Player,Index,Value,Set)
--Profile
local ClientData = Manager.Profiles[Player].Data
RecursiveSearchAndEdit(ClientData,Index,Value,Set)
--Physical Value
for i, Descendant in pairs(ClientsDataFolder:WaitForChild(Player.Name):GetDescendants()) do
if Descendant.Name == Index then
if type(Descendant.Value) == "number" then
if Set == true then
Descendant.Value = Value
else
Descendant.Value += Value
end
elseif type(Descendant.Value) == "boolean" or type(Descendant.Value) == "string" then
Descendant.Value = Value
end
end
end
end
--Connections
ReadDataRemote.OnServerInvoke = function(Player)
return Manager.Read(Player)
end
Hello! Instead of storing instances, you could use HTTP Service to do JSONEncode on a table containing information about the item you want to store so that you can store it in Datastore as a string.
For example, if you wanted to store the name of an item and its value, you can do this.
local Item = {
["Name"] = "Apple",
["Value"] = 1
}
local toStore = game:GetService("HttpService"):JSONEncode(Item)
Then you can store toStore in Datastore.
To get the dictionary again, you can do
local decodedStore = game:GetService("HttpService"):JSONDecode(ItemInDatastore)
Hello!
I see you have already gotten A LOT of help by the previous people, but I just came here to tell my opinion.
So I think in roblox you can’t actually serialize data. Serialization is when you convert an object into plain text. The method we use to save data here isn’t serialization, we just take the main properties and store them in a table.
Like for example, if, let’s say you want to store the position of a part. (Suppose it’s moveable and a player moved it). You would just save the Part.Position or Part.CFrame value. You won’t actually serialize it. And suppose you have a building system, you would then store the BrickColor, CFrame, etc. etc. You get my point. (hopefully)
I’m not writing all the code because i’m lazy but it would be something like this DISCLAIMER: THIS IS TRASH CODE, DO NOT USE THIS! IT IS ONLY FOR THE PURPOSE OF SHOWING MY POINT.
-- Saving the data
local data = {Part.Position, Part.Color}
Datastore:SetAsync(key, data)
-- Retrieving the data
local data = Datastore:GetAsync(key)
local partPosition = data[1] --It's a table, so we access the data by indexing the table
local partColor = data[2]
Part.Position = partPosition
Part.Color = partColor
So that’s basically it. My code is terrible, it doesn’t use pcalls or BindToClose, heck, it doesn’t even connect to the PlayerAdded or PlayerRemoved functions, but i hope this helps!
Question, where do i add this into my line of code?
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("InventoryDataStore")
local TableToStore = {}
local Data = nil
function SaveData(Player, StoreStuff)
end
game.Players.PlayerAdded:Connect(function(Player)
Player.PlayerGui.InventoryUI.CharacterFrame.CharacterList.Changed:Connect(function()
for i, v in pairs(Player.PlayerGui.InventoryUI.CharacterFrame.CharacterList:GetChildren()) do
if v:IsA("GuiButton") then
local ButtonTable = {}
table.insert(ButtonTable, v.Name)
table.insert(ButtonTable, v.Text)
end
end
end)
end)
game.Players.PlayerRemoving:Connect(function(Player)
end)
Hey friend, i think i did it, first of all i don’t know if this code will work, second of all, what do i write on the If Success and Data then on the player added function:
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("InventoryDataStore")
--local TableToStore = {}
local Data = nil
local ToStore = nil
function SaveData(Player)
local DecodedStore = game:GetService("HttpService"):JSONDecode(ToStore)
local Success, Err = pcall(function()
DataStore:SetAsync(Player.UserId, DecodedStore)
end)
if Success then
print("Data has been succefully saved!")
else
warn(Err)
end
end
game.Players.PlayerAdded:Connect(function(Player)
Player.PlayerGui:WaitForChild("InventoryUI").CharacterFrame.CharacterList.Changed:Connect(function()
for i, v in pairs(Player.PlayerGui.InventoryUI.CharacterFrame.CharacterList:GetChildren()) do
if v:IsA("GuiButton") then
local Item = {
["Name"] = v.Name
}
ToStore = game:GetService("HttpService"):JSONEncode(Item)
end
end
end)
local Success, Err = pcall(function()
Data = DataStore:GetAsync(Player.UserId)
end)
if Success and Data then
end
end)
game.Players.PlayerRemoving:Connect(function(Player)
local Success, Err = pcall(function()
SaveData(Player)
end)
if Success then
print("Inventory saved!")
else
warn(Err)
end
end)