Сохранение монет между входами
Создайте Coins в таблице игроков и сохраните значение через DataStoreService.
У каждого игрока появляются Coins. При возвращении значение загружается из DataStore; изменения периодически сохраняются и при выходе тоже.
1. Подготовьте объект
Где разместить: Обычный Script в ServerScriptService
Опубликуйте отдельную тестовую игру Roblox (File → Publish to Roblox). В Studio включите Game Settings → Security → Enable Studio Access to API Services только для тестовой игры.
В ServerScriptService создайте ОДИН обычный Script с кодом. Удалите другие скрипты, которые создают leaderstats.Coins или сохраняют те же монеты.
Запустите Play, дождитесь появления Coins в таблице игроков, соберите монеты, выйдите и зайдите снова. Проверьте сообщения в Output при временной недоступности DataStore.
Эта учебная реализация повторяет загрузку и запись до трёх раз, не выдаёт 0 при ошибке загрузки и не запускает параллельные сохранения одного игрока на сервере.
ВАЖНО: для публичной многосерверной игры необходима отдельная система блокировки сессий. Без неё два сервера могут перезаписать прогресс друг друга.
2. Вставьте код
-- Единственный Script монет в ServerScriptService
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local store = DataStoreService:GetDataStore("IgroCoins_v1")
local AUTOSAVE = 60
local loaded, saving = {}, {}
local function tryLoad(key)
for attempt = 1, 3 do
local ok, value = pcall(function() return store:GetAsync(key) end)
if ok then return true, value end
warn("Загрузка монет: попытка " .. attempt .. " не удалась: " .. tostring(value))
if attempt < 3 then task.wait(attempt * 2) end
end
return false, nil
end
local function save(player)
if not loaded[player] then return false end
-- Не допускаем одновременной записи для одного игрока на этом сервере.
while saving[player] do task.wait(0.1) end
saving[player] = true
local stats = player:FindFirstChild("leaderstats")
local coins = stats and stats:FindFirstChild("Coins")
if not coins then saving[player] = nil; return false end
local value = math.clamp(math.floor(coins.Value), 0, 2000000000)
local key = "coins_" .. player.UserId
local success = false
for attempt = 1, 3 do
local ok, err = pcall(function()
store:UpdateAsync(key, function(_old) return value end)
end)
if ok then success = true; break end
warn("Сохранение монет: попытка " .. attempt .. ": " .. tostring(err))
if attempt < 3 then task.wait(attempt * 2) end
end
saving[player] = nil
return success
end
Players.PlayerAdded:Connect(function(player)
local ok, value = tryLoad("coins_" .. player.UserId)
if not ok then
player:Kick("Не удалось загрузить монеты. Попробуйте войти позже.")
return -- Нельзя заменять неизвестное сохранение нулём.
end
if not player.Parent then return end
local stats = Instance.new("Folder")
stats.Name = "leaderstats"
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Value = typeof(value) == "number" and math.clamp(math.floor(value), 0, 2000000000) or 0
coins.Parent = stats
stats.Parent = player
loaded[player] = true
end)
Players.PlayerRemoving:Connect(function(player)
save(player)
loaded[player] = nil
end)
task.spawn(function()
while true do
task.wait(AUTOSAVE)
for _, player in ipairs(Players:GetPlayers()) do
task.spawn(save, player)
end
end
end)
game:BindToClose(function()
local pending = 0
for _, player in ipairs(Players:GetPlayers()) do
pending += 1
task.spawn(function()
save(player)
pending -= 1
end)
end
local started = os.clock()
while pending > 0 and os.clock() - started < 25 do task.wait(0.2) end
end)3. Проверьте в игре
Нажмите Play в Roblox Studio и проверьте действие механики. Если механика не работает, откройте окно Output и проверьте тип скрипта, его расположение и названия объектов.
Когда проверите механику в Roblox Studio, отметьте практику как выполненную. Отметка хранится только в этом браузере, не в личном кабинете.
Добавляйте механики по одной и проверяйте окно Output. Не создавайте несколько одинаковых систем монет или интерфейсов; скрипты, меняющие WalkSpeed, прыжок или освещение, могут влиять друг на друга.
Измените AUTOSAVE на 90 секунд и проверьте, что монеты сохраняются.
Добавьте награду за найденный сундук из соседней практики.
Создайте три игровых достижения, оплачиваемых монетами.
4. Проверьте себя
Какой сервис Roblox используют для сохранения монет между посещениями?
Если монеты не загружаются, проверьте публикацию игры и API Services в Studio. При ошибке загрузки игрок отключается, чтобы случайно не перезаписать накопления нулём. Не запускайте два скрипта сохранения с одним ключом DataStore. Для многосерверного релиза нужен session locking.