Что нужно знать до первого сохранения
- DataStore работает только на сервере и только в опубликованной игре
- В настройках игры должен быть включён доступ к API-сервисам
- Любой запрос может упасть — оборачивай его в pcall
- У запросов есть лимиты по частоте: сохранять каждый кадр нельзя
Скелет сохранения
local DataStoreService = game:GetService("DataStoreService")local store = DataStoreService:GetDataStore("PlayerData_v1")local function load(userId)local ok, result = pcall(function()return store:GetAsync("user_" .. userId)end)if not ok thenwarn("Не удалось загрузить данные: " .. tostring(result))return nilendreturn result or { coins = 0, level = 1 }endlocal function save(userId, data)local ok, err = pcall(function()store:UpdateAsync("user_" .. userId, function()return dataend)end)if not ok thenwarn("Не удалось сохранить данные: " .. tostring(err))endendreturn { load = load, save = save }
Имя стора с версией: когда формат данных изменится, старые записи не сломаются.
Почему UpdateAsync, а не SetAsync
SetAsync просто перезаписывает значение. Если игрок успел зайти на второй сервер, запись с первого затрёт всё, что он сделал на втором.
UpdateAsync получает текущее значение и возвращает новое — так можно принять решение на основе того, что уже лежит в базе. Не потерять данные важнее, чем сохранить быстро.
Когда сохранять
- При выходе игрока — Players.PlayerRemoving
- При закрытии сервера — game:BindToClose, иначе последние минуты пропадут
- Периодически, раз в несколько минут, а не после каждого действия
- Никогда — по запросу от клиента: клиент не решает, что сохранять