Я недооценивал ресурсы
И коротко о том, как я избавился от фризов при смене сцен и сделал почти мгновенную загрузку игры
В прошлой демке вы могли заметить, что игра намертво зависала при переходе из главного меню в меню выбора персонажа и оттуда в забег.
Виной тому было моё распиздяйство по отношению к загрузке данных)0)
Что фризило?
Дело в том, что при открытии менюшки выбора персов я подгружал всех персонажей, все их скиллы и все перки.
Причина была в том, что я хранил данные о них (всякие иконки, названия итд.) прямо в классах.
То есть, в классе персонажа лежали сцены со скиллами, а так же класс PerksMap, в котором лежали все перки, доступные персонажу. Ну а информация о перке лежала в классе перка.
Таким образом, для того, чтобы выбрать персонажа и его скиллы, приходилось загружать соответствующие сцены. А для выдачи перков - загружать все перки.
Делал я так, потому что неправильно прочитал доку и полагал, что функция load() подгружает класс на момент создания инстанса.
Настоящая же разница между preload и load следующая:
preload()подгружает штуки на момент запуска сцены, в которой preload написан. Независимо от того, вызвалась ли строчка кода сpreload()или нет;load()подгружает штуки на момент выполнения строки, где load() использован;
при нажатии на кнопку "Play" фризила игру примерно секунд на 10. А загрузочный экран я никакой ещё не делал. Жопа!
Окей, а причём тут ресурсы?
Я решил оперативно избавиться от загрузок и хранения мета-инфы в классах, чтобы при выборе персов/скиллов/перков не было необходимости грузить классы.
Но чот вдруг решил полистать доку и наткнулся на Resource.
Я как-то обошёл их стороной в своё время - оперировал всё время либо нодами, либо RefCounted.
В общем, Resource - это класс, от которого можно наследоваться, чтобы создавать кастомные структуры данных.
Например, вот такой класс сделал под персонажа:
Затем мы можем создать .tres-файлик, который от него наследуется:
И в инспекторе мы можем с ним поиграться:
Обращаю внимание на "Scene Path" и "Perks Map Path" - вместо сцен/скриптов в эти переменные я сложил пути для них. Чтобы они не загружались при загрузке этого ресурса.
Теперь вместо прокидывания сцены с юнитом и скиллами в меню можно швыряться чисто этим ресурсом, и оно загрузится почти мгновенно.
Также, поскольку ресурс написан на GDScript и имеет жёсткую структуру, в коде будут подсказки, что тоже оч полезно.
Окей, но ты мог так сделать и с обычным классом
Мог, но у ресурсов есть ряд преимуществ.
Во-первых, инстансами ресурсов являются файлы, а не ноды. Таким образом, редачить их можно прямо оттуда, и для создания общего инстанса для всей игры не нужно пилить сцены. То есть, добиться идентичного результата ресурсы позволяют гораздо более дешёвым и удобным способом.
Во-вторых, ресурсы можно редактировать в рантайме и сохранять. И независимо от того, какого типа данные в них хранятся, они сами сериализуются.
Это дало бесплатную возможность запоминать, какие скиллы были выбраны в менюшке. Всего одна строчка кода и готово:
А что насчёт JSON?
Хранить подобные данные в JSON удобно с той точки зрения, что ты можешь их использовать в других местах.
Например, JSON ты можешь конвертировать в csv и экспортировать в Notion. Так ты получишь редактируемую табличку, которую можешь потом обратно скачать и сохранить для игры.
С ресурсами такой трюк не прокатит. Если только кто-нибудь не написал сторонний двухсторонний конвертёр. То есть, переходя на ресурсы, ты расписываешься в том, что не будешь юзать эти данные где-то, кроме Godot.
Однако, JSON хранит только тривиальные данные - числа, строки, булевые флаги и null. Ну и вложенные массивы с объектами.
То есть, ты не сможешь положить туда файл, скилл и так далее.
Всякие вспомогательные функции тоже придётся описывать отдельно.
Также, с JSON ты лишаешься редактирования внутри IDE и прочих QoL-штук.
Короче говоря, оба формата имеют свои плюсы и минусы. Я решил посидеть на ресурсах по итогу.
Осталось вытащить в них описание из 200+ перков. Ближайшие 2 дня будут очень увлекательными)0)