I just started using OOP and I came across a problem in the process of making a data store server script.
The issue right now, is that the system doesn’t save the player’s money. Any help is appreciated.
local ServerStorage = game:GetService("ServerStorage")
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("DataStore")
local DataFolder = Instance.new("Folder")
DataFolder.Name = "Data"
DataFolder.Parent = ServerStorage
local PlayerData = {}
PlayerData.__index = PlayerData
function PlayerData.new(player)
local self = setmetatable({}, PlayerData)
self.player = player
self.userId = "Player_" .. player.UserId
self.data = {
["money"] = 0
}
local playerDataFolder = Instance.new("Folder")
playerDataFolder.Name = player.Name
playerDataFolder.Parent = DataFolder
for key, value in pairs(self.data) do
if typeof(value) == "number" then
local numberValue = Instance.new("NumberValue")
numberValue.Name = key
numberValue.Value = value
numberValue.Parent = playerDataFolder
elseif typeof(value) == "string" then
local stringValue = Instance.new("StringValue")
stringValue.Name = key
stringValue.Value = value
stringValue.Parent = playerDataFolder
end
end
print(self.data)
return self
end
function PlayerData:Load()
local success, data = pcall(function()
return DataStore:GetAsync(self.userId)
end)
if success then
self.data = data or {
money = 0
}
else
warn(data)
end
end
function PlayerData:Save()
local success, err = pcall(function()
DataStore:SetAsync(self.userId, self.data)
end)
if not success then
warn(err)
end
end
function PlayerData:ChangeData(key, value, method)
if method == "addition" then
self.data[key] += value
elseif method == "substraction" then
self.data[key] -= value
elseif method == "multiplication" then
self.data[key] *= value
end
print(self.data[key])
local playerDataFolder = DataFolder:FindFirstChild(self.player.Name)
if playerDataFolder then
local dataInstance = playerDataFolder:FindFirstChild(key)
if dataInstance then
dataInstance.Value = value
end
end
end
game.Players.PlayerAdded:Connect(function(player)
local playerData = PlayerData.new(player)
playerData:Load()
--playerData:ChangeData("money", 100, "addition")
end)
game.Players.PlayerRemoving:Connect(function(player)
local playerData = PlayerData.new(player)
playerData:Save()
end)
game:BindToClose(function()
for _, player in pairs(game.Players:GetPlayers()) do
local playerData = PlayerData.new(player)
playerData:Save()
end
end)
if game:GetService("RunService"):IsStudio() then
game:BindToClose(function()
for _, player in pairs(game.Players:GetPlayers()) do
local playerData = PlayerData.new(player)
playerData:Save()
end
end)
end
You are creating an entirely new metatable when the Player Leaves, with inherits entirely new data along with it, you are then saving the “New Data” under the Player’s Key, With “Resets” your Data.
A Simple Solution is to Store the metatable into a Table, and then Access it once the Player is leaving to Save it, just so you dont lose it.
It appears to be so, besides the PlayerRemoving Event.
local ServerStorage = game:GetService("ServerStorage")
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("DataStore")
local DataFolder = Instance.new("Folder")
DataFolder.Name = "Data"
DataFolder.Parent = ServerStorage
local PlayerData = {}
PlayerData.__index = PlayerData
function PlayerData.new(player)
local self = setmetatable({}, PlayerData)
self.player = player
self.userId = "Player_" .. player.UserId
self.data = {
money = 0
}
local playerDataFolder = Instance.new("Folder")
playerDataFolder.Name = player.Name
playerDataFolder.Parent = DataFolder
for key, value in pairs(self.data) do
local dataInstance
if typeof(value) == "number" then
dataInstance = Instance.new("NumberValue")
elseif typeof(value) == "string" then
dataInstance = Instance.new("StringValue")
end
dataInstance.Name = key
dataInstance.Value = value
dataInstance.Parent = playerDataFolder
end
print(self.data)
return self
end
function PlayerData:Load()
local success, data = pcall(function()
return DataStore:GetAsync(self.userId)
end)
if success then
self.data = data or {
money = 0
}
else
warn(data)
end
end
function PlayerData:Save()
local success, err = pcall(function()
DataStore:SetAsync(self.userId, self.data)
end)
if not success then
warn(err)
end
end
function PlayerData:ChangeData(key, value, method)
if method == "addition" then
self.data[key] += value
elseif method == "subtraction" then
self.data[key] -= value
elseif method == "multiplication" then
self.data[key] *= value
end
print(self.data[key])
local playerDataFolder = DataFolder:FindFirstChild(self.player.Name)
if playerDataFolder then
local dataInstance = playerDataFolder:FindFirstChild(key)
if dataInstance then
dataInstance.Value = self.data[key]
end
end
end
local playerDataInstances = {}
game.Players.PlayerAdded:Connect(function(player)
local playerData = PlayerData.new(player)
playerData:Load()
playerDataInstances[player] = playerData
--playerData:ChangeData("money", 100, "addition")
end)
game.Players.PlayerRemoving:Connect(function(player)
local playerData = playerDataInstances[player]
if playerData then
playerData:Save()
playerDataInstances[player] = nil
end
end)
game:BindToClose(function()
for player, playerData in pairs(playerDataInstances) do
playerData:Save()
playerDataInstances[player] = nil
end
end)
if game:GetService("RunService"):IsStudio() then
game:BindToClose(function()
for player, playerData in pairs(playerDataInstances) do
playerData:Save()
playerDataInstances[player] = nil
end
end)
end