Возможно, ваша игра еще не была опубликована, но ничто в вашем коде не выглядит так, как если бы она вызывала синтаксические ошибки, но она выглядит небезопасной и расточительной.
Каждый вызов GetAsync()
и SetAsync()
- это блокирующий сетевой запрос, который может привести к сбою и выбрасыванию ошибок. Кроме того, существует ограничение на количество запросов , которые вы можете отправлять с сервера, и если вы достигнете этого предела, ваш код выдаст ошибки и, скорее всего, потеряет данные игрока.
Вместо того, чтобы сохранять одно значение на ключ, вы можете сохранить всю таблицу значений в один ключ. Это значительно уменьшает количество сетевых запросов и вероятность того, что что-то может произойти.
Сохранение данных
local HttpService = game:GetService("HttpService")
local DataStoreService = game:GetService("DataStoreService")
local ds = DataStoreService:GetDataStore("Data")
game.Players.PlayerRemoving:Connect(function(player)
local stats = player.leaderstats
local hidden = player.hidden
local data = {
coins = stats.Coins.Value,
gems = stats.Gems.Value,
xp = hidden.XP.Value,
level = stats.Level.Value,
maxstamina = hidden.MaxStamina.Value,
maxmagic = hidden.MaxMagic.Value,
}
-- wrap the request in a try-catch block to ensure that failures don't throw errors
local success, result = pcall(function()
-- save all the data as a JSON string
ds:setAsync(player.UserId, HttpSevice:JSONEncode(data))
end
if not success then
warn(string.format("Failed to save %s's data with error : %s", player.Name, tostring(result))
-- TO DO: FIGURE OUT HOW YOU WANT TO HANDLE THIS ERROR.
-- IF YOU DO NOTHING, THE PLAYER WILL LOSE THIS SESSION'S DATA
end
end)
Загрузка данных
game.Players.PlayerAdded:Connect(function(player)
local defaultData = {
coins = 0,
gems = 0,
xp = 0,
level = 1,
maxstamina = 100,
maxmagic = 100,
}
local loadedData = defaultData
local success, result = pcall(function()
return ds:GetAsync(player.UserId)
end
if success then
if result then
-- if we've successfully loaded the data, parse the stored json data
print(string.format("An old player named %s has returned with data : %s!", player.Name, result))
-- player data should look like this :
-- {"coins":0,"xp":0,"gems":0,"level":1,"maxstamina":100,"maxmagic":100}
local parseSuccess, parseResult = pcall(function()
return HttpService:JSONDecode(result)
end)
if parseSuccess then
loadedData = parseResult
else
warn(string.format("Failed to parse %s with error : %s", tostring(result), tostring(parseResult))
end
else
-- we have a new player
print(string.format("New player named %s has joined!", player.Name))
end
else
warn(string.format("Something went wrong fetching %s's data : %s", player.Name, tostring(result))
-- TO DO: FIGURE OUT HOW YOU WANT TO HANDLE THIS ERROR.
-- IF YOU DO NOTHING, THE PLAYER'S DATA WILL BE THE DEFAULT DATA USED FOR
-- NEW PLAYERS
end
-- create the leaderstats and hidden values, load the data from the loadedData table
local leaderstats = Instance.new("Model")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local hidden = Instance.new("Model")
hidden.Name = "hidden"
hidden.Parent = player
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Parent = leaderstats
coins.Value = loadedData.coins
local gems = Instance.new("IntValue")
gems.Name = "Gems"
gems.Parent = leaderstats
gems.Value = loadedData.gems
local level = Instance.new("IntValue")
level.Name = "Level"
level.Parent = leaderstats
level.Value = loadedData.level
local xp = Instance.new("IntValue")
xp.Name = "XP"
xp.Parent = hidden
xp.Value = loadedData.xp
local maxstamina = Instance.new("IntValue")
maxstamina.Name = "MaxStamina"
maxstamina.Parent = hidden
maxstamina.Value = loadedData.maxstamina
local maxmagic = Instance.new("IntValue")
maxmagic.Name = "MaxMagic"
maxmagic.Parent = hidden
maxmagic.Value = loadedData.maxmagic
local stamina = Instance.new("IntValue")
stamina.Name = "Stamina"
stamina.Parent = hidden
stamina.Value = loadedData.maxstamina
local magic = Instance.new("IntValue")
magic.Name = "Magic"
magic.Parent = hidden
magic.Value = loadedData.maxmagic
end)