24 декабря 2023 г. Архивач восстановлен после серьёзной аварии. К сожалению, значительная часть сохранённых изображений и видео была потеряна. Подробности случившегося. Мы призываем всех неравнодушных помочь нам с восстановлением утраченного контента!
Как это сделано, в чем секрет архитектуры кода? Несколько миллионов объектов с кучей взаимодействий друг с другом, обновляется 60 раз в секунду и не тормозит. Каким образом? Давайте обсудим.
>>644712 (OP) Просто не надо пользоваться памятью как распиздяй. Ну и по возможности батчить все что можно, конвейеры обрабатывать группами, а не каждый по отдельности.
>>644712 (OP) Секрет, в том, что большая часть объектов не взаимодействует. Их следующее состояние определяется предыдущим состоянием и прошедшим временем. Поэтому нет необходимости обновлять 60 раз в секунду. Видел SwarmSim? Пока пользователь не вмешивается в ход вещей, состояние полностью детерминировано.
>>644714 В факторио сложнее выразить функцию x(t), ибо надо учитывать повороты конвейеров, кол-во предметов на линии. В сворм сим действительно хуйня, экспоненциальную или линейную формулу размножения бахнул, и считай сколько хочешь. Факторио все же более динамичная, ибо объекты могут рандомно на конвейере появляться/уходить.
>>644712 (OP) >Несколько миллионов объектов Ты считал? Тысяча объектов хотя бы наберется? Обычным циклом обновления можно обновлять десятки, если не сотни тысяч объектов безо всякой оптимизации. Ты недооцениваешь современные процессоры.
>>644742 Да считал, у меня на одиночной карте 1100000+ объектов было. Сейчас появилась возможность играть в онлайн на супер огромных картах для двухсот человек. И это все дело не тормозит.
>>644715 Сложнее, не значит невозможно, конечно там не все на 100% можно выразить через x(t), но многое все же можно. В каких то девблогах, они писали о чем-таком, мол поезда, когда их не было видно ездили неправильно, телепортировались через пробки на развязках или типа того. И на ковеере каждый итем не просчитывается каждый тик, а считается сколько итемов на белт попало, с какой скоростью они движутся, в зависимости от заполненности белта. Короче секрет в том, что не симулировать, то что можно рассчитать.
>>644743 Важно не сколько объектов на карте, а сколько событий происходит за один кадр. Если посчитать, то даже для таких игр как factorio будет совсем незначительные числа.
>>644712 (OP) Не интересовался. Скорее всего просто посчитали, сколько всего влезает в кеш линию процессора, сколько всего влезает в батчинг на видеокарте. Какие нибудь трюки, с расчетами через кадр, каждый четный кадр просто ехать по прямой.
>>644820 >на каком-нибудь каловом юнити такое не запилишь Анус ставишь? Я в этот симулятор экселя не играл, конечно же, но судя по видео, там просто трансформация одного типа ресурса в другой. Что-то типа продюсер-консумера. Там самое сложное - это сделать конвеер. С чего такие ньюфаги как ты решили, что это что-то сложное - я не понимаю.
>>644899 Потому что ты не пытался этого сделать и от того у тебя типичный эффект Даннинга-Крюгера, выразающийся простой и известной фразой: "Да что там эта ваша виндовс? Мы такую же с приятелем на коленке за пару ночей напишем! Даже лучше."
>>645011 >>644881 Хотя, сейчас проверил без использования fpu — там действительно проц делит медленнее. Но поскольку проц без фпу работает только с целыми числами, то твое замечание >по возможности заменяй деление (10/2) на умножение (10*0,5) все равно является ошибочным.
>>645051 главное что код читается проще, чем непонятное деление на магическую хуиту.. зачастую узкие места не в единичных делениях и умножениях, че вы так приебались к этому
>>645055 Да никто не приебался, просто ищем истину в споре. В общем, положняк такой: заменять деление умножением имеет смысл только в тех случаях, если множители это целые 64-битные (или 32, в зависимости от битности вашей программы) числа, и если заведомо не будет при этом переполнения. В остальных случаях выигрыша не будет, потому что при умножении вещественных чисел будет задействован фпу, который в разы медленнее цпу. Такие дела. Таким образом, получаем абсолютную бессмысленность замены деления на умножение, за исключением особых случаев, когда используется битовый сдвиг или магическое число. Поправьте, если ошибаюсь.
>>645059 Если там целочислннная константа, то компилятор сам заменит деление на умножение на (1/x). Т.е. при делении на 5 там будет что то вроде умножения на 0xccccccccd и сдвиг на пару битов. >>645055 > че вы так приебались к этому Потому что это было оформлено в отдельный пост как ультимативный совет, который по факту был бы актуален лет 20 назад.
>>645065 >Если там целочислннная константа, то компилятор сам заменит деление на умножение на (1/x). Т.е. при делении на 5 там будет что то вроде умножения на 0xccccccccd и сдвиг на пару битов. Все верно братишка, я это и имел в виду под магическими числами.
>>645065 > было оформлено в отдельный пост как ультимативный совет, который по факту был бы актуален лет 20 назад По факту ты хуя пососал. Потому что по факту это работает у нативных господ, а у фреймворкохолопов действительно разницы нет, что умножение, что деление одинаково в 10 раз медленнее: >>644995
Уважаемые анончики. А что находится в ядре у этой штуки ? с точки зрения программирования. Если про рендер боле менее понятно, что можно применить всякие трюки (которые были в одном видео выше) То вот как они спроектировали саму архитектуру игры? Типо там наверно есть класс Game с методами run stop или что то такое, где про это можно прочитать? Или там в основе всего многопоточный Event обюработчик?
>>645272 >>645327 >>645331 Спасибо за ответы. До сих пор не могу понять, как соединить ECS с рендером. Хотел запилить небольшую игру и взять entt + sdl, но как их вместе подружить и как организовать - картинки в голове нет.
Прямые руки. Вот и все - это весь секрет. Потому что игру делал программист, а не обезьяна, тыкающая на кнопочки в визуальном редакторе, и делающая 2д-игру на движке на фреймворке на фреймворке на фреймворке... Нет, серьезно, иной раз запускаешь примитивную 2д-парашу, а она тормозит как Крайзис. Если конкретнее, то я считаю, что здесь все так быстро, потому что каждый кадр выполняется за O(~1), а не за O(n^n), потому что нет поиска по массивам объектов. Каждый объект содержит прямую ссылку на тот объект, с которым взаимодействует, тот - на третий и и тд, пока не будет достигнута определенная глубина, критерий или взаимодействие не закольцуется.
я просто напомню что в таких играх не нужно делать расчеты каждый кадр (один кадр занимает 16мс - что там игрок увидит?).
достаточно делать расчеты каждую секунду - то есть каждые 60 кадров, размазываем эти расчеты на эти 60 фпс.
А если эти расчеты делать еще и на разных ядрах процессора (например разбиваем игровое пространство на регулярную сетку - обрабатываем набор ячеек на своем процессе)
>>646927 Ты в факторио играл вообще? Там миллионы деталей идут по конвееру в реальном времени, если это будет раз в секунду апдейтиться, никто в это играть не будет.
>>646930 проигрывание анимации на экране не равно выполнению логики. На экране ты видишь только анимацию спрайта - это дешевая операция даже если у тебя вдруг будет миллион видимых анимированных спрайтов (ну конечно если игру делаешь не на годоте который не знает о батчинге)
Остальное - это логика. Если у тебя руда перерабатывается 15 секунд - нахрена общитывать ее логику обработки чаще 1секунды? игрок не заметит мелких погрешностей во времени
(а если включить мозг, можно еще и сделать обработку с разными приоритетами по времени - например руда обрабатывается 15 секунд. Делаем три очереди. от 1 до 10 секунд первая очередь. от 10 до 13 перекидываем эту руду на вторую очередь. от 13 до 15 - перекидываем на третью очередь.
Первую очередь мы спокойно можем обрабатывать раз в 5 секунд (даже раз в 10 секунд). Это сразу откинет 60-80% работы Вторую очередь мы уже обрабатываем более аккуратно - раз в секунду или даже 2 раза в секунду Третья очередь - это все то что сейчас завершится и очень важно точное время - их мы уже обрабатываем каждый кард, и обычно это будет 10-100 операций
>>646930 теперь про движующийся конвеер. на экране ты видишь только анимацию. не более.
В логике кода все что нужно знать - это время, за которое деталь должна пройти от точки А (начало конвеера) до точки Б (конец конвеера) и длину всего конвеера.
Зная время и длину можно определить дельту движения. Дельту не надо считать каждый кадр (конвеер же не ускоряется.... хотя даже если бы ускорялся, то это тоже решаемо)
И просто сдвигать спрайт руды на конвеере каждый кадр
>>646977 >>646978 В факторио всё должно быть ещё проще. Ведь всё, кроме игроков (и, может быть, мобов) детерменированно. Вот взять и поделить весь мир на чанки разных или одинаковых размеров, вывести для них формулы с коэффициентами и готово. Когда игрок захочет изменить что-то, то изменятся формулы во всех зависимых чанках.
>>646977 Двачую, не знаю почему тот шизик решил что если много объектов то и рассчеты должны вестись чаще, если там завод выдает объект в дискретные моменты времени, и находится все на грубо говоря тайлах. То там все четко детерменировано, там же неоткуда взяться микроподергиваниям, это же не рассчет физики теннисного мяча.
>>647172 Что ты там интерполировать собрался, долбоёбушка? Еще раз. Есть конвеер, по нему идет миллион деталей в реальном времени. Сбоку конвеера стоит тысяча механических рук, которые работают по своему алгоритму, выхватывают рандомные детали в зоне досягаемости с конвеера, перемещают их на другие конвееры, нарушая состояние основного конвеера. То, как они работают - зависит от состояний конвееров, куда они переносят детали - они могут остановиться, если конвееры заполнены, продолжают работать, если место освободилось. Как ты это интерполировать собрался? Тебе в любом случае придется обсчитывать эти руки и детали в реальном времени каждый фрейм, если хочешь чтобы все работало плавно как в оригинале. Я понимаю, что с дивана просто кукарекать, но ты бы постыдился хоть немного пороть хуйню.
>>647201 Проиграл с безыгорного кукаретика, не сделавшего ничего в своей жизни. Понятно, что с дивана просто рассуждать и мечтать о том, какой ты охуенный разработчик с гениальными идеями. А ты попробуй что-нибудь сделать на практике, хотя бы не игру, а играбельный прототип из одного уровня, сразу жиденько сходишь под себя и пойдешь обратно на диван мечтать.
>>647252 Посчитал, блеать. Старые i7 100'000 Million instr. per second Поделим на среднюю длину инструкции в тактах (примем 10) Поделим на 100 (фпс) Вот и 100 миллионов. Умножим на 4 ядра 400 миллионов на асме переместить 2 координаты, скажем 20 инструкций 20 миллионов объектов можно двигать не запариваясь особо на старом компе
>>647259 МИПСы дохуя пиковые показатели. Для среднего кода можно порядок или два убирать. Плюс скорее всего в нем уже заложена многопоточность. Так что даже при таких подсчетах стоит скорее на 1 лям объектов рассчитывать.
>>647259 >на асме переместить 2 координаты, скажем 20 инструкций но зачем перемещать на асме (да и вообще на процессоре) если эту задачу можно перенести на видеокарту? :-/
(на самом деле на видеокарте через вычислительный шейдер идеально обрабатывать конвееры - так как это заложено в архитектуру самой видеокарты и она лучше работает с этим чем линейный процессор)
>>647295 Не знаю, анон, почему то кажется сомнительным что вся логика может работать в гпу. 20 инструкций я и имел в виду некое планирование координат.