Прощай HollowCore, привет HE SDK...
Приветствую, как Вы могли уже заметить из названия, я решил отказаться от HollowCore... Зачем? Что будет теперь? Что случится с HollowEngine и квестовой системой о которой я обещал рассказать в этом посте? – Всё будет, но обо всём по порядку.
Заранее хочу извиниться за оформление кода и текста, поскольку пишу с телефона, а тут просто ужасный интерфейс Boosty, посты вообще можно делать только через сайт, поскольку в приложении такой возможности всё ещё нет. Да и код писать с телефона тот ещё кошмар...Начнём с того, что я сейчас в небольшом отпуске до 25 числа включительно, потому особо новостей и нет. Но это позволило мне хорошо обдумать архитектуру движка и план его развития на ближайшее время.
Пока я пришёл к нескольким проблемам:
Заранее хочу извиниться за оформление кода и текста, поскольку пишу с телефона, а тут просто ужасный интерфейс Boosty, посты вообще можно делать только через сайт, поскольку в приложении такой возможности всё ещё нет. Да и код писать с телефона тот ещё кошмар...Начнём с того, что я сейчас в небольшом отпуске до 25 числа включительно, потому особо новостей и нет. Но это позволило мне хорошо обдумать архитектуру движка и план его развития на ближайшее время.
Пока я пришёл к нескольким проблемам:
1) Существование HollowCore существенно замедляет разработку: При каждом изменении в ядре мне нужно проверить его работоспособность на всех версиях, потом его компилировать, потом загрузить на maven.0mods.team, а потом уже обновить его в самом движке... Согласитесь, не очень удобно.
2) Если не считать HollowCore, то сам движок весит ~75мб. А всё, потому что вместе с движком идёт полноценный компилятор Kotlin со всеми его платформами, синтаксическим анализатором и многочисленным фишками Языка.
3) По сути за исключением редактора кода и пары функций для нпс в нём ничего и нет... Я просто раз за разом переписываю одно и то же...
Собственно и что я хочу со всем этим сделать? – Слить вместе и разделить.
Собственно и что я хочу со всем этим сделать? – Слить вместе и разделить.
А если более конкретно, то HollowCore станет частью HollowEngine. А сам HollowEngine будет разделён в первую очередь на `HollowEngine Core+API`, который сможет запускать уже скомпилированные скрипты и будет иметь весь функционал HollowCore. По весу он тоже будет примерно такой же. А второй мод – `HollowEngine SDK`, будет отвечать за тяжёлые вещи вроде компилятора, редактора скриптов и т.п.
Возможно в далёком будущем и NPC, сюжетную часть и квесты стоит разделить на отдельные моды, но тут ещё надо думать. Пока я не планирую вырезать нпс в отдельный мод.
Таким образом моя работа всегда будет происходить в рамках одного репозитория, хоть и с несколькими модулями. Также это упростит и работу будущим контрибьюторам, поскольку не придётся метаться между библиотеками. И на это в целом уйдёт не больше недели.
А второй важный шаг, это внедрение нескольких систем их большинства игровых движков:
1) Система компонентов – позволяет привязывать различные компоненты к игровым объектам вроде блоков, мобов или даже миров. Выглядит это примерно так:
```kotlin
@Serializabledata class NpcMessages( // Скорее всего содержимое компонентов можно будет настраивать прямо в редакторе npc vararg val messages: String)
// И где-то в скрипте запускаем новую корутинуval action = launch { // Я пока ещё думаю как реализовать события, можно сделать бесконечный цикл с ожиданием событий и кучей проверок, а есть вариант с использованием механизма Flow из корутин 🤔 // В данном случае поток будет ждать взаимодействия с нпс и вызывать код внутри forEach npc.interactFlow.forEach { event ->event.player send npc.get<NpcMessages>().messages.random() }
println("А этот код никогда не сработает, потому что события в подобном Flow идут бесконечно...")}
action.cancel() // Также эту корутину легко остановить из скрипта
// И где-то в скрипте запускаем новую корутинуval action = launch { // Я пока ещё думаю как реализовать события, можно сделать бесконечный цикл с ожиданием событий и кучей проверок, а есть вариант с использованием механизма Flow из корутин 🤔 // В данном случае поток будет ждать взаимодействия с нпс и вызывать код внутри forEach npc.interactFlow.forEach { event ->event.player send npc.get<NpcMessages>().messages.random() }
println("А этот код никогда не сработает, потому что события в подобном Flow идут бесконечно...")}
action.cancel() // Также эту корутину легко остановить из скрипта
```
2) Второй важный механизм это корутины, думаю про них я вам уже все уши прожужжал и похоже буду это делать и дальше 😅От полного сохранения корутин я отказался, но некоторые вещи сохранить в них всё же можно будет:
```kotlin
suspend fun main() { println(tag::class) // Вернёт: CompoundTag
// Если коротко, то tag это переменная которая будет предоставляться в любую suspend функцию в скрипте и при каждом выходе из игры её данные будут сохранены. Но сам код начнётся с начала.
// В этом случае мы получаем текущее количество "жизней", которое по умолчанию 5. Но если игрок потеряет несколько жизней и перезайдёт в игру, то оно не сбросится а будет восстановлено из tag var liveCount: Int = tag.getOrPut("liveCount") { 5 }
// Если коротко, то tag это переменная которая будет предоставляться в любую suspend функцию в скрипте и при каждом выходе из игры её данные будут сохранены. Но сам код начнётся с начала.
// В этом случае мы получаем текущее количество "жизней", которое по умолчанию 5. Но если игрок потеряет несколько жизней и перезайдёт в игру, то оно не сбросится а будет восстановлено из tag var liveCount: Int = tag.getOrPut("liveCount") { 5 }
liveCount--
tag.putInt("liveCount", liveCount) // Значение нужно будет обновить и в теге, чтобы при перезапуске он брал сохранённые значение
// Либо использовать готовый делегат, способный запоминать и автоматически сохранять сериализуемые типы:
// Либо использовать готовый делегат, способный запоминать и автоматически сохранять сериализуемые типы:
var liveCount: Int by remember { 5 }
liveCount--
}
```
То есть, если у вас есть условный диалог на пол часа, то вы можете добавить каждую фразу в список и сохранять индекс текущей фразы в тег, применений этому думаю сможете найти много. Если с простыми действиями вроде списка фраз или предметов, которые нужно сохранить – всё понятно, то что делать с большими скриптами состоящими из нескольких этапов? Как строить не линейные сюжеты? Как сделать, чтобы скрипт продолжался после определённого действия? Об этом и есть 3 пункт.
3) Стейт машины – наверное проще всего это представить как несколько городов соединёнными дорогами. А Вы в этом случае бедный работяга, который работает в каждом городе на определённой работе и иногда переходите из одного города в другой и выполняете там другую работу. Тоже самое я планирую сделать и со скриптами: Сначала объявляются все состояния с действиями внутри них, а потом переходы из одного состояния в другое. Таким образом, Вы сможете делать как последовательные истории, так и развилки, да даже циклические. А при перезаходе движок просто запустит с начала состояние, в котором последний раз находился скрипт. Кроме того, я думаю ещё сделать разделение на стейт машины отдельно для сервера и отдельно для сущностей/блоков/предметов. Тогда гораздо проще будет писать всяких боссов и делать сложные механики для блоков и предметов. Но пока что я ещё не определился с тем, как это будет выглядеть в коде.
А насчёт обновлений, думаю первые два я уже сделаю в начале сентября. На третье может уйти как неделя, так и пара месяцев. Но этого функционала уже в целом должно хватать чтобы реализовать всё что угодно со стороны сервера и геймплея. Пример кода с ними я писал в прошлых постах, но я всё ещё думаю над удобным DSL... Может даже визуальный редактор сделаю, кто знает...
Ну и наконец, по поводу мода на квесты, расскажу немного своих идей на эту тему:
1) Мод будет работать на базе `HollowEngine Core/API` о котором я писал выше. То есть не будет требовать компилятора для работы, но будет использовать возможности движка. Да и вероятно интеграция со скриптами будет (например, добавление своих условий для выполнения квеста)
2) Квестовая система будет аналогична 1 вкладке в FTB Quests. Квестовую систему можно будет привязать к:
- Игрокам (Как в FTB Quests, где её можно открыть в инвентаре)
- Блокам (Будет открываться только через пкм по блоку)
- Сущностям (Будет открываться через пкм по сущности)
- Предметам (При использовании предмета)
3) Прогрессию квестовой системы можно будет привязать к:
- Игроку (У каждого игрока своя прогрессия)
- Команде (Несколько игроков будут иметь общую прогрессию)
- Сущность/Предмет/Блок (Будет привязана конкретно к самому объекту)
4) Будет импорт готовых квестов из FTB Quests и достижений.
5) Внутри одного большого квеста можно будет создать несколько маленьких квестов. Нажав на один квест появится панель с ещё одним деревом квестов.
6) Мод будет и как API для мододелов и как инструмент для сборкоделов. Кроме того, я хочу сделать 100% кастомизацию интерфейса и API покрывающее почти все возможности квестовой системы, а не только банальную смену рамки квеста, цвета фона и замену пары текстур. Так что тут я пока что ещё думаю над некоторыми сложностями:
7) Полная кастомизация интерфейса значит, что квесты можно будет отображать не только, как граф из иконок со стрелочками, но и как книгу с заданиями или главами, как линейный список заданий у нпс и т.д. Но проблема тогда в том что для каждого кастомного интерфейса кому-то придётся делать кастомный редактор)))
8) Кастомный интерфейс также предполагает и кастомные данные (например, модельку нпс), но как их лучше передать пока не ясно. Хотя учитывая, что интерфейс делается через скрипты, то думаю тут уже проще что-то придумать.
9) Если так подумать, квестовый граф, это ведь тоже по своей сути Стейт-машина? Возможно стоит сделать более сложные условия переходов, где для открытия одного квеста нужно выполнить лишь некоторые из зависимостей, или добавить цикличные квесты, которые условно через 5-10 повторений пропустят дальше? Если рассматривать систему в подобном ключе, то открывается, как тонна новых возможностей, так и тонна новых вопросов и сложностей.
Ну и да, разумеется все хотят узнать, когда будет MVP версия мода на квесты и что в ней будет: **Бета версия планируется к концу сентября-началу октября на Boosty** (а если нет, пните Холлова из будущего и попросите билд :D), вместе с базовым дизайном, редактором и прикрепление квестов к тем объектам, что писал выше. Остальное уже по мере возможностей. Релиз будет в открытом доступе, когда я решу, что мод готов.
Но в целом как по мне идея очень даже интересная. А привязка прогрессии к другим объектам позволит делать интересную логику, например, данж, где чтобы открылся вход нужно пройти несколько квестов. К тому же эта задумка по своей сути очень близка к так полюбившимся многими нодам, так что может со временем это станет чем-то большим, вроде HollowEngine: Visual Programming)
Но в целом как по мне идея очень даже интересная. А привязка прогрессии к другим объектам позволит делать интересную логику, например, данж, где чтобы открылся вход нужно пройти несколько квестов. К тому же эта задумка по своей сути очень близка к так полюбившимся многими нодам, так что может со временем это станет чем-то большим, вроде HollowEngine: Visual Programming)
Axel Encore
Тема интересная, но название с ходу напугало, правда интересно а состояние например открытия дверей данжа будет регулироваться у каждого игрока по отдельности? То есть например дверь дома закрыта но игрок 1 прошел квест и теперь по квесту может открыть, но другой игрок 2 не может открыть и пройти пока не выполнит такой же
Aug 20 2025 14:52 (changed)
Hollow HorizonReplying to Hollow Horizon
Hollow Horizon, В том же Twilight Forest Есть похожая механика, где нужно поставить 4 головы боссов на пьедесталы, чтобы открылся проход. На серверах, понятное дело почти все подобные данжи зачищены, но думаю так или иначе механика хорошая
Aug 20 2025 15:07
Axel EncoreReplying to Hollow Horizon
Hollow Horizon, хм ладно надо думать
Aug 20 2025 15:34