Для первой игры использовал собственные решения, чтоб прочувствовать на кончиках. Затем пошел искать готовое расширения и нашел Saver.
Saver - библиотека для сохранения и загрузки сохраненных данных в проектах Defold
Ключевые функции для новичка:
- удобный API относительно собственного костыльного решения и куча доп функций в придачу)))
- автосохранение каждые n секунд
- можно хранить данные в lua и json
И куча других классных функций: GitHub - Insality/defold-saver: Defold Save File Manager · GitHub
добавляем зависимость и создаем базовый скрипт
Добавляем расширение: game.project → project → dependencies → плюсик и добавляем строчку.
https://github.com/Insality/defold-saver/archive/refs/tags/5.zip
создаем скрипт и привязываем к го
# ASSETS
- создать game.script
# OUTLINE
- создать go
- правая кнопка мыши по go, add component file и добавляем game.script
базовое применение
local saver = require("saver.saver")
local function save(self)
-- делаем что-то с данными STATE, убираем ID/форматируем
print('произошел вызов функции!')
end
local STATE = {}
function init(self)
-- инициализация расширения
saver.init({
save_name = "game.lua", -- название файла, можно выбрать JSON game.json или автоматический выбор или lua
save_folder = "DEFOLD", -- путь /Users/USER_NAME/Library/Application Support/DEFOLD/game.lua
utosave_timer = 7, -- автосохранение в секунду
})
-- Биндим состояние: свяжет + перезапишет поле STATE
saver.bind_save_state("game", STATE)
-- путь до файла в файловой системе
local res= saver.get_save_path("game.lua")
print(res)
-- если у вас особые данные, требующие отформатирования перед использвоанием
-- например, храним данные в JSON, а у вас таблица с ID гошек
-- в JSON нельзя хранить ID
-- и поэтому парсим перед сохранением таблицу, удаляя ID
saver.before_save_callback = function()
save(self)
end
-- есть get/set
-- не сохранятся вместе со STATE
-- предположу, что нужен для данных,
-- не требующих сохранения, но удобно иметь доступ к переменным во всем приложении
saver.set_value("name","alice")
print(saver.get_value("name")) -- alice
-- если не хочется ждать автосохранения, можно сохранять сразу
saver.save_game_state()
-- получить весь слепок для отладки:
pprint(saver.get_game_state())
end
как проверить пустое ли хранилище
local function is_empty_table(t)
return type(t) == "table" and next(t) == nil
end
if is_empty_table(STATE) == true then
-- если таблица пустая
else
-- STATE с даннными
end
как я использовал
local STORE = {}
-- можно сохранять данные в переменные
local function restore_from_save(self)
self.current = STATE.current or 1
self.score = STATE.score or 0
end
-- сохраняем в STATE из локальных переменных
local function save(self)
STATE.current = self.current
STATE.score = self.score
end
return _dump_board_to_save
local function is_empty_table(t)
return type(t) == "table" and next(t) == nil
end
function init(self)
-- инициализируем
restore_from_save(self)
saver.init({
save_name = "game.lua",
})
-- Биндим состояние:= свяжет + перезапишет поле STATE
saver.bind_save_state("game", STATE)
if is_empty_table(STATE) == true then
-- если таблица пустая
-- можем настроить переменные допустим
self.current = 1
self.maxCurrent = 10
else
-- делаем данными STATE переменные в self.current, self.score
-- зачем? если имеется длинная цепочка данных
-- чтоб каждый раз не менять STATE.current и тд
-- и не дергать сохранение
-- мы делаем их локальными
restore_from_save(self)
end
-- сохраняем в STATE из локальных переменных
save(self)
end