Pull to refresh
64K+
572
Sergei Kushnirenko@dalerank

Люблю (ш)кодить, алгоритмы и старые авто.

378,3
Rating
662
Subscribers
Send message

Архитектурные компромиссы в разработке игр

Level of difficultyEasy
Reading time107 min
Reach and readers21K

У меня есть книга, которая называется Game++ и несколько статей, где я разбирал какие паттерны применяются в играх и движках. В книге почти сто страниц отведено про эти самые паттерны и подробно рассказано какие они бывают, как выглядят в C++, где у них подводные камни и как их применять. Т.е. ровно те мелочи реализации, которые обычно интересно перечитать, когда вы в очередной раз решаете делать фабрику отдельным классом или попробовать обойтись std::function. Когда я её писал, мне казалось, что это будет очень полезный практический текст, и он таким и получился, и человек с опытом довольно быстро находит там нужное.

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

Если вам вдруг надоест читать эти 106 минут, там в конце есть TL;DR секция, где собрано краткое описание.

Больше паттернов, богу паттернов

Трое в лодке, нищета и собаки (с)

Level of difficultyEasy
Reading time7 min
Reach and readers25K

Недавно я был на отраслевой конференции, где встретил пару знакомых, с которыми начинал ещё в питерских студиях. В отличие от меня, который всегда работал на «дядю», они в какой-то момент выбрали тернистый путь создания инди, своих студий и (судя по тому, как они заказывали напитки) этот путь оказался значительно тернистее, чем выглядел десять лет назад. Хотя глаза у них горели ровно так же, как тогда. Что тогда, что сейчас эти горящие глаза одновременно вызывали и зависть, и лёгкое подозрение, что они просто не успели ещё по-настоящему устать.

Потом мы разговорились. Пусть будет Костя, с которым мы когда-то делали "симсов", уже год пилит гачу для очередных китайцев, чтобы платить зарплаты своим ребятам. А пусть будет Лёша, держит студию из четырёх человек и занимается код-ревью аишных коммитов, но теперь уже для индийских ребят, только тех, которые в солнечной Калифорнии, а не в прекрасном Дели. Тут я вспоминаю своё четвертьвековое легаси, и когда мне говорят, что искусственный интеллект скоро заменит программистов, тихо радуюсь: после стольких лет разработки большинство систем там устроено настолько коряво, что любая нейросеть сжирает все токены, просто пытаясь осмыслить, куда она попала. А значит, как минимум до конца поддержки игры у меня будут задачи.

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

Читать далее

Непослушный using

Level of difficultyEasy
Reading time11 min
Reach and readers16K

В прошлой статье я разобрал, как работает квалифицированный поиск и как using namespace участвует в нём только в качестве запасного варианта, когда собственных объявлений в указанной области нет. Компилятор сначала смотрит, что объявлено непосредственно в текущем контексте, и только при неудаче переходит к именам, подмешанным через директиву using. Казалось бы, схема прозрачная и предсказуемая: есть область поиска, есть приоритет явных объявлений, есть «правило N-объявлений» как страховка.

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

Но тут есть скользкое место, о котором умалчивает большинство учебников и курсов, обходя вниманием работу с операторами. Например оператор сдвига влево <<, может быть определён в любом пространстве имён.

ох уж этот using

Про 10x программистов

Level of difficultyEasy
Reading time5 min
Reach and readers29K

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

Меня в этой теме всегда смущало, что под 10x часто пытаются запихнуть вообще всё: скорость написания кода, умение чинить баги, знание проекта, способность не делать больно проекту, опыт коммуникации с менеджментом, архитектурный вкус и опытный опыт, готовность сидеть ночью и баф на везение. А потом из этого делают красивую легенду про человека, который работает в десять раз быстрее остальных.

Мечты ПМа, это все же мечты, а в реальной жизни всё скучнее и интереснее одновременно. Я видел людей, которые действительно делали задачи сильно быстрее других. Видел в open-source, видел в игровых проектах, видел на старом коде, видел в маленьких библиотеках. Но почти всегда причина была не в том, что человек родился с коэффициентом x10 и бафом на скорость набирания буковок, а в том, что за его скоростью стоял какой-то накопленный капитал, вроде знания проекта, инструмента, узкой экспертизы или годов ковыряния в похожих задачах.

Читать далее

Как работают с памятью в игровых консолях

Level of difficultyEasy
Reading time24 min
Reach and readers24K

Самая продаваемая консоль поколения имела худшую архитектуру памяти, самая технически грамотная продалась хуже всех, а самая простая в разработке принадлежала компании которая никогда раньше не делала консолей. Вы наверное узнали тут PS2, GameCube и Xbox.

Иногда шутят, что когда разработчик переносил игру с PS2 на Xbox, то первое что он делал это выбрасывал систему управления памятью и писал новую с нуля, потому что 32Мб плюс 4Мб плюс 2Мб не помещается в 64Мб.

Для чтения этой статьи вам не потребуется знать ассемблер или работать с конкретными SDK. Достаточно понимать, что такое указатель, чем стек отличается от кучи и что рендерить геометрию параллельно с её обновлением плохая идея, и что классические GPU и CPU паттерны работы по-разному нагружают память.

Там, где в тексте встречается псевдокод, он нужен для иллюстрации концепции, а не как готовый код для компиляции. Я уже подзабыл конкретные константы и названия буферов на каждой платформе, но паттерн работы всегда был примерно одинаковый.

Читать далее

Как не перепутать мечту, портфолио и вторую работу

Level of difficultyEasy
Reading time8 min
Reach and readers15K

У разработчиков игр есть довольно странная профессиональная болезнь, когда после рабочего дня, проведенного за тасками и кодом хочется открыть ноутбук и снова писать код, только уже «для себя». Большинство моих коллег по цеху, придя домой тратят 1+ часов чтобы: поделать свой движок или переписать/помодить/любимую/старую/новую/другую (нужное подчеркнуть) игру или собрать какую‑нибудь библиотеку, или починить инструмент, который всех раздражает. Не знаю, может эта заразно и гуляет по студиям, а может это просто кусочек творческой атмосферы, который ты уносишь из офиса, и он некоторое время живет вне этого пространства.

Часто бывает что маленький проект, который был на «пару вечеров» внезапно превращается в несколько лет жизни. Я много раз видел это снаружи и изнутри: СorsixTH, 0AD, Akhenaten, Cytopia, StoneKingdoms, (тут больше open‑source‑games) очень разные проекты (из тех куда я комитил), но все они хорошо показывают одну и ту же вещь, что пет‑проект почти никогда не остаётся «просто маленькой штукой». Он либо умирает, либо начинает требовать от автора взрослого отношения и тянет за собой архитектуру, поддержку, документациу, общение с коллегами по цеху и теми кто просто играет, разбора багов, релизов и неприятных компромиссов.

И главный вопрос тут не «как найти мотивацию», а точно ли тебе это нужно?

Читать далее

Простой поиск имен в С++

Level of difficultyHard
Reading time11 min
Reach and readers12K

Это продолжение темы начатой в статье Важны ли компилятору имена, и продолженной в Ночью все кошки серы, а using'и одинаковы, и далее в Компиляторы тоже путаются в именах. Если не читали, то лучше будет пробежаться по диагонали. Теперь вот мы подобрались к такой интересной теме, как квалифицированный и неквалифицированный поиск.

Что такое простой поиск(неквалифицированный) имени n в области S? Это механизм компилятора, который находит все объявления n, находящиеся непосредственно в этой области. Просто? С виду да, но даже этот простой механизм часто работает не так, как ожидает разработчик.

Например, у нас есть пространство имён N и локальная переменная N. Они могут сосуществовать вместе? Могут, потому что находятся в разных областях видимости. А пространство имён и глобальная переменная с тем же именем могут? Как же мы докатились до жизни такой, давайте разбираться.

Вот такой простой с++

Scene not Graph

Reading time13 min
Reach and readers15K

Scene not Graph. Место для запятой выбирайте сами.

Scene Graph как концепция появился в академической и промышленной среде, где компьютерная графика использовалась для CAD-систем, научной визуализации и инженерного проектирования, а потом уже пришел в игры. Задачи отрисовки мира и его объектов в CAD были совсем другие и нужно было описывать, например, сложные сборки из деталей, с шестерней в редукторе, редукторе в двигателе, двигателе в машине, и такая модель отражала физическую реальность, которая играм была нужна с приставкой "не". Причины, по которым Scene Graph пришел и остается в играх довольно банальные, этой концепции учат в университете, и многие кто пришел делать игры, естественно знакомились с ней раньше других. На курсе компьютерной графики ИТМО эту модель давали уже на втором месяце и объясняли её полгода, а остальные пять или шесть техник давали всего месяц и в конце года.

Но проблема была в том, что в CAD иерархия объектов это буквальное описание устройства изделия, и перенос этой модели в игры в целом и в игровую графику в частности был концептуальной ошибкой с самого начала. Поняли это достаточно поздно, чтобы эта модель успела поселиться в мозгах целого поколения, выпуск OpenGL в 1992 году с принципиально другой моделью (immediate mode) стал первым сигналом что играм надо двигаться в другую сторону, но инерция Scene Graph в движковой архитектуре сохраняется до сих пор.

Читать далее

Компиляторы тоже путаются в именах

Level of difficultyHard
Reading time10 min
Reach and readers10K

Это продолжение темы начатой в статье Важны ли компилятору имена, и продолженой в Ночью все кошки серы, а using'и одинаковы, и если вам нужна полная картина, как компилятор превращает текст в программу, то без понимания поиска имён (name lookup) дальше двигаться уже не получится.

Имена в тексте исходника это просто удобные ярлыки для людей: переменные, функции, типы. Но для компилятора имя является точкой входа в довольно сложный алгоритм, который должен однозначно определить, что именно вы имели в виду. И вот здесь начинается самое интересное: одинаково написанное имя в разных контекстах может означать совершенно разные вещи, а иногда даже не означать ничего вовсе, в зависимости от того, где и как оно используется.

C++ в этом месте особенно коварен. Язык рос десятилетиями, и правила поиска имён эволюционировали вместе с ним: добавлялись пространства имён, шаблоны, ADL, двухфазный поиск. Всё это не просто усложнило модель, оно сделало её местами неинтуитивной даже для опытных разработчиков, добавим сюда еще, что разные компиляторы исторически реализовывали эти правила (по-своему) по-разному, и часть этих различий до сих пор всплывает в коде.

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

Какой-то странный, этот ваш с++

Лишние вычисления

Level of difficultyEasy
Reading time12 min
Reach and readers16K

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

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

Ответом на это стало не ускорение памяти, а усложнение самих процессоров, которые перестали быть просто пассивными исполнителями кода и стали решать задачи управления потоком данных: выполнять инструкции вне порядка, переупорядочивать зависимости и на каком‑то этапе подошли к идее спекулятивно исполнять код, который, возможно, вообще не понадобится.

Предсказание ветвлений стало один из ключевых механизмов в этой системе, которая должна была снять часть времени простоя потока вычислений, но если удачное предсказание стало возможностью начать дорогие загрузки заранее и скрыть их латентность, то ошибка предсказания скрывает не только потерянные такты, но и зря использованные ресурсы памяти: шину, буферы загрузки, пропускную способность контроллера и сами кэш‑линии, которые могли бы быть заняты полезными данными.

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

Если вы собираетесь писать branchless код, надо помнить как именно спекулятивное выполнение и предсказание ветвлений взаимодействуют с подсистемой памяти, потому что «лишняя работа» иногда ускоряет программу, а в некоторых случаях попытка сделать код более «предсказуемым» приводит к обратному эффекту.

Читать далее

Ночью все кошки серы, а using'и одинаковы

Level of difficultyEasy
Reading time4 min
Reach and readers11K

Одной из самых сложных частей C++ до сих пор считаются правила поиска имён, и ошибки связанные с name lookup проявляются обычно уже в рантайме. Код компилится и даже работает какое-то время, но при свете луны ведёт себя не так как ожидает программист. За простыми идентификаторами скрывается многоуровневая система областей видимости, категорий имён и специальных правил, и очень многое в нашем текущем стандарте растёт прямиком из восьмидесятых, частенько без изменений. Давайте посмотрим как компилятор видит имена в C++, какие области видимости существуют и почему они ведут себя по-разному.

В C++ есть несколько типов областей видимости, вы наверное сходу назовёте глобальное пространство имён, область параметров шаблона, область видимости класса и область параметров функции, но также есть блочная область видимости и область видимости перечислений. Между этими областями есть исторически сложившаяся асимметрия, которая частенько удивляет: два объявления using, которые вводят одно и то же имя в одну и ту же область видимости внутри пространства имён компилятор съест без возражений, но если попытаться сделать то же самое других областях видимости, то получим ошибку на повторное объявление. В серии статей про "нескучное программирование" я разбираю скользкие случаи и как мы докатились до такого. Это продолжение темы, начатой в "Важны ли компилятору имена", поэтому чтобы картинка была цельной, лучше пробежать её по диагонали.

Читать далее

Записки ездового кота, Артёмка-электроник

Level of difficultyEasy
Reading time10 min
Reach and readers7.9K

Пятничное, давно я что-то не писал про приключения ездового кота, но недавно наткнулся на  очередной пост про нейросети и искусственный интеллект, который теперь умеет диагностировать болезни, предсказывать поломки оборудования и вообще решать задачи, для которых раньше требовались годы человеческого опыта. Автор распинался про триллионы параметров, петабайты данных и революцию в промышленности, а я читал, усмехался и вспоминал, что в начале нулевых был свой “ии” для диагностики неисправностей, только работал он не на GPU-кластерах и обучался не на размеченных датасетах, а на похвале старого инженера, с которым был на дежурствах и не мешал делать выводы.

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

Не только про котов

Нескучное программирование. Обобщения (ч.2)

Level of difficultyHard
Reading time26 min
Reach and readers9.9K

Это не отдельная статья, а продолжение статьи про теорию объектов в с++, почему объекты в плюсах такие какие есть. Все завершенные главы я также выкладываю на github'e в английском и русском варианте. Продолжаем разбираться в теории С++...

Отдельного разговора заслуживает идентичность объектов, потому что в реальном мире конкретные сущности обладают идентичностью и Сократ останется Сократом независимо от того, перекрасил ли он волосы, сменил адрес или умер, а государство остаётся тем же государством, даже если меняет флаг, конституцию или размер населения. 

Чтобы отразить это в программе, объекты, представляющие конкретные сущности, нуждаются в своём определении идентичности, которая отделена от текущего состояния. Удобный способ ввести такую идентичность будет сделать некий токен идентичности, уникальное значение, которое выражает "кто это", а не "в каком он сейчас состоянии". Таким токеном может быть, например, адрес объекта в памяти, индекс в массиве, или табельный номер сотрудника в кадровой системе и проверяя равенство токенов идентичности, мы фактически проверяем тождественность объектов: один и тот же объект или разные. 

На протяжении жизни программы конкретный объект может менять свои токены идентичности, потому что его могут переместить в другой участок памяти или переложить из одного контейнера в другой, или назначить ему новый идентификатор, но логическая идентичность сохраняется, если мы поддерживаем сопоставление между "старым" и "новым" токеном.

Читать далее

Почему у нас нет кешей L5?

Level of difficultyEasy
Reading time13 min
Reach and readers29K

Вы не задавались на первый взгляд тривиальным вопросом: почему в процессоре есть уровни кэша, если можно было бы взять один большой? Ответ на этот вопрос тесно переплетается с физикой полупроводников, историей архитектуры процессоров и тем, как компиляторы научились использовать иерархию памяти.

Первое, что нужно понять: процессор не является абстрактным вычислителем, а вполне себе реальный кусок кремния размером примерно с ноготь большого пальца, на котором размещены миллиарды транзисторов и когда мы говорим «данные передаются из памяти в регистр», то мы буквально имеем в виду, что электрический сигнал проходит по металлическому проводнику длиной в несколько миллиметров или сантиметров. И это тоже расстояние, пусть и ничтожное по человеческим меркам, но при тактовой частоте 3–4 ГГц оно уже имеет значение, просто потому что за один такт сигнал в идеальных условиях будет проходить всего 10 сантиметров, а в металлическом проводнике на кристалле и того меньше.

Другими словами, путь сигнала по проводу между двумя точками на чипе не будет мгновенной телепортацией данных, потому что это физическая среда с задержкой, сопротивлением и энергопотреблением, пропорциональным длине, и именно это физическое ограничение делает один большой кэш невозможным, и чем дальше от ядра лежит ячейка памяти, тем дольше нужно ждать ответа.

Читать далее

Нескучное программирование. Обобщения (ч.1)

Reading time22 min
Reach and readers13K

Представьте на минуту, что C++ — это не набор странных ключевых слов и ошибок линковки, а всего лишь ещё один способ поговорить о мире вокруг нас: о людях, числах, цветах, событиях и котах. Мы привыкли думать о программировании как о чём‑то сугубо техническом, где важно запомнить синтаксис, расставить точки с запятой и “угадать”, чего сейчас хочет компилятор. 

Но если задать себе вопрос «а чем вообще оперирует программа?», внезапно выясняется, что за всеми этими int, struct и template прячутся довольно простые и понятные идеи: вещи, их свойства, группы похожих вещей и правила, по которым одни вещи превращаются в другие.

И попробовав объяснить, что такое объекты, типы и прочие фундаментальные понятия информатики, неизбежно приходится выходить за рамки чисто технического языка и говорить о более общих категориях идей, с которыми человечество работает уже тысячи лет, и именно здесь нам пригодятся слова «сущность», «вид» и «род». 

Когда философы и логики говорят об абстрактных сущностях, они имеют в виду индивидуальные вещи, которые не существуют в пространстве и времени так, как существуют стол, человек или компьютер, а как нечто неизменное: например, число 13 или сам по себе синий цвет не родились в какой‑то момент и не "умирают" через какое‑то время, это не объекты физического мира, а идеи, с которыми мы работаем в голове и в математике. 

Читать далее

О радости программирования и невесомости достижений

Reading time8 min
Reach and readers21K

Я отношусь к тому постепенно вымирающему поколению разработчиков, которым выпала странная привилегия писать программный код в его самой чистой, первозданной форме, создавать каждую строчку вручную, собственными руками и головой, без всяких умных копайлотов-помощников, без промптов, без автодополнения, которое якобы знает что ты хочешь написать лучше тебя самого. Голая логика алгоритмов, литры выпитого кофе и мигающий курсор в пустом файле открытой IDE, когда мозг пытается удержать в своей “оперативной” памяти всю архитектуру системы целиком. 

И я искренне рад, что прошёл через этот опыт в своё время, что успел застать ту эпоху, когда программирование ещё было настоящим ремеслом, а не управлением автоматическими генераторами кода. В те совсем недавние времена, которые теперь уже кажутся какой-то историей мамонтов, я писал код постоянно: в офисе, дома, когда был под стрессом от мажора, когда был счастлив от решения сложной задачи, иногда во снах продолжал что-то отлаживать и искать баги.

Я делал это не потому, что меня кто-то заставлял или потому что так требовало начальство, а просто потому что сам процесс создания работающей системы из ничего, исправление хитрых багов, построение сложных систем из простых компонентов – всё это было по-настоящему весело, приносило какое-то детское удовольствие от созидания. Когда наконец откидываешься в кресле от монитора после многих часов работы, смотришь на то что построил своими руками, и видишь что всё работает как задумано, и думаешь: "Да, я, блин, чертов гений, это всё сделал только я, и никто мне не помогал". Ну разве что SO и немного гуглежки.

Читать

Писать код проще, чем книгу о том, как писать код

Level of difficultyEasy
Reading time4 min
Reach and readers19K

Иногда книга начинается с одной статьи, опубликованной в нужный момент и в нужном Хабре и в моём случае всё действительно началось с публикации про аллокаторы, которая несмотря на обилие технического материала, кода и схем набрала больше всего плюсов среди моих статей на околоплюсовую и игродев разработку. А дальше и сам цикл Game++ постепенно вырос из отдельных технических размышлений о C++, архитектуре движков и производительности в связный нарратив. За спиной Game++ стоит еще больше узкотехнических материалов в блоге и вики моей компании и я бы рад ими поделиться, да и делюсь периодически, но сами понимаете выкладывать можно не всё и даже из то, что выложено на Хабре, частенько было подрезано, ибо NDA и секретные технологии-бла-бла-бла. Та статья стала точкой, когда я увидел, что разрозненные тексты на самом деле образуют скелет будущей книги, нужно лишь перестать относиться к ним как к «постам» и начать воспринимать как главы. Идея написать книгу не пришла просто так, и несколько не связанных между собой людей и компаний связались и предложили переписать цикл статей в виде книги.

Читать далее

Охота за красным fps

Level of difficultyEasy
Reading time25 min
Reach and readers14K

Профилирование часто недооценивают как постоянный процесс, считая его чем вроде финальной фазы перед релизом, вроде полировки или поиска багов и в целом это, конечно, напоминает поиск багов, но это не просто поиск узких мест в коде и их фикс здесь и сейчас, а часто отдельная философия разработки, которая содержит несколько школ со своими принцЫпами, которые нормально так разнятся. И без глубокого понимания "как надо профилировать" невозможно создать игру, которая будет приемлемо работать на "картошке".

Начну я с фундаментального вопроса: что же такое игра с точки зрения программной инженерии? В целом игра -- это система мягкого реального времени, что означает, что все процессы, которые в ней происходят, начиная от игровых событий вроде нажатия кнопок игроком или появления врагов на экране, продолжая игровой логикой, которая определяет правила взаимодействия объектов и состояния игрового мира, физикой, столкновениями и заканчивая рендерингом, должны происходить в строго определенное время, и это ограничение является абсолютным и не подлежащим обсуждению, иначе мы получим "вязкий" игровой процесс.

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

Но если игра пропускает хотя бы один кадр и вместо 16.6 миллисекунд тратит 30 и больше, то игрок зачечает задержку в анимации, и это портит впечатление от игры. Соответственно, если мы что-то добавляем в игровой код, что-то изменяем в алгоритмах или в контенте, мы должны это строго отслеживать, чтобы не внести каких-то проблем с производительностью, которые разрушают игровой опыт.

Оптимизируй это...

Почему универ не готовит программистов

Level of difficultyEasy
Reading time8 min
Reach and readers17K

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

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

С одной стороны у нас движковый, анимационный и gameplay программист это буквально одна из самых дефицитных профессий в индустрии прямо сейчас, чтобы вы понимали в среднем нехватка по студиям больше 20% мидловых и помидорских позиций, т.е. не хватает как минимум одного спеца в каждой команде, куда ни ткни. А ребята из Epic Games, Unity, CD проджектов и прочих крупных студий постоянно жалуются, что не могут найти нормальных специалистов, которые реально умеют работать с современными движками, и они готовы платить безумные деньги (безумные по меркам штатов конечно, в старом свете все более приземленное, но тенденция та же) тем кто шарит в графике или может написать мультипоточный код, который не развалится на проде, или знает, как выжать лишние пару кадров из железа, но людей всё равно не хватает и это при том, что желающих работать в геймдеве очень и очень много.

Читать далее

Нескучное программирование. Важны ли компилятору имена

Reading time8 min
Reach and readers16K

Есть старая шутка о том “чем отличается обычный программист на С++ от хорошего программиста на С++”? Первый пишет код, а второй может объяснить, почему он работает. 

Это конечно шутка, но сейчас далеко не всякий даже хороший программист может объяснить, как работает тот или иной участок кода или внутренняя логика, которая привела к конечному решению, не прибегая к ультимативными фразам вроде «так написано в стандарте» или «так нахерачил компилятор».

В центре всего, что происходит внутри компилятора, находятся два процесса: поиск имён и разрешение перегрузок, которое мы рассмотрели в предыдущих статьях. И каждый раз, когда компилятор обрабатывает ваш код — он обрабатывает всего два вопроса:

Первый: «Что вообще может означать это имя здесь?»
Второй: «Если вариантов несколько, какой из них правильный?»

Если вы поймёте, как компилятор отвечает на эти вопросы, то вы поймете как работает и всё остальное — шаблоны, концепты, перегрузки — это всё строится на решении этих двух вопросов.

Читать далее
1
23 ...

Information

Rating
6-th
Location
Москва и Московская обл., Россия
Date of birth
Registered
Activity

Specialization

Десктоп разработчик, Разработчик игр
Старший
From 300,000 ₽
Git
C++
Многопоточность
Прикладная математика
ООП