I just finished my OOP data module and it saves values fine but am wondering if there is a better way to do it then the way im doing?
local DataService = {}
local IndexTable = {
__index = DataService
}
local MainStore = game:GetService("DataStoreService"):GetDataStore(script:WaitForChild("DataKey").Value)
local RunService = game:GetService("RunService")
--Function Used To Get The Value Type
local function GetDataType(data)
if typeof(data) == "number" then
return "IntValue"
elseif typeof(data) == "string" then
return "StringValue"
elseif typeof(data) == "boolean" then
return "BoolValue"
end
end
--Data Object Constructer
function DataService.new(UserId)
local newData = {}
setmetatable(newData, IndexTable)
--Makes the server sided folder to store the real data in
local PlayerDataFolder = Instance.new("Folder")
PlayerDataFolder.Parent = game:GetService("ServerStorage"):WaitForChild("GlobalData")
PlayerDataFolder.Name = "Data-"..UserId
--creates a client sided folder to locally store the data for access from UIs and stuff
local PlayerLocalFolder = Instance.new("Folder")
PlayerLocalFolder.Parent = game:GetService("ReplicatedStorage"):WaitForChild("LocalData")
PlayerLocalFolder.Name = "Data-"..UserId
newData.PlayerId = UserId
newData.Key = "Key-"..UserId
newData.GlobalData = PlayerDataFolder
newData.LocalData = PlayerLocalFolder
--adds player removing function inside automatically
game.Players.PlayerRemoving:Connect(function(player)
if player.UserId == UserId then
DataService:SaveData(player.UserId)
end
end)
return newData
end
function DataService:CreateNewData(ValueName, DefaultValue)
--creates new value that will be server sided
local ValueObjGlobal = Instance.new(GetDataType(DefaultValue))
ValueObjGlobal.Parent = self.GlobalData
ValueObjGlobal.Value = DefaultValue
ValueObjGlobal.Name = ValueName
--crates new local value to be used to be indexed by UIs and stuff
local ValueObjLocal = Instance.new(GetDataType(DefaultValue))
ValueObjLocal.Parent = self.LocalData
ValueObjLocal.Value = ValueObjGlobal.Value
ValueObjLocal.Name = ValueObjGlobal.Name
--updates the local value anytime the server value changes
ValueObjLocal.Value = ValueObjGlobal.Value
ValueObjGlobal.Changed:Connect(function()
ValueObjLocal.Value = ValueObjGlobal.Value
end)
local data
local success, err = pcall(function()
data = MainStore:GetAsync(self.Key)
--loops through the data and sees if it can find a key with the value name, if not the value is default
if data then
for _,v in pairs(self.GlobalData:GetChildren()) do
if data[v.Name] ~= nil then
v.Value = data[v.Name]
end
end
end
end)
if not success then
print("error loading data: ")
print(err)
end
end
function DataService:SaveData(id)
local SaveTable = {}
for _,v in pairs(game:GetService("ServerStorage"):WaitForChild("GlobalData")["Data-"..id]:GetChildren()) do
SaveTable[v.Name] = v.Value
end
--inserts the data values into the table with there naeme as a key
--removes any gaps in the table
for k,v in pairs(SaveTable) do
if v == nil then
table.remove(SaveTable, k)
end
end
--set the value
local success, err = pcall(function()
MainStore:SetAsync("Key-"..id, SaveTable)
end)
if not success then
print("error saving data")
print(err)
end
end
--added bind to close in order to prevent data loss from server shutdown
game:BindToClose(function()
if RunService:IsStudio() then
--to make the data saving in studio more reliable
wait(3)
else
for _,v in pairs(game.Players:GetPlayers()) do
DataService:SaveData(v.UserId)
end
end
end)
return DataService