Сегодня почти весь день ушел на переосмысление системы блоков кода, чтобы довести созданный прототип до ума. Особенно в рамках мультиплеера и работы с данными.
Что изменилось:
1) Триггеры событий: Глобальные и Локальные
Теперь у триггеров два режима работы:
- Глобальный: Создаёт новый экземпляр скрипта с нуля.
- Например: Игрок зашёл на сервер
- Зачем: Это изолирует данные игрока. Если во время диалога с одним игроком на сервер зайдет второй, то он не перезапишет переменную первого, а запустится в своей "среде".
- Локальный: Срабатывает внутри уже запущенного скрипта.
- Например: Игрок сломал блок во время выполнения квеста
- Зачем: Позволяет обрабатывать события в контексте текущей ситуации (например, запретить ломать блоки, пока идет диалог, или ждать действий второго игрока).
2) Сообщения и Функции
Я пересмотрел структуру пользовательских сообщений и функций, напомню что это и в чём между ними разница:
- Сообщения: 2 вида блоков, грубо говоря отправитель и приёмщик. То есть Вы можете вместо того, чтобы писать огромный спагетти блоко-код, использовать сообщения и, например, при разных вариантах выбора посылать разные сообщения и писать их параллельно, а не последовательно. По факту это
async { ... } на стероидах, можно как запустить это асинхронно и забыть, можно запустить и дождаться завершения. А можно отправить сообщение и записать его контроллер в переменную, чтобы потом отменить задачу (например, если вам нужно чтобы персонаж "размышлял" перемещаясь между 2 точками одновременно с диалогом, а по его завершению перестал) - Функции: Тоже 2 вида блоков, один запускает функцию, второй содержит её действия. В отличии от сообщений - может принимать разные параметры, но не может вызываться асинхронно, чтобы случайно не изменить эти данные в процессе выполнения и не было потом вопросов, почему у вас скрипт работает не так)
3) Переменные и состояния
- Переменные: Теперь двух уровней - локальные (в рамках 1 файла) и глобальные (в рамках всех файлов). Поддерживают все типы данных, включая игроков, мобов и т.п.
- Состояния и флаги: Те же переменные, но привязанные к конкретной сущности (игроку/нпс), что позволяет Вам легко настроить триггеры, чтобы у разных игроков всегда запускался подходящий им скрипт. Да и я думаю мне тут даже объяснять не нужно, и так много чего можно придумать, можете даже пару своих примеров в комментариях написать :)
4) (Пока просто как идея) Думаю многие помнят, что в Legacy был один неприятный косяк, что нпс мог выгрузиться из чанка, а потом дублироваться, потому что движок его не нашёл. Особенно это было заметно во всяких городах с массовкой, приходилось ставить чанклоадеры и этим ещё и ухудшать производительность. А ещё для надёжности при входе полностью всю эту массовку удалять и респавнить, короче жуть 😨
Сейчас это решено просто - если нпс не прогружен, скрипт просто ждёт, пока придёт игрок и сам всё прогрузит. Это хоть и самый стабильный и надёжный вариант, но я думаю доработать эту систему следующим образом:
- При обычной задаче дойти до точки, можно будет включить принудительную прогрузку чанков в области нпс. Например, если эта какая-нибудь важная катсцена или задача.
- Для массовки и распорядка дня сделать вообще независимую систему не требующую загруженных чанков! Согласитесь, какое вообще игроку дело до того, как очередной Виталик будет идти на работу или на Олег - на рынок. Важен сам факт, что к определённому времени нпс должен быть в определённом месте, так что я думаю лучше сделать настраиваемую систему для каждого нпс, где указать во сколько он должен прийти на место и откуда. После чего движок уже сам определит, где и когда должен быть нпс.
Короче говоря, работаю над основой, чтобы потом разом закрыть кучу задач 🙂