You can write your topic however you want, but you need to answer these questions:
- What do you want to achieve? Keep it simple and clear!
I am trying to make my OOP data module.
- What is the issue? Include screenshots / videos if possible!
The variable self.Stats is nil in the SaveStats() function when it can be accessed by other functions just fine.
module
local StatsManager = {}
StatsManager.__index = StatsManager
local Settings = {}
local TableUtil = require(game.ServerScriptService.TableUtil)
Settings.TriesAllowed = 3
Settings.DataKey = "TestKey"
Settings.StudioSave = true
Settings.DefaultTable = {Cash = 0}
local MainStore = game:GetService("DataStoreService"):GetDataStore(Settings.DataKey)
local PlayerObjects = {}
function StatsManager.new(player)
local self = {}
setmetatable(self, StatsManager)
local leaderstats = Instance.new("Folder", player)
leaderstats.Name = "leaderstats"
self.Key = "PlayerData-"..player.UserId
self.Id = player.UserId
self.Stats = StatsManager[self.Id]
self.Player = player
self.leaderstats = leaderstats
PlayerObjects[player.Name] = self
return self
end
function StatsManager:GetPlayerManager(player)
return PlayerObjects[player.Name]
end
function StatsManager:LoadStats()
local tries = 0
local success
local data
repeat
tries = tries + 1
success = pcall(function()
data = MainStore:GetAsync(self.Key)
end)
until tries == 3 or success
if data then self.Stats = data else self.Stats = TableUtil.deepCopy(Settings.DefaultTable) end
for key,value in pairs(self.Stats) do
local newValue = Instance.new("StringValue", self.leaderstats)
newValue.Name = key
newValue.Value = value
end
end
function StatsManager:SaveStats()
local tries = 0
local success
local data
local err
repeat
tries = tries + 1
success, err = pcall(function()
MainStore:SetAsync(self.Key, self.Stats)
end)
until tries == 3 or success
if not success then
print("error saving")
print(err)
end
end
function StatsManager:IncrementStat(statName, incrementValue)
if self.Stats[statName] then
self.Stats[statName] = self.Stats[statName] + incrementValue
self:UpdateStats()
else
warn(statName.." is not a valid member of stats")
end
end
function StatsManager:SetStat(statName, newValue)
if self.Stats[statName] then
self.Stats[statName] = newValue
self:UpdateStats()
else
warn(statName.." is not a valid member of stats")
end
end
function StatsManager:GetStat(statName)
if self.Stats[statName] then
return self.Stats[statName]
else
warn(statName.." is not a valid member of stats")
end
end
function StatsManager:UpdateStats()
for key,value in pairs(self.Stats) do
if self.leaderstats:FindFirstChild(tostring(key)) then
self.leaderstats[tostring(key)].Value = value
else
warn(tostring(key).." is not a valid member of leaderstats")
end
end
end
function StatsManager:ClearStats()
self.Stats = TableUtil.deepCopy(Settings.DefaultTable)
end
game.Players.PlayerRemoving:Connect(function(player)
if PlayerObjects[player.Name] then
if Settings.StudioSave then
StatsManager:SaveStats()
PlayerObjects[player.Name] = nil
end
end
end)
game:BindToClose(function()
if game:GetService("RunService"):IsStudio() == false then
for _,player in pairs(game.Players:GetPlayers()) do
local PlayerStatManager = StatsManager:GetManager(player)
PlayerStatManager:SaveStats()
end
else
wait(2)
end
end)
return StatsManager
script
local StatsManager = require(script.Parent.StatsManager)
game.Players.PlayerAdded:Connect(function(player)
local PlayerStatManager = StatsManager.new(player)
PlayerStatManager:LoadStats()
while true do
wait(1)
PlayerStatManager:IncrementStat("Cash", 50)
end
end)