Публикации

sam0delk1n
Я не очень в Java, но в интернете рекомендуют прямые буферы (ByteBuffer).

Если нет способа размещать компоненты в памяти последовательно, то сделать быструю ECS вряд ли выйдет.

Я отсюда не вижу, как там у тебя в коде, но идея Entity-Component-System — это когда System обходит свой массив(ы) из Component без обращения к Entity или компонентам других систем. В примере из топика все данные должны быть в PhysicsBody, и обходить массив нужно по порядку, напрямую обращаясь к компоненту, а НЕ через Entity прыгать. Хеш-таблицы обычно располагают данные локально, но не последовательно, у аппаратного префетчера с этим могут быть проблемы. К тому же массивы (или пулы) можно сортировать, например, если два компонента взаимодействуют (как пружина в примере), их можно разместить подряд. Если каждый кадр по чуть-чуть перетасовывать, уже через несколько секунд всё будет разложено по порядку.

В этом случае возникает проблема дублирования данных, например, координаты объекта нужны и для графики, и для физики. Здесь уже по ситуации — если обращение на чтение системами своих компонентов происходит чаще, чем изменение их данных (графика ничего не меняет, а физика, например, на 90% из статических или спящих объектов), тогда имеет смысл поля координат сделать и в компоненте графики, и в компоненте физики, и в случае изменения проводить синхронизацию копированием этих полей. Если все объекты физики постоянно двигаются, тогда имеет смысл выделить координаты в отдельный компонент (типа Transform), разместить эти компоненты в массив, который расположить «достаточно близко» к массивам с компонентами графики и физики.

В любом случае нужно отслеживать «горячие» и «холодные» поля разных компонентов и учитывать по этому признаку тоже, а не только интуитивно делить на «графику и физику». В редакторе движка деление по типам компонентов может быть стандартным, а внутри движка данные можно распределять в памяти по-другому, если нужно.
sam0delk1n
На сайдбаре, где «Активность», есть ссылки на автора, топик и начало комментариев, но нет самой нужной — на добавленный комментарий.

Вообще некоторые тексты и элементы мелковаты. Чтобы соответствовать масштабу Хабра, нужно увеличить до 125%, и то некоторые тексты остаются маленькими — на Хабре шрифты и элементы более однородные и нет слишком больших или маленьких, больше используются всякие стили, толщина, цвет, а не размер для разделения разных текстов.
sam0delk1n
Я искал, где можно поставить плюсик автору топика, но, видимо, это разрешено, начиная с определённого рейтинга.
sam0delk1n
Было бы неплохо добавить пояснение к рейтингу — какие возможности появляются у пользователей при достижении такого-то рейтинга.
sam0delk1n
По моему, корутины это довольно красивое и простое решение для некоторых случаев. Что вы думаете об этом?
Думаю, что «некоторых случаев» реально не так и много.

Вот пример с ходу. У меня рендерится кадр и параллельно запущена корутина с квестом, результаты которой прямо сейчас не нужны. Время, отведенное под кадр, заканчивается, и мне нужно принять решение поставить корутину на паузу, чтобы успеть с рендером. Корутины (доступные из коробки) нельзя приостановить снаружи — в корутину нужно передать сообщение (исключение и т. п.), чтобы код внутри отреагировал. Допустим, это удобно при завершении корутины — код внутри лучше знает, как обработать контекст, но приостанавливать удобнее снаружи. В процессе работы движка много чего может случиться, и каждый раз обрабатывать исключения внутри каждой корутины очень неразумно, а если не обрабатывать, они будут мешать плавной работе основного цикла. Здесь нужен менеджер задач, который управляет корутинами, но это уже немного уводит идею в сторону от концепции корутин к концепции более функциональных потоков. Далее зависит от реализации — если обычные потоки тяжелые, можно реализовать свои или доработать так, чтобы синтаксически это выглядело как корутины.

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

Честно говоря, я сомнительно отношусь к тенденции применять универсальные подходы на разных уровнях разработки ПО. Разработка движка может подразумевать концепцию DOD, ручной менеджмент памяти и соответствующий язык, например даже просто С. Здесь нет формального деления игры на состояния типа «главное меню», «игровой цикл», «переход на новый уровень» — есть один большой главный цикл, который параметризуется входными данными. Разработка игры на движке — это уже другие подходы и концепции, например можно ограничиться исключительно графическим интерфейсом, и программисты С здесь не нужны. Более полезен будет скриптовый интерпретируемый язык, с которым можно работать как в режиме REPL, так и компилировать в байткод. Именно здесь можно применять длинные корутины, каждая будет исполняться в своём окружении, контролироваться и синхронизироваться через ядро движка и его API.

Впрочем, реальность состоит не из концепций — нужно видеть и оценивать конкретное решение.