Сам написал игру, знаю все спойлеры — и всё равно залипаю вместо тестов. древняя греция.. древняя греция. игра.. древняя греция. игра. ИИ.. древняя греция. игра. ИИ. ии-ассистент.. древняя греция. игра. ИИ. ии-ассистент. инди-разработка.. древняя греция. игра. ИИ. ии-ассистент. инди-разработка. искусственный интеллект.. древняя греция. игра. ИИ. ии-ассистент. инди-разработка. искусственный интеллект. Разработка игр.. древняя греция. игра. ИИ. ии-ассистент. инди-разработка. искусственный интеллект. Разработка игр. симулятор.
Развитый полис

Развитый полис

Запускаю Age of Poleis, чтобы проверить одну мелочь. Получилось ли у меня в онбординге передать смысл продолжать разведку или нет. И вот я уже исследую весь остров в поисках нужного для старта артефакта. Странное чувство. Игру придумал я. Я знаю, какие здания откроются следующими, где экономика начнёт скрипеть и к чему всё идёт. Спойлеров у меня больше, чем у кого угодно. И всё равно иногда закрываю чек-лист и продолжаю строить город — просто потому что хочется.

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

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

Если объясняешь второй раз — это уже правило

Бэкенд на Django, интерфейс на React и TypeScript, между ними API. Контракт описывается на бэкенде, из него получается OpenAPI-схема, из схемы генерируются TypeScript-типы.

Django → OpenAPI → TypeScript-типы → код интерфейса

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

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

-  Fix root causes; do not silence failures with skipped tests, broad assertions, duplicated

   flows, generated-file edits, or an alternate database.

- API-owned TypeScript types come from generated OpenAPI. Client-owned types remain local.

- API boundary: backend source change, OpenAPI/type regeneration, frontend validation.

Но правило в тексте — это пока пожелание. Поэтому в общем скрипте проверки проекта есть шаг, который генерирует схему и типы во временные файлы и сравнивает их с тем, что лежит в репозитории. Разошлось — проверка красная.

```python

def run_frontend_contract(gate: Gate, temporary: Path, generated_types: Path) -> None:

    if gate.run(

        "Generate TypeScript API types into an isolated file",

        [NPM, "exec", "--", "openapi-typescript", str(OPENAPI), "-o", str(generated_types)],

        cwd=FRONTEND,

    ):

        gate.check(

            "TypeScript API types drift",

            lambda: assert_same(

                "frontend/src/types/generated/api.ts", generated_types, GENERATED_TYPES

            ),

        )

```

С тех пор у меня простая схема: правило, способ его выполнить и проверка. Без проверки правило соблюдается, пока агент о нём помнит. С проверкой — всегда. Так же закрывается форматирование, локализация и любая другая рутина, которая повторяется.

Тридцать зелёных тестов, которые проверяли не то

Windows-версия запускалась так: сначала маленькое окно загрузки, потом отдельное игровое. На выходе — ещё одно окно ожидания. Работало, но выглядело как три разные программы. Хотелось по-человечески: одно окно, в нём загрузка, потом игра. Закрыл — окно исчезло.

На словах задача на одну строку. В коде — несколько состояний: запуск, загрузка, закрытие посреди запуска, сохранение, повторный старт.

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

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

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

  • загрузка и игра идут в одном окне;

  • закрытие во время запуска не открывает новое окно;

  • сохранённая кампания на месте после перезапуска.

В итоге прошли 96 JavaScript-тестов оболочки, а агент отдельно прогнал настоящее Electron-приложение. Одно окно от загрузки до игры, закрытие без лишних окон, кампания жива после перезапуска. Ручное сохранение пережило закрытие с тем же идентификатором, названием и игровым моментом.

И ещё одна строчка, которую я теперь требую в каждом отчёте: что не проверялось. Здесь это установка на чистую Windows, она живёт отдельной задачей. Через месяц такая строчка спасает от ложной уверенности.

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

Моя работа — играть

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

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

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

Был момент, когда я понял, что подбирать очередного жителя для очередной требуемой профессии по началу было весело, а спустя 100 игровых периодов уже утомляет. Итогом стало автоматический подбор по критериям, теперь я  просто как управленец “распоряжаюсь” и “приказываю” обучаться.

Автоподбор кандидатов

Автоподбор кандидатов

Честности ради: то, что нравится мне, ещё ничего не говорит о других игроках. Для этого нужны чужие прохождения. Но если автору самому не хочется выходить из своей игры, это хороший знак.

Перфекционизм против рандома

Есть у меня и совсем личная проблема, из-за которой производство растягивается очень сильно. Перфекционизм.

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

Кривые кнопки

Кривые кнопки

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

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

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

Чего ИИ за меня не сделает

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

С маркетингом ещё сложнее. Набросать описание с ИИ — дело пяти минут. Понять, кому эта игра нужна, что показать первым и как объяснить её человеку, который слышит о ней впервые, — уже нет. Игра плюс пачка постов ещё не аудитория.

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

А теперь пойду запущу игру. Только проверить одну мелочь.

Бесплатную демку можно скачать тут: https://age-of-poleis.itch.io/age-of-poleis

Автор: sharben

Источник