Скрипт: сохранение прогресса в DataStore
Готовый каркас сохранений: монеты и уровень игрока переживают перезаход и рестарт сервера. Каждый сетевой запрос обёрнут в pcall — иначе сбой связи обрывает скрипт.
Куда положить
ServerScriptService, тип объекта Script
Что должно быть в проекте
- Игра опубликована в Roblox
- В настройках игры включён доступ к API-сервисам (Studio Access to API Services)
Код
local DataStoreService = game:GetService("DataStoreService")local Players = game:GetService("Players")local store = DataStoreService:GetDataStore("PlayerData_v1")local DEFAULT = { coins = 0, level = 1 }local cache = {}local function keyFor(player)return "user_" .. player.UserIdendlocal function save(player)local data = cache[player.UserId]if not data thenreturnendlocal ok, err = pcall(function()store:UpdateAsync(keyFor(player), function()return dataend)end)if not ok thenwarn("Сохранение не прошло: " .. tostring(err))endendPlayers.PlayerAdded:Connect(function(player)local ok, data = pcall(function()return store:GetAsync(keyFor(player))end)if not ok thenwarn("Загрузка не прошла, играем без сохранения")returnendcache[player.UserId] = data or table.clone(DEFAULT)end)Players.PlayerRemoving:Connect(function(player)save(player)cache[player.UserId] = nilend)game:BindToClose(function()for _, player in ipairs(Players:GetPlayers()) dosave(player)endtask.wait(2)end)return {get = function(player)return cache[player.UserId]end,}
Если загрузка не прошла, данные в кэш не кладутся вовсе — так пустой прогресс не запишется поверх настоящего.
На что обратить внимание
- Версия в имени хранилища — PlayerData_v1 — пригодится, когда формат данных изменится
- Не сохраняй после каждого действия: у запросов есть лимиты по частоте
- Никогда не принимай от клиента, что именно сохранять