Как построить игру с Astra: 10 000 планет, WebGPU и непрерывный спуск с орбиты

· 1 мин чтения
astra coding-agents game-dev threejs procedural-generation
Как построить игру с Astra: 10 000 планет, WebGPU и непрерывный спуск с орбиты

Astra — агент OpenAI, встроенный в Codex, — оказался на удивление хорош в том, чтобы превращать словесные описания в геймплей и арт-директиру. Автор блога разработчиков OpenAI использовал его для создания Void Explorer — космической игры, где можно летать от далёких звёзд до поверхности чужих планет. В статье разбирается, как выстроена работа над проектом: от первого промпта до измерения производительности.

Суть игры

Void Explorer — это вселенная из 2 048 звёздных систем и более 10 000 процедурно сгенерированных планет, включая миры размером с Землю. Каждая видимая звезда — реальный объект, до которого можно долететь: выбираете точку света вдали и отправляетесь к ней. Корабль проходит сквозь атмосферу, снижается до полёта над побережьем, садится — можно выйти, пройтись пешком и взлететь снова.

Автор подчёркивает: добиться такого путешествия означало одновременно решить задачи масштаба, террейна, управления и рендеринга.

Начать с опыта, а не с технологий

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

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

Это дало Astra конкретные ограничения: звезда не может быть просто точкой на фоне, планета не превращается в отдельный уровень при приближении.

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

Архитектуру предлагает Astra

Ограничения задавал автор, реализацию предлагал агент. Приложение построено на TypeScript и Vite с Three.js для рендеринга — это даёт прямой контроль над мешами, материалами, освещением и процедурной геометрией.

Интересный момент: первый рендерер работал на WebGL2, но когда автор спросил, не тормозит ли Three.js визуал, Astra рекомендовала оставить симуляцию и перенести рендер на WebGPU-архитектуру Three.js. Вселенную, навигацию и террейн сохранили — менялся только слой отрисовки. Атмосфера, вода и освещение описываются кодом через node-материалы и Three.js Shading Language (TSL).

Генерация террейна выполняется в Web Workers, чтобы не блокировать поток ввода и отрисовки. Vitest проверяет повторяемость генерации и координатную математику, Playwright гоняет игру в браузере. Поверх всего — фильтр Neon Phosphor, добавляющий ретро-текстуру дисплея.

Дать агенту инструменты проверки

Автор сам играл в игру, но Astra нужны были способы исследовать проблему за пределами того, что он мог описать словами. Игра экспортирует небольшой JavaScript-интерфейс window.__VOID_EXPLORER__: браузерные тесты могут узнать, к какому телу приближается корабль, какой режим полёта, готов ли террейн, сколько draw calls и треугольников в сцене.

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

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

Вселенная в нескольких масштабах

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

С координатами отдельная история. Расстояния в световых годах и человек рядом с кораблём — разные масштабы, и отправка гигантских позиций напрямую в GPU убивает точность у земли. Astra разделила физический адрес и позицию для отрисовки: вселенная использует большие целочисленные ячейки с меньшими локальными смещениями, а перед рендерингом вычитается позиция наблюдателя — камера всегда в начале координат.

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

Непрерывный спуск

Переход из космоса на землю потребовал больше всего итераций. Один из промптов:

Когда подлетаю почти параллельно планете, могу войти слишком быстро — планета почти исчезает, пока грузится террейн. Нужно починить кривую скорости и стриминг террейна вместе. Может, атмосфера смягчит переход между дальним LOD и детальным террейном? Планета не должна исчезать при приближении.

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

Система уровней детализации: издалека планета — недорогая гранёная сфера-прокси. При приближении включается террейн из шести граней куба, спроецированных на сферу; каждая грань рекурсивно делится на четыре квадрата — классический quadtree. Это позволяет уточнять рельеф в видимой области и по направлению движения, не генерируя поверхность Земли с разрешением для ходьбы.

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

Осознанное ограничение: планеты построены на heightfield — одна высота на направление поверхности. Это подходит для больших ландшафтов, но не даёт пещер, нависаний и разрушаемых туннелей. Ходьба использует Rapier в маленьком локальном физическом мире, логика посадки отдельно проверяет опоры, уклон и зазор корабля.

Измерять работу за медленным кадром

Обратная связь автора часто объединяла внешний вид и производительность. Astra использовала счётчики рендерера Three.js и Playwright-тест, собиравший 90 интервалов кадров со средним и перцентилями.

Показательный пример: замена процедурного корабля на первую модель AURORA из Blender увеличила число треугольников, но снизила количество draw calls. Тот же 90-кадровый орбитальный тест до и после (headless Chromium со SwiftShader):

Метрика До После
Draw calls в сцене 119 77
Треугольники в сцене 48 809 61 092
Средний интервал кадра 251,48 мс 199,26 мс

Дальше — оптимизации загрузки. Детализацию далёких планет привязали к размеру на экране: планета размером меньше пикселя не требует плотной геометрии. В контрольном сравнении новая политика использовала 7 040 треугольников прокси вместо 51 200. Индексированные меши переиспользуют вершины соседних треугольников: при том же количестве 241 952 треугольника передаваемые буферы упали с ~35 МБ до 15 МБ. А стабилизация решений quadtree — уточнять тайл только когда бюджет позволяет все четыре дочерних — сократила отменённые задачи террейна с 6 074 до 13 за девять секунд симуляции.

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

От концепт-арта к ассетам

Вселенная генерируется кодом, но корабль — главный авторский 3D-ассет. Автор итерировал по сгенерированным концептам и Blender-рендерам, пока не получил нужный: четыре отдельных крыла, симметричный силуэт, розовые огни на законцовках. Затем попросил Astra построить модель в Blender, сохранить арт-стиль игры и добавить её в игру.

Исходник в Blender содержит 193 редактируемых меша; экспортированный корабль — 14 968 треугольников в восьми непрозрачных material batches. Детализацию в исходнике можно наращивать, удерживая стоимость рендера под контролем.

Процедурная вода

Тот же подход автор применил в Sunwake — игре о катании на лодке по процедурному океану. Кастомный рендер воды в Three.js: одна модель волн управляет и видимым морем, и плавучестью лодки — корпус поднимается, кренится, оставляет пенный след. В Hollowflux, 2D action RPG вокруг светящейся подземной реки, пещеры и персонажи нарисованы кодом без импортированных спрайт-листов. Сетка ячеек отслеживает высоту воды, течения, пену и электрический заряд: шаги оставляют круги, удары молота — кольца, а разряд угря идёт по связанной воде — сухой камень защищает игрока.

Публиковать просто

Автору нравится формат работы: начать с желаемого опыта, конкретизировать визуал картинками, давать обратную связь от реальной игры. Решение, «правильно ли это ощущается», остаётся за человеком, а Astra проводит его через код, ассеты и тесты.

Поделиться браузерной игрой тоже несложно: через Sites-плагин достаточно попросить Astra задеплоить игру и дать ссылку — с публичным доступом в неё можно играть прямо в браузере. Void Explorer, Sunwake и Hollowflux доступны в showcase OpenAI.

Совет напоследок: если идея игры давно сидит в голове, соберите с Astra маленькую играбельную версию. Одной лодки, комнаты или одного взаимодействия достаточно для старта — играйте, конкретно формулируйте, что изменить, и продолжайте.

Источник: https://developers.openai.com/blog/how-to-build-games-with-astra