The Jerusalem PostFormer hostage Romi Gonen reveals footage from moments she was taken to GazaPunchArmy confirms killing of ISWAP leader in OndoESPN'If we bunt, we win': How the Rays developed a secret weaponBollywood HungamaSanjay Leela Bhansali and Alia Bhatt planning to revive Inshallah after Love And War: REPORTUN NewsOne day behind bars: Students and incarcerated women break prison stigma in ThailandInquirerEl Niño to bring drought to all provinces by March 2027 – DOSTSky TG24Baby Gang resta in carcere, gip respinge domiciliari: "È in rete criminale internazionale"Observador DesportoMoedas: "As lutas ideológicas nunca deram casa a ninguém"Il Fatto Quotidiano“Dal ‘ti amo’ all’addio in una settimana, questo è lui”: Elon Musk lascia Shivon Zilis all’improvviso e lei pubblica le loro chat privateRTL BoulevardKeizer Naruhito woont openingsceremonie Japans parlement bijOnetDonald Tusk zapytany o list żelazny dla posła PiS. Premier wskazał, co było błędem7sur7“Malgré la maladie, il a continué à créer”: le rappeur français Prince Waly est mort à 34 ans
The Daily Newsstand · Free, Always
Monday, October 5, 2026

God of Pixels: шесть лет, два языка и один генератор планет

Translate

Более 6 лет назад, во время учебы в школе, я писал всякие небольшие программы для развлечения. Так однажды мне пришла амбициозная (в сравнении с моими навыками) идея: процедурный генератор планет. Да, просто генератор красивых картинок, без какой‑то объективной пользы. И сейчас перед вами история проекта, который развивался вместе со своим разработчиком на протяжении всей его карьеры.

God of Pixels — просто пиксели

В новой школе мы как раз начали изучать Python и я принялся за работу.

Каменные острова в океане

Каменные острова в океане

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

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

Полярные льды и растения

Полярные льды и растения

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

Тест освещения на планете

Тест освещения на планете

Это все еще больше похоже на бактерии в чашке Петри и мне потребовалось время, чтобы понять причину. Свет! Начались эксперименты и математические расчеты. Да, да, на Python, на CPU циклах, по собственным формулам я рассчитывал освещение на сфере. И вот результат.

Даже код сохранился:

def Shadow(x1,y1): #координаты пикселя
    import math
    a=x1-57 #координаты относительно центра картинки
    b=y1-58
    R=52    #радиус планеты
    xm=-24  #координаты точки максимальной освещенности (ТМО)
    zm=math.sqrt(R*R-xm*xm)
    z=math.sqrt(R*R-a*a-b*b) #координата точчки на поверхности планеты
    r=math.sqrt((a-xm)*(a-xm)+b*b+(z-zm)*(z-zm)) #расстояние до ТМО
    u=math.degrees(math.asin(r/2/R)) #угловое расстояние до ТМО
    k=(45-u)/45 #теневой коэффициент
    return k

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

А пока предлагаю посмотреть на первую версию интерфейса:

Первый интерфейс

Первый интерфейс

Здесь уже появились разнообразные настройки: формирование каждого биома, количество растений и немного контроля над цветами. С интерфейсом это уже не просто скрипт, а полноценный продукт, которому нужно запоминающееся название. Тогда и появился «God of Pixels».

Населенный мир

Населенный мир

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

God of Pixels 2 — настоящая генерация ландшафта

Через какое то время размышлений мне не удалось придумать более реалистичный алгоритм для поверхности планеты, и было решено пойти погуглить. В итоге я нашел бриллиант, вернее алгоритм diamond‑square. В меру простой по реализации, очень реалистичный и очень быстрый.

UV преобразования

UV преобразования

Но была и еще одна проблема. Объем нужно придавать не только освещением, но и самой геометрией. По сути, плоская текстура со сферическим освещением создает диссонанс. Тут уже появляются UV преобразования. В формулах с википедии я тогда не разобрался, так что просто по‑своему воплотил идею. Все пиксели смещаются к центру, как если бы они ложились на сферу, а потом проецировались на экран.

Облака

Облака

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

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

Этот технологический скачок показался мне настолько невероятным, что я назвал новую версию God of Pixels 2. Про версии ПО тогда не знал или не обращал внимания. Git репозитория тоже не было. Так что да, сразу вторая часть.

И в интерфейсе произошли изменения:

Новый интерфейс

Новый интерфейс

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

Собственные виджеты настроек

Собственные виджеты настроек

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

God of Pixels 3 — месяцы рефакторинга

Со временем поддерживать код стало труднее. Усложнившийся интерфейс весь описывался кодом на tkinter и я до сих пор с ужасом смотрю на те строки. Рендеринг занимал неприлично много времени, особенно облачность. Да и сама по себе разработка на Python с ростом проекта приносила все меньше удовольствия.

Как раз в это время проходила учеба в вузе, где нам преподавали C++ и фреймворк Qt. Тогда я решил потратить целое лето на рефакторинг проекта. Кстати, это было долго, но довольно легко. Почти полное отсутствие внешних зависимостей превращают переписывание кода в почти медитативное занятие. Ничего не изучаешь, просто перекладываешь конструкции языка из одного в другой. Хотя пришлось даже залезть в стандартную библиотеку Python, чтобы списать оттуда алгоритм случайных чисел с нормальным распределением для шума Перлина.

Здесь же появились мысли о распространении проекта, так что появился репозиторий на github, лицензия и небольшое описание в readme.

После переноса проекта было добавлено много всего. В первую очередь Qt позволил создать более менее красивый интерфейс. Я решил сделать все черным, чтобы замаскировать границу рендера планеты.

Интерфейс на Qt

Интерфейс на Qt

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

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

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

Один из первый вариантов карточек

Один из первый вариантов карточек

Здесь же появились карточки. Захотелось чего‑то вроде научного отчета. Первая карточка это всегда превью планеты, просто из главного экрана. Вторая это описание. Большая часть берется случайно, но шкалы реально считаются в зависимости от наполнения планеты. А вот с другими частями долгое время были проблемы. Нужна была какая‑то эффектная визуализация. Сначала это была карта галактики и 3D рельеф.

Однако рельеф как будто бы раскрывал главную тайну приложения — неполную генерацию. Здесь все еще создается только половина мира и показывается на экране png картинкой.

Карточки со звездной системой

Карточки со звездной системой

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

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

Автоматически сгенерированный коллаж

Автоматически сгенерированный коллаж

Однако, каждый следующий алгоритм и каждая новая функция давались все труднее. В какой‑то момент я оказался в тупике. Либо терпеть и продолжать писать алгоритмы самому и пытаться не утонуть в формулах, либо переписать все на какой‑нибудь движок. В обе стороны недели работы.

V1.0.0 — первый релиз

В какой‑то момент я отчаялся, дальнейшее развитие казалось слишком сложным. Поэтому я решил просто прибраться в проекте, сделать несколько вещей для удобства пользователей (в частности локализацию на английский) и полноценно поделиться с миром. За несколько дней смонтировал пару видео‑трейлеров, завел страничку на itch.io, собрал и выпустил проект. Я искренне думал, что на этом все.

Про сам релиз — пару честных слов. Он прошёл заметно тише, чем я ожидал — не более 20 скачиваний. Оказалось, продвигать свои творения тоже нужно уметь. Например, на обложку я сначала поставил логотип с названием и лишь через пару дней понял, какая это была ошибка. Такое превью просто теряется на фоне тех, кто ставит на обложку реальный скриншот игры/приложения. Собственно, эта статья и есть моя вторая попытка привлечь к проекту внимание.

Обновление CORE — чудо нейросетей

А потом случились нейросети. Я, как и многие, относился скептически, однако, решился попробовать. И вот в Cursor открыт God of Pixels.

Это было нечто. Увидеть ЛЛМ в действии на своем личном проекте это совершенно другой уровень взаимодействия с нейросетями. В эмоциональном смысле. Твой проект знаешь и понимаешь только ты. Но вдруг появляется «нечто», которое за 30 минут читает все файлы и уже разбирается в тонкостях лучше тебя. Это новое для меня ощущение. С одной стороны восторг, как будто произошла встреча со старым другом, с которым мы делили разработку многие годы, мы пишем код, обсуждаем идеи и все такое. А с другой стороны обида, как будто усилия многих лет в раз обесценились.

За пару вечеров рендеринг был полностью переписан на OpenGL и планету стало возможно вращать и приближать. Раньше генерировалось только одно полушарие, так как на экране все равно будет только png, а теперь все алгоритмы адаптированы под сферу. Трудно даже сразу вспомнить сколько всего было добавлено позже: звездное небо, солнце, метеоритные кольца, лавовые разломы, переработка карточек, города (они вернулись) и многое другое. Появилась даже система достижений!

Интерфейс этой версии показан вначале статьи. Здесь размещу новый формат карточек.

Новый формат карточек

Новый формат карточек

Карточки тоже в очередной раз переделаны. Карта галактики (которая ни от чего не зависела) заменена на карту поверхности в проекции Меркатора, а карта звездной системы на теги. Кстати говоря, система тегов реагирует практически на все: климат, свет, население, ресурсы. Есть случайные теги‑пасхалки. Есть даже теги‑эмоции, которые реагируют на выбранный цвет поверхности. Например, красный — «агрессивный мир».

В сумме изменений так много, что можно было бы назвать это God of Pixels 4, но я решил остановиться на большом именованном (потому что мне нравится No Man’s Sky) обновлении. Так в сентябре вышло обновление CORE, а я снова ощутил радость создания чего‑то нового.

Обновление FRIEND — планы на будущее

Разумеется, теперь мне нужно не просто развивать проект, но и придумывать более амбициозные цели, чтобы соответствовать новым инструментам. Следующим шагом станет обновление FRIEND, которое будет направлено на улучшение UX/UI. Здесь появятся: новые языки локализации, сборки под Linux/Mac, переработка интерфейса и многое другое.

Вот, например, рабочий прототип нового интерфейса:

Тестовый вариант нового интерфейса

Тестовый вариант нового интерфейса

Заключение

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

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

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.