Spiiin's blog

Важность простых языков

Про важность использования простых языков в геймдеве и не только.

Why Go and not Rust? - статья вообще про преимущества простого go перед более сложным rust в блоге про zig :) Но в ней есть развернутый ответ на вопрос “почему обычно в корпоративном мире качество кода оставляет желать лучшего. В мире геймдева (там где я видел, во всяком случае), ситуация такая же — длительные в разработке проекты с большим количеством кода и широкой предметной областью, в которой эксперты предметной области слабо разбираются в технологии, а программисты — в особенностях предметной области, поэтому необходим процесс.

Процесс

Разработка больших систем — это всегда про масштаб. Понятие масштаба касается не количества данных или пользователей, а количества фич (scope) и процесса разработки. Опыт масштабирования как его понимают программисты часто неприменим к такому типу сложности, нетехнические трудности перевешивают технические.

Чтобы разобраться с масштабированием, менеджеры пытаются настроить процесс разработки, и привлекают экспертов и аналитиков, которые “знают как правильно” побороть сложности масштабирования.

Ссылки про “процессы” в геймдеве:
Древние логи из IRC, про то, как в геймдеве в принципе приходили к тому, чтобы разработка стала хоть как-то предсказуемее (если не ошибаюсь, обсуждается Midway).

[09:17] <look4awhile> когда технические сложности - это всего-лишь технические сложности
[09:17] <look4awhile> а оценивается работа продюсера
[09:18] <look4awhile> наглядный пример, из последнего - дум-3.

При этом забавно, что описанный там подход, начало 2000х — как будто попытка адаптировать к геймдеву методы, разработанные еще в 80х.

Паттерны организации разработки уровней игр — мои попытки обнаружить интересные идеи среди принятых сейчас Agile/Lean подходов.

Из этого взаимодействия бизнеса/управления/команды возникает несколько хорошо известных “причуд” корпоративной разработки.

Джуниоры

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

Бывает, что джуниор вынужден реализовывать фичу, вообще впервые сталкиваясь с какой-либо технологией. Примеры из мобильной разработки — интеграция sdk с использованием нативных языков (java/kotlin/obj c/swift) в C++ код, программирование на gpu, скриптовые языки.

Код быстро становится запутанным

Причин множество.

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

Команды, работающие независимо, неизбежно будут создавать избыточный код.

Из-за сжатых сроков также кривой код попадает в релиз. “Когда-нибудь перепишем”.

С течением времени предметная область меняется, что неизбежно делает недействительными старые предположения и, следовательно, приводит к утечке абстракций. Чем сложнее абстракция, тем выше риск того, что она станет проблемой, когда гейм-дизайнер вернется с серьезным запросом на изменение. Проект никогда не может быть достаточно гибким, чтобы учесть все возможные пожелания и фантазии. Бизнес может прийти с запросами вроде “ситуация на рынке изменилась, меняем жанр/платформу/удваиваем количество фич”.

Пайплайн устаревший/жуткий

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

Что с этим делать

Что может предоставить язык программирования, чтобы бороться с перечисленными проблемами?

Краткий ответ — быть максимально простым (только не примитивным, а именно незапутанным), гибким (не настраиваемым на все случаи жизни, а готовым к быстрым изменениям), и позволяющим мгновенно проверять гипотезы.

Именно возможность писать код так, чтобы он соответствовал этим критериям стоит использовать при сравнении языков между собой — они влияют на конечную продуктивность команды (продуктивность это не просто скорость, с которой можно делать фичи, а способность сделать продукт, который будет приносить деньги). Язык стимулирует писать код определенным способом — и этот способ может быть общепринятым для одного языка, но контр-интуитивным для другого.

Идти “против языка” при этом достаточно сложно в перспективе. Как в рамках одного проекта, так и распространяя паттерны работы — создание библиотек/тулзов/общепринятных подходов к разработке. Несколько случайных примеров не прижившихся или экспериментальных идей на C++ из русского геймдева (это не какие-то особенно продвинутые идеи, просто как пример подхода “против языка”, отчасти не прижившихся из-за необычности, отчасти из-за того, что это “не касается” языка, не выразимо на языке == будет отброшено, программист навряд ли наткнётся на такие подхода, если будет искать “как реализовать XXX”; старые ссылки выбраны отчасти потому, что я видел развитие каких-то из этих идей в движках, отчасти потому что, в современной геймдев культуре менее принято делиться интересными подходами, во всяком случае, если мониторить конференции и доклады, отчасти потому, что сохранились в коллекции ссылок):
Compile-time vs run-time: назад в будущее — генерация кода из данных в “build-time”
Component-oriented design на консолях, лобзиком по шаблонам — распиливание классов на компоненты на шаблонах
Data structures baking — чтение структур языка с диска без кода инициализации (еще пара ссылок)
Дзен-3, скрипт — триггеры с минимальным функционалом вместо скриптов, создание минимального интерпретатора dsl на стороне игры. Хех, ну и почти блюпринты в движке SkyForge

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