Плюсую. А то ведь у меня тоже есть какая-то стратегия, идущая вразрез с принятой у технологических гигантов, и я могу о ней рассказать. И у оренбуржского разработчика Василия Помидорова есть. И у саратовского тимлида Николая Главнюкова.... Давайте срочно все выйдем и раскроем свои удивительные стратегии, а то ведь весь мир мучается в догадках и спать не может без этого знания...
Пока из интересного - только обманутые ожидания. Я-то думал, у него фамилия Борщ. А оказалось - просто банальный Борх, вот скукота-то....
Хммм, на днях запилил похожее для своего велосипеда, каждый объект в состоянии взаимодействия с другим взаимодействующим объектом отсылает ему список доступных экшенов на выбор, ломать, юзать, экипировать или что там ещё... Даже не подозревал, что это может быть реализовано так, что тормоза будут не при взаимодействии с объектом (у меня там, признаться, дофига абстракций, которые, уверен, дают ощутимый оверхэд), а просто при заходе на уровень =\
Я правильно понял, что ему передается компонент, движение которого надо отслеживать?
Да, почти так. Ну, я передаю ему не сам объект, а хитбокс объекта, для которого движок всё равно на каждом цикле будет расчитывать абсолютную позицию относительно мира, чтобы не делать эти вычисления повторно.
У SpatialGrid именно в том и суть, что мы можем отсекать большие группы объектов из работы над столкновениями, и не пробегаться по всем фрагментам игрового мира, а брать только активные. Поэтому тут однозначно HashMap, а не списки, т.к. предполагается, что ячеек очень-очень много и итерация по всем ним будет однозначно дольше, чем медленный доступ по ключу.
Хотя, я тут недавно разбирал, что можно в ряде случаев HashMap переписать на циклы, но в ходе профилирования у меня никогда не возникало случая, чтобы тормозил именно этот доступ по ключу. Уверен, на каком бы языке вы ни писали, это не станет узким местом. Уж меня Dart совсем не балует беспрецедентной скоростью работы, так что если бы в коде что-то тормозило - это точно сразу стало бы видно.
Но надо заметить, что всё зависит от игры: если у вас RPG, и в центре внимания персонаж, то можно замораживать или откладывать расчёты по фрагментам мира, которые находятся достаточно далеко от него. Если же это, скажем, RTS, то придётся одинаков скрупулёзно расчитывать события на всех участках карты - и тогда уже от итерации по всему списку никуда не деться.
Можно либо полезть в исходники Skia и посмотреть, что же она делает с картинками под капотом, получить некое знание, и жить с ним дальше, т.к. повлиять на этот процесс всё равно не получится на уровне Dart. Мы просто сможем сказать "да, всё плохо" или "да забейте, всё хорошо".
Либо не разрабатывать свой продукт на инструментах, не дающих такого детального контроля, раз для продукта так критично даже то, в каком формате файлы улетают.
На уровне языка Dart есть только разделение на растризованную картинку и объект с записанными командами отрисовки. Всё. Не важно, грузим мы в Flutter jpg, png, bitmap или поток байтов со звуковой карты :-) В конечном итоге он пойдёт на видеокарту либо в одном либо в другом формате, и на то, что у этих форматов под капотом мы никак воздействовать не можем.
Блин, у нас тут Ворд и Ексель в гуглодоках на жабасурипте в браузере требуют 16 гигов оперухи и новый i7, когда всё то же самое работало у меня на пентиум 1 и win 95. Я с каждой новостью о выходе нового процессора всё больше содрагаюсь, что софт теперь станет ещё более херовым, и придется свой комп обновлять просто чтобы работало то, что работало и раньше.
«Нужно бежать со всех ног, чтобы только оставаться на месте, а чтобы куда-то попасть, надо бежать как минимум вдвое быстрее!»
Тут уж надо проводить деконструкцию каждой конкретной игры... Я в своих поделках, в целом, тем же Арканумом и Фолычем вдохновляюсь, но хочется сделать при этом какую-то реюзабельную архитектуру, потому что сама игра, может ,и не будет иметь столько ценности, сколько возможность собрать на ее движке ещё что-нибудь.
А, да, и в каждом квадратике с кирпичами - по 400 объектов, для которых теперь проигрывается анимация и считаются столкновения + потенциальная игровая логика. Итого, сейчас на экране чуть менее чем 30 * 15 * 400 = 18 0000 объектов, котрые все пришлось прогрузить и активировать, а за экраном ещё такая же куча объектов, которые предзагружены, но не рендерятся, а при сдвиге в сторону к ним докидывается ещё приличная пачка...
В общем да, без проработки механизма различных уровней детализации на больших отзумах ничего делать будет невозможно. Но без оптимизаций вообще вы и свои 3 FPS на таких зумах не получите. Тут же не просто тупо картинка, её зумить как раз нет никаких проблем.
Ну если резко отзумить на максималку - то это всё равно что попытаться в Morrowind открыть сразу всю карту и жаловаться, что она долго прогружается. А мне же надо продемонстрировать как-то чисто техническую возможность отзумить ооооочень далеко.
В рамках конкретной игровой механики должно стоять своё ограничение на максимальный зум, в зависимости от целесообразности, а при слишком больших "отзумах" вообще нужно показывать упрощённую карту с меньшей детализацией, но это отдельная и пока не реализованная история.
Ну я про физику сейчас вообще не думаю: если система неудовлетворительно справляется с задачей сказать, перекрываются ли объекты А и Б, а также испытывает трудности с их отображением в достаточном количестве - то о какой тут физике вообще можно говорить)) Хотя у них же есть физический движок forge2D, но мне даже не интересно смотреть, честно, что там по производительности, после того что я увидел в базовом collision detection, обработке касаний с жестами и в рейтрейсинге...
Ну я ж не говорю, что он специально получается запутанный, просто появляется куча дополнительных каких-то телодвижений, нужность которых с первого взгляда не очевидна, особенно для нового человека, который впервые зашел на проект и не вполне понимает, какая проблема этим куском решается, и что вообще такая проблема есть. Вот и кажется при первом взгляде "о боже, что за макаронный монстр, я бы проще сделал!"...
Угу... Я тут недавно писал о том, что даже forEach можно заставить в определённых условиях работать в 15 раз быстрее... Если найти в системе штук 10 таких мест и все затюнить - тоже получится прирост. В общем, каждая кроха может внести свой вклад.
Но языки высокого уровня как-то приучают людей решать проблемы "грубыми мазками", часто отдавая приоритет красивым интерфейсам и синтаксическому сахару, когда во главе угла стоять должно совсем другое. Но более быстрый код порою хрен прочтёшь, даже если это ты сам писал всего лишь вчера :-)
GPU пофигу, он на расслабоне большую часть времени, даже если у вас FPS низкий.
Тут надо вообще начинать с того, что Flutter считает за FPS. Если у вас процессор не успевает обсчитать всю логику за 16 милисекунд, то команды на графический процессор будут формироваться дольше и позже, и GPU очень-очень быстро отрисует вам кадр, но команду на отрисовку он получит позже, чем должен.
Конкретно у Flame, по моим ощущениям, проблемы в том, что:
Разработчики движка и игр на движке как-то в основном мыслят играми уровня "три в ряд", по моим ощущениям. Мы сделали игру, где скачет пять шариков и один квадратик - ура, мы счастливы, это успех, наш движок супер! Это не даёт команде смотреть на некоторые проблемы под другим углом
Как следствие, некоторые архитектурные решения не оптимальны, и в "нагруженных" сценариях приводят к драматическому уменьшению FPS. Но об этом мало кто знает, потому что "мы делаем три в ряд, у нас всё хорошо, Flame - зрелый движок для разработки игр"
На текущий момент цель команды - это стабилизировать имеющуюся ветку разработки, так что на какие-то радикальные архитектурные изменения они не готовы, максимум - вставлять костыли, чтобы предоставить workaround для самостоятельного фикса проблемы. Поэтому ожидать каких-то радикальных улучшений в плане скорости сейчас не стоит.
При этом ребята жестко озабочены следованием какого-то архитектурного плана, которого надо придерживаться, так что даже предложив рабочее решение, которое решает проблему и даёт новые фичи - есть риск получить отказ, потому что "эта архитектура недостаточно хорошо, это решение предлагает пользователю делать игры не так, как их дОлжно делать" и т.п. С этим приходится мириться.
Часть модулей там просто никто не поддерживает, команда маленькая и рук не хватает. Тот же модуль для работы с Tiled ни то жив ни то мёртв, в чатиках порой возникает какое-то движение, какие-то фиксы мелкие, но это всё и близко не напоминает какой-то мощный прогресс.
Flame в основном состоит из "максимально общих решений". Взять те же столкновения объектов. В множестве игр будет достаточно расчитывать столкновения между квадратами и прямоугольниками, а то и просто кругами, но даже такие фигуры Flame обратабывает как абстрактные многоугольники - более общий и более дорогой алгоритм, но зато точно везде будет работать. Аналогично с общим игровым циклом - в процессе там происходит много всякого, что можно бы вообще отключить до возникновения какой-то особой ситуации (например, ресайз окна), но по-умолчанию Flame выполняет этот код на каждом тике - "ну а мало ли чего?" - вот возможности процессора и улетают в трубу...
Вот... и если бы перед разработчиками стояла задача написать конкретную игру с конкретной мезханикой - всё было бы гораздо проще и оптимизированнее, чем при подходе "мы пишем архитектурно и идеологически правильный движок, обязательно делаем ревью каждого мерджреквеста, обязательно пишем документацию и автотесты... и да. нас всего 5 человек, из них трое большую часть времени заняты на основной работе" =)
Привет! Спасибо за упоминание моей статьи)) Однако, хочу заметить, что она относительно старая, и есть более свежие наработки, в которых решена проблема бесконечной динамически подгружающейся карты, вопрос столкновения с неограниченным числом статических объектов + отдельно был сделан тюнинг столкновения между динамическими объектами.
Вот эта статья, а вот демка, которая даже в мобильном браузере работает на приличных FPS, можно по-зумить, увидеть как динамически подгружаются рядомстоящие карты. а все пространство без карт заполняется динамически сгенерированным контентом.
Вот вам и ответ на вопрос, "как тогда работали игры типа baldur gate, Arcanum, fallout, на железе на порядок слабее" - алгоритмы!
Я пока стараюсь сильно об этой либе не кричать, потому что документацию ещё не описал нормально, хотя что-то уже есть + тестирую её в прикладных условиях и по ходу вношу некоторые изменения... некоторые. правда, приходится контрибьютить непосредственно в Flame, что несколько дольше.
В общем, если заморочиться оптимизацией и подобрать алгоритмы, то даже на одном потоке можно иметь в игре 500к объектов и более - и всё будет работать шустро даже в условиях браузера и JS.
Но я бы не сказал, что переписывать Broadphase было легко. Я полтора года назад начал этим развлекаться, и ещё , как видите, в процессе.... Так что со своей стороны все-таки не рекомендую начинать этот путь с нуля, если у вас есть лимиты во времени, сроках, ресурсах и т.п.
Почему же везде, в моё скромное болотце можно устроиться и в день собеседования порой, а день собеседования может случиться тогда же, когда я впервые открою резюме на хх.ру
Но с айчаром в штате да, этот процесс сразу же растягивается....
Собственно, чем я уже с 2019 года и пользуюсь. А уж стекла от подглядывания на смартфоны видел еще ой с каких бородатых времен... В общем, новизна идеи вызывает сомнения)).
Тут понимаете, какое дело, если бы выкинуть из всей этой схемы Битрикс - тогда тонкие оптимизации имели бы смысл. Но даже если просто подключить самые минимальные битриксовые "заголовки" к простейшему php-скрипту, то потребление памяти подскакивало с нескольких мегабайт сразу на тридцатку, а если уж начать использовать эти битриксовые API, то вообще пиши-пропало. Уверен, с 2013 года, когда я последний раз с этим возился, Битрикс в этом вопросе продвинулся вперед и теперь потребляет памяти ещё больше, чем ранее ? Так что если уж вы правда озабочены вопросом памяти, и ваш сервер правда может упасть от растраты пары сотен лишних мегабайт - ну тогда ваши скрипты должны писаться на базе фреймворка, который об этом будет заботиться.
Плюсую. А то ведь у меня тоже есть какая-то стратегия, идущая вразрез с принятой у технологических гигантов, и я могу о ней рассказать. И у оренбуржского разработчика Василия Помидорова есть. И у саратовского тимлида Николая Главнюкова.... Давайте срочно все выйдем и раскроем свои удивительные стратегии, а то ведь весь мир мучается в догадках и спать не может без этого знания...
Пока из интересного - только обманутые ожидания. Я-то думал, у него фамилия Борщ. А оказалось - просто банальный Борх, вот скукота-то....
Хммм, на днях запилил похожее для своего велосипеда, каждый объект в состоянии взаимодействия с другим взаимодействующим объектом отсылает ему список доступных экшенов на выбор, ломать, юзать, экипировать или что там ещё... Даже не подозревал, что это может быть реализовано так, что тормоза будут не при взаимодействии с объектом (у меня там, признаться, дофига абстракций, которые, уверен, дают ощутимый оверхэд), а просто при заходе на уровень =\
Да, почти так. Ну, я передаю ему не сам объект, а хитбокс объекта, для которого движок всё равно на каждом цикле будет расчитывать абсолютную позицию относительно мира, чтобы не делать эти вычисления повторно.
У SpatialGrid именно в том и суть, что мы можем отсекать большие группы объектов из работы над столкновениями, и не пробегаться по всем фрагментам игрового мира, а брать только активные. Поэтому тут однозначно HashMap, а не списки, т.к. предполагается, что ячеек очень-очень много и итерация по всем ним будет однозначно дольше, чем медленный доступ по ключу.
Хотя, я тут недавно разбирал, что можно в ряде случаев HashMap переписать на циклы, но в ходе профилирования у меня никогда не возникало случая, чтобы тормозил именно этот доступ по ключу. Уверен, на каком бы языке вы ни писали, это не станет узким местом. Уж меня Dart совсем не балует беспрецедентной скоростью работы, так что если бы в коде что-то тормозило - это точно сразу стало бы видно.
Но надо заметить, что всё зависит от игры: если у вас RPG, и в центре внимания персонаж, то можно замораживать или откладывать расчёты по фрагментам мира, которые находятся достаточно далеко от него. Если же это, скажем, RTS, то придётся одинаков скрупулёзно расчитывать события на всех участках карты - и тогда уже от итерации по всему списку никуда не деться.
Ну тут нет каких-то особых способов повлиять.
Можно либо полезть в исходники Skia и посмотреть, что же она делает с картинками под капотом, получить некое знание, и жить с ним дальше, т.к. повлиять на этот процесс всё равно не получится на уровне Dart. Мы просто сможем сказать "да, всё плохо" или "да забейте, всё хорошо".
Либо не разрабатывать свой продукт на инструментах, не дающих такого детального контроля, раз для продукта так критично даже то, в каком формате файлы улетают.
На уровне языка Dart есть только разделение на растризованную картинку и объект с записанными командами отрисовки. Всё. Не важно, грузим мы в Flutter jpg, png, bitmap или поток байтов со звуковой карты :-) В конечном итоге он пойдёт на видеокарту либо в одном либо в другом формате, и на то, что у этих форматов под капотом мы никак воздействовать не можем.
Блин, у нас тут Ворд и Ексель в гуглодоках на жабасурипте в браузере требуют 16 гигов оперухи и новый i7, когда всё то же самое работало у меня на пентиум 1 и win 95. Я с каждой новостью о выходе нового процессора всё больше содрагаюсь, что софт теперь станет ещё более херовым, и придется свой комп обновлять просто чтобы работало то, что работало и раньше.
«Нужно бежать со всех ног, чтобы только оставаться на месте, а чтобы куда-то попасть, надо бежать как минимум вдвое быстрее!»
Тут уж надо проводить деконструкцию каждой конкретной игры... Я в своих поделках, в целом, тем же Арканумом и Фолычем вдохновляюсь, но хочется сделать при этом какую-то реюзабельную архитектуру, потому что сама игра, может ,и не будет иметь столько ценности, сколько возможность собрать на ее движке ещё что-нибудь.
Такой слоёный пирог нужен, чтобы сделать иерархию объектов по глубине, считайте это осью Z из 3D графики.
А, да, и в каждом квадратике с кирпичами - по 400 объектов, для которых теперь проигрывается анимация и считаются столкновения + потенциальная игровая логика. Итого, сейчас на экране чуть менее чем 30 * 15 * 400 = 18 0000 объектов, котрые все пришлось прогрузить и активировать, а за экраном ещё такая же куча объектов, которые предзагружены, но не рендерятся, а при сдвиге в сторону к ним докидывается ещё приличная пачка...
В общем да, без проработки механизма различных уровней детализации на больших отзумах ничего делать будет невозможно. Но без оптимизаций вообще вы и свои 3 FPS на таких зумах не получите. Тут же не просто тупо картинка, её зумить как раз нет никаких проблем.
Ну если резко отзумить на максималку - то это всё равно что попытаться в Morrowind открыть сразу всю карту и жаловаться, что она долго прогружается. А мне же надо продемонстрировать как-то чисто техническую возможность отзумить ооооочень далеко.
В рамках конкретной игровой механики должно стоять своё ограничение на максимальный зум, в зависимости от целесообразности, а при слишком больших "отзумах" вообще нужно показывать упрощённую карту с меньшей детализацией, но это отдельная и пока не реализованная история.
Ну я про физику сейчас вообще не думаю: если система неудовлетворительно справляется с задачей сказать, перекрываются ли объекты А и Б, а также испытывает трудности с их отображением в достаточном количестве - то о какой тут физике вообще можно говорить)) Хотя у них же есть физический движок forge2D, но мне даже не интересно смотреть, честно, что там по производительности, после того что я увидел в базовом collision detection, обработке касаний с жестами и в рейтрейсинге...
Ну я ж не говорю, что он специально получается запутанный, просто появляется куча дополнительных каких-то телодвижений, нужность которых с первого взгляда не очевидна, особенно для нового человека, который впервые зашел на проект и не вполне понимает, какая проблема этим куском решается, и что вообще такая проблема есть. Вот и кажется при первом взгляде "о боже, что за макаронный монстр, я бы проще сделал!"...
Угу... Я тут недавно писал о том, что даже forEach можно заставить в определённых условиях работать в 15 раз быстрее... Если найти в системе штук 10 таких мест и все затюнить - тоже получится прирост. В общем, каждая кроха может внести свой вклад.
Но языки высокого уровня как-то приучают людей решать проблемы "грубыми мазками", часто отдавая приоритет красивым интерфейсам и синтаксическому сахару, когда во главе угла стоять должно совсем другое. Но более быстрый код порою хрен прочтёшь, даже если это ты сам писал всего лишь вчера :-)
GPU пофигу, он на расслабоне большую часть времени, даже если у вас FPS низкий.
Тут надо вообще начинать с того, что Flutter считает за FPS. Если у вас процессор не успевает обсчитать всю логику за 16 милисекунд, то команды на графический процессор будут формироваться дольше и позже, и GPU очень-очень быстро отрисует вам кадр, но команду на отрисовку он получит позже, чем должен.
Конкретно у Flame, по моим ощущениям, проблемы в том, что:
Разработчики движка и игр на движке как-то в основном мыслят играми уровня "три в ряд", по моим ощущениям. Мы сделали игру, где скачет пять шариков и один квадратик - ура, мы счастливы, это успех, наш движок супер! Это не даёт команде смотреть на некоторые проблемы под другим углом
Как следствие, некоторые архитектурные решения не оптимальны, и в "нагруженных" сценариях приводят к драматическому уменьшению FPS. Но об этом мало кто знает, потому что "мы делаем три в ряд, у нас всё хорошо, Flame - зрелый движок для разработки игр"
На текущий момент цель команды - это стабилизировать имеющуюся ветку разработки, так что на какие-то радикальные архитектурные изменения они не готовы, максимум - вставлять костыли, чтобы предоставить workaround для самостоятельного фикса проблемы. Поэтому ожидать каких-то радикальных улучшений в плане скорости сейчас не стоит.
При этом ребята жестко озабочены следованием какого-то архитектурного плана, которого надо придерживаться, так что даже предложив рабочее решение, которое решает проблему и даёт новые фичи - есть риск получить отказ, потому что "эта архитектура недостаточно хорошо, это решение предлагает пользователю делать игры не так, как их дОлжно делать" и т.п. С этим приходится мириться.
Часть модулей там просто никто не поддерживает, команда маленькая и рук не хватает. Тот же модуль для работы с Tiled ни то жив ни то мёртв, в чатиках порой возникает какое-то движение, какие-то фиксы мелкие, но это всё и близко не напоминает какой-то мощный прогресс.
Flame в основном состоит из "максимально общих решений". Взять те же столкновения объектов. В множестве игр будет достаточно расчитывать столкновения между квадратами и прямоугольниками, а то и просто кругами, но даже такие фигуры Flame обратабывает как абстрактные многоугольники - более общий и более дорогой алгоритм, но зато точно везде будет работать. Аналогично с общим игровым циклом - в процессе там происходит много всякого, что можно бы вообще отключить до возникновения какой-то особой ситуации (например, ресайз окна), но по-умолчанию Flame выполняет этот код на каждом тике - "ну а мало ли чего?" - вот возможности процессора и улетают в трубу...
Вот... и если бы перед разработчиками стояла задача написать конкретную игру с конкретной мезханикой - всё было бы гораздо проще и оптимизированнее, чем при подходе "мы пишем архитектурно и идеологически правильный движок, обязательно делаем ревью каждого мерджреквеста, обязательно пишем документацию и автотесты... и да. нас всего 5 человек, из них трое большую часть времени заняты на основной работе" =)
Привет! Спасибо за упоминание моей статьи)) Однако, хочу заметить, что она относительно старая, и есть более свежие наработки, в которых решена проблема бесконечной динамически подгружающейся карты, вопрос столкновения с неограниченным числом статических объектов + отдельно был сделан тюнинг столкновения между динамическими объектами.
Вот эта статья, а вот демка, которая даже в мобильном браузере работает на приличных FPS, можно по-зумить, увидеть как динамически подгружаются рядомстоящие карты. а все пространство без карт заполняется динамически сгенерированным контентом.
Вот вам и ответ на вопрос, "как тогда работали игры типа baldur gate, Arcanum, fallout, на железе на порядок слабее" - алгоритмы!
Я пока стараюсь сильно об этой либе не кричать, потому что документацию ещё не описал нормально, хотя что-то уже есть + тестирую её в прикладных условиях и по ходу вношу некоторые изменения... некоторые. правда, приходится контрибьютить непосредственно в Flame, что несколько дольше.
В общем, если заморочиться оптимизацией и подобрать алгоритмы, то даже на одном потоке можно иметь в игре 500к объектов и более - и всё будет работать шустро даже в условиях браузера и JS.
Но я бы не сказал, что переписывать Broadphase было легко. Я полтора года назад начал этим развлекаться, и ещё , как видите, в процессе.... Так что со своей стороны все-таки не рекомендую начинать этот путь с нуля, если у вас есть лимиты во времени, сроках, ресурсах и т.п.
Реклама от гриппа?...
...напрягся, вспоминая, когда в последний раз вообще видел телевизор или незаблокированный видос в интернете....
Почему же везде, в моё скромное болотце можно устроиться и в день собеседования порой, а день собеседования может случиться тогда же, когда я впервые открою резюме на хх.ру
Но с айчаром в штате да, этот процесс сразу же растягивается....
...я один бегло прочитал "в виде робокишок"?...
Собственно, чем я уже с 2019 года и пользуюсь. А уж стекла от подглядывания на смартфоны видел еще ой с каких бородатых времен... В общем, новизна идеи вызывает сомнения)).
Тут понимаете, какое дело, если бы выкинуть из всей этой схемы Битрикс - тогда тонкие оптимизации имели бы смысл. Но даже если просто подключить самые минимальные битриксовые "заголовки" к простейшему php-скрипту, то потребление памяти подскакивало с нескольких мегабайт сразу на тридцатку, а если уж начать использовать эти битриксовые API, то вообще пиши-пропало. Уверен, с 2013 года, когда я последний раз с этим возился, Битрикс в этом вопросе продвинулся вперед и теперь потребляет памяти ещё больше, чем ранее ? Так что если уж вы правда озабочены вопросом памяти, и ваш сервер правда может упасть от растраты пары сотен лишних мегабайт - ну тогда ваши скрипты должны писаться на базе фреймворка, который об этом будет заботиться.
А, ну да. Согласен ?