Геймдевовских вопросов псто...

В общем, пилю я тут потихоньку «Дитя ночи», и в процессе возникает тонна всяких вопросов, как что лучше сделать. Во избежание обретения крупометки с велосипедом о квадратных колесах хочется найти кого-нибудь умного и распросить на эту тему. Поиск в интернетах, к сожалению, дает либо очень общие ответы, либо описание конькретных реализаций, которые, как правило, не подходят.

Собственно, кто может пояснить за грамотное создание скриптовой системы, построение годной ECS, правильное построение взаимодействия игровых объектов и еще кучу всего — отзовитесь! Нужна ваша помощь!


Касаемо движка...Движок свой, самописный и компонентно-ориентированный. То есть, игровой объект это просто id в общем массиве, к каждому из которых прикреплен набор компонентов — позиция, форма, внешность и т.д. Компоненты — хранилища данных и логики не содержат. Логика содержится в системах — графической, поведенческой, обсчета прикосновений и т.д. — которые каждый такт пробегают по всему массиву и изменяют данные в компонентах либо делают что-то на основе этих данных.

Пишется на С++, хотя сомневаюсь, что это будет актуально.

А вопросы вот такие.1) у каждого объекта есть состояние, которое отвечает за то, что объект делает. Некоторые состояния, скажем, удар или применение вещи, требуют анимации. Как лучше сделать связь необходимого момента анимации и действия?
2) на данный момент «применение» вещей реализовано через создание при нажатии клавиши невидимого объекта-применятеля, который при обсчете прикосновений что-то делает, например, вызывает диалог. Адекватно ли такое решение?
3) точно так же, адекватно ли решение для нанесения урона в драке создавать невидимый ранящий объект?
4) каким образом лучше реализовать скриптовую систему? На данный момент идея состоит в том, что у каждого объекта будет таблица [триггер — действие], которая будет опрашиваться каждый такт. Триггер — некое условие, скажем, нажатие клавиши или истечение определенного времени на истекающем таймере. Действие — некая команда. Основной вопрос возникает в моментах, где необходимо использовать множественные условия — непонятно, как это лучше обрабатывать. Хранить условия в строках и парсить строку?
5) есть ли какой-то способ разнести логику системы обработки касаний? То есть, на данный момент ей требуется у каждого объекта узнать его роль и, сопоставляя эти роли, решать, что будет дальше. В таком раскладе функция обработки разрастется до гигантских размеров. Как это можно логично упростить?

11 комментариев

Во имя геймерши Луны, лети, пост, в ленту!
Ginger_Strings
0
Объяснил бы для диванно-танковых войск, о чем собственно, пост?
Escatello Изменён автором
0
Э-э… ну… А что из него непонятно? Я ищу людей, кого можно расспросить. Конкретные темы расспросов, вроде, тоже указал…
Ginger_Strings
0
Ну, я полагаю, чтобы народ откликнулся на твой запрос, наверное желательно хотя бы вкратце рассказать, что ты собственно задумал сделать.
Я лично только после третьего прочтения вспомнил про твою игру, «Children of the Night», хотя я пристально следил за ВОКИ. А что сказать про тех кто в ВОКИ не участвовал и особо не заходил в посты?

Сказал бы, хоть, на ком движке делается игра, про какого плана взаимодействия идет речь(учитывая что диалоги ты там запилил), с какими проблемами столкнулся и тд.
Escatello
+1
Вопросы общие и движковонезависимые. Движок я делаю свой, компонентно-ориентированный. То есть, объекты = id в общем массиве, к каждому из которых приложены компоненты, содержащие данные, а логика находится в системах, которые пробегают каждый такт по всему массиву и выполняют с данными компонентов всяческие операции.

Список вопросов достаточно массивный. Сейчас обновлю пост.
Ginger_Strings
0
Обновил.
Ginger_Strings
0
правильное построение взаимодействия игровых объектов

Это такая засада, которую строишь-строишь, потом нужно добавить одну функцию в игру — и вся архитектура рассыпается.

В общем случае, есть три вариации, называются они каждый раз по-разному, привожу так, как моя память помнит из книг.
1) Архитектура «бог» — когда есть один главный класс, которым всем рулит, а остальные у него только для хранения данных и первичной обработки. Плюсы — централизация логики, минусы — распухание класса.
2) Архитектура «полис» — когда каждый объект равноправен и обращается за необходимыми данными к необходимым классам. Плюсы — примерно равный код на каждый класс, минусы — сложно следить за связями классов.
3) Архитектура «лес» — классы группируются по назначению (объекты, ресурсы, карта и т.д.), каждой группе назначается главный класс, который ей управляет, объекты внутри группы общаются между собой, объекты вне группы — могут обратиться только через главный класс этой группы. Наиболее сбалансированное решение, но требует времени на построение.

По разным прочим — пиши в личку, если есть конкретные вопросы. Пересказывать всего Фаулера и Бека довольно затруднительно, пальцы не резиновые :-)
NTFS
+1
Я обновил пост, и там теперь есть список вопросов :)
Спасибо за приглашение в личку — воспользуюсь, если понадобится еще какая-то помощь.
Ginger_Strings
0
То есть, игровой объект это просто id в общем массиве, к каждому из которых прикреплен набор компонентов — позиция, форма, внешность и т.д. Компоненты — хранилища данных и логики не содержат. Логика содержится в системах — графической, поведенческой, обсчета прикосновений и т.д. — которые каждый такт пробегают по всему массиву и изменяют данные в компонентах либо делают что-то на основе этих данных.

То есть я правильно понимаю, что мухи, котлеты и даже аллах были покиданы в одну кучу? Оригинальное решение, ничего не скажешь.

1) у каждого объекта есть состояние, которое отвечает за то, что объект делает. Некоторые состояния, скажем, удар или применение вещи, требуют анимации. Как лучше сделать связь необходимого момента анимации и действия?

Самое простое, что приходит при такой системе в голову — синхронизировать тайминги. То есть выставить в этом объекте-применителе анимацию, которая через секунду стреляет из пистолета и, заодно, проставить таймстемп=now+1 — чтобы если при следующем глобальном поллинге всего этого зоопарка оказалось что этот таймстемп истёк, то надо рожать пулю.

2) на данный момент «применение» вещей реализовано через создание при нажатии клавиши невидимого объекта-применятеля, который при обсчете прикосновений что-то делает, например, вызывает диалог. Адекватно ли такое решение?

Ммм, а каким это ещё способом можно реализовать в рамках выбранной концепции?

3) точно так же, адекватно ли решение для нанесения урона в драке создавать невидимый ранящий объект?

Мне кажется, вы уже чувствуете нехватку очереди событий. Но если её не создавать — то всё так и есть.
… Проблемы у вас начнутся, когда обнаружится, что в этом глобальном хранилище развелось квадриллион фиктивных объектов, которые проверяются на каждом шаге и для большинства из них делается нифига.

4) каким образом лучше реализовать скриптовую систему? На данный момент идея состоит в том, что у каждого объекта будет таблица [триггер — действие], которая будет опрашиваться каждый такт. Триггер — некое условие, скажем, нажатие клавиши или истечение определенного времени на истекающем таймере. Действие — некая команда. Основной вопрос возникает в моментах, где необходимо использовать множественные условия — непонятно, как это лучше обрабатывать. Хранить условия в строках и парсить строку?

Можно, конечно, и в Средиземье идти через северный полюс, но зачем? Вы же знаете, что любое условие можно перевести в СДНФ? А дальше просто заведите вектор из конъюнкция, каждую конъюнкцию записываете в виде набора литер со знаком, либо в виде массива тритов — как удобнее, в зависимости от числа элементарных условий. Вот и всё.

5) есть ли какой-то способ разнести логику системы обработки касаний? То есть, на данный момент ей требуется у каждого объекта узнать его роль и, сопоставляя эти роли, решать, что будет дальше. В таком раскладе функция обработки разрастется до гигантских размеров. Как это можно логично упростить?

Стоп-стоп. У вас этим должны заниматься независимые сущности. То есть грубо говоря, должно быть нечто такое:
Обработка касаний:
Для всех пар объектов:
(форма1=получить форму по объекту(объект1))
(форма2=получить форму по объекту(объект2))
Если (пересечение(форма1, форма2))то
при_пересечении(объект1, объект2)

При этом форма1, 2 — не несёт никакой информации о том, какой же это изначально объект был, а что-то типа набора полигонов+ограничивающий прямоугольник(если речь о 2д). Где тут у вас разрастание?
narf
0
В последнем пункте? Ну да, при такой системе как у вас оно будет. Максимум, что можно с этим сделать — ввести понятие подтипа и раскидывать дальше на функции:
(Тип1, тип2) = (получить_тип(объект1), получить_тип(объект2))
Если (тип1==фиктивный_объект)вызвать_фиктивную_фигню(объект1)
Если (тип1==настоящий_объект)настоящая_коллизия(объект1, объект2)
И засовывать логику в функции поменьше.
narf
0
Пульну-ка свои глупые велосипеды
Спойлер
1) у каждого объекта есть состояние, которое отвечает за то, что объект делает. Некоторые состояния, скажем, удар или применение вещи, требуют анимации. Как лучше сделать связь необходимого момента анимации и действия?

Обобщенно: у объекта есть некая переменная, которая содержит в себе номер текущей картинки (она может быть анимированной, но не суть). И она просто меняется, затем логика самого объекта ее возвращает. Можно прикрутить переменную, которую логика учитывает, и уже потом сама меняет. Я у себя замутил систему состояний (которые упрощают программирование анимации на стороне физики, но усложняют логику выбора кадров), но у меня написан кусок, который сам обеспечивает переходы, саму анимацию, вложенность и прочая. (возможно, дохера лишнего накатал там). А по анимации — у меня есть для этого целый объект, в нем пишутся вообще все анимации, их строение, длительность каждого кадра (заодно каждый кадр тоже расписывается, размеры, поправки, все такое).
2) на данный момент «применение» вещей реализовано через создание при нажатии клавиши невидимого объекта-применятеля, который при обсчете прикосновений что-то делает, например, вызывает диалог. Адекватно ли такое решение?

Вполне, сам бы так сделал (у меня лично (по архитектуре) у игрока не будет просто вызываться ИИ (точнее все же будет, но он ничего не будет делать большую часть времени), вместо вызова будет обсчет нажатий).
3) точно так же, адекватно ли решение для нанесения урона в драке создавать невидимый ранящий объект?

Если не будет происходить мессива, мб проканает. Если есть какой-то интерфейс связи между объектами, то лучше через него.
4) каким образом лучше реализовать скриптовую систему?

Ох, в написании своих скриптовых систем не мастак. Насчет триггеров — в среднем случае банального перебора всех триггеров и проверки (если они позиционные) должно хватать. Можно делать это не каждый такт. Если их все же дофигалион — я бы завел второй массив с картой, где помечал бы клетки с определенными триггерами (точнее фактом наличия триггера, и только если там правда что-то есть — перебрать. А можно скомбинировать, отрицательные числа иногда помогают).
5) есть ли какой-то способ разнести логику системы обработки касаний? То есть, на данный момент ей требуется у каждого объекта узнать его роль и, сопоставляя эти роли, решать, что будет дальше. В таком раскладе функция обработки разрастется до гигантских размеров. Как это можно логично упростить?

Лично я слабо представляю. Я бы это на ИИ объекта возложил, а там пусть сам смотрит, что в него стукнулось и что с ним делать.

Попробуй все же в ооп, если еще не поздно
StaSyaN Изменён автором
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.
Скрыто Показать