Мне очень нравится знаменитая цитата Ричарда Фейнмана:

«То, что я не могу создать, я не понимаю»

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

Сегодня, в 2025 году, красота и ремесло написания ПО подвергаются разрушению. ИИ угрожает тем, что заменит нас (или, по крайней мере, заберёт все самые приятные аспекты нашего ремесла), а разработка ПО становится всё более стандартизированной, выверенной, упакованной и индустриализированной. Разработке программного обеспечения нужно больше простых удовольствий. Я выяснил, что создание хобби-программ — отличный способ снова напомнить себе, почему вообще я начал работать с компьютерами.

Не усложняйте

Хобби-проекты устроены по правилу «80 к 20»: 20% работы дают 80% функциональности. Наша цель — не создать готовое к продакшену ПО (хоть некоторые из лучших продакшен-проектов изначально были хобби). Нужно агрессивно ограничивать себя в оверинжиниринге, писать только тот код, который необходим для достижения нашей цели. Пусть каждый путь выполнения кода приводит к панике/вылетам, пока вы не будете вынуждены реализовать их, чтобы двигаться дальше. Вы удивитесь, насколько легко писать хобби-версии ПО, которые когда-то казались вам неподъёмно сложными в создании.

Другие преимущества

Меня постоянно приятно удивляет то, что какие-то нишевые знания, полученные при работе над хобби-проектом, оказываются бесконечно полезными в моей повседневной работе. Я или сразу понимаю, где искать проблему в инструменте/библиотеке, или распознаю ошибки ещё до того, как их совершат.

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

Список

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

Движок регулярных выражений (сложность = 4/10, время = 5 дней)

Движок регулярных выражений, способный читать regex-программу в стиле POSIX и находить соответствующие ей строки. Регулярные выражения просты, но на удивление выразительны, а создание работающего движка научит вас всему, что нужно знать об использовании языка.

Ядро операционной системы x86 (сложность = 7/10, время = 2 месяца)

Совместимое с мультизагрузкой ядро ОС с простым CLI, драйвером клавиатуры/мыши, поддержкой управляющих последовательностей ANSI, диспетчером памяти, планировщиком и так далее. Задачи со звёздочкой: написать файловую систему, работающую в памяти, реализовать пользовательский режим и изоляцию процессов, загрузку исполняемых файлов ELF и поддержку видеооборудования в объёме, достаточном для рендеринга GUI.

Tupai

Эмулятор GameBoy/NES (сложность = 6/10, время = 3 недели)

Сырой эмулятор самых простых игр для GameBoy или NES. GB и NES — это классика; обе консоли обладают относительно простыми наборами команд и периферийным оборудованием. Задачи со звёздочкой: написать работающие реализации PPU (видео) и PSG (аудио), а также обработку каких-нибудь более сложных форматов картриджей.

Игра для GameBoy Advance (сложность = 3/10, время = 2 недели)

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

Физический движок (сложность = 5/10, время = 1 неделя)

Движок физики абсолютно твёрдых 2D-тел, реализующий ньютоновскую физику с поддержкой прямоугольников, кругов и так далее. Самое простое — создать отталкивающиеся друг от друга сферы. Всё усложняется с добавлением более сложных фигур, углового момента и тому подобного. Задачи со звёздочкой: быстрое и надёжное разрешение коллизий, постепенный переход сложных взаимодействий в стабильное состояние, взаимодействие мягких тел и так далее.

Динамический интерпретатор (сложность = 4/10, время = 1-2 недели)

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

Forge

Комилятор для C-подобного языка (сложность = 8/10, время = 3 месяца)

Компилятор для языка программирования наподобие C с простыми типами и поддержкой хотя бы одной целевой архитектуры. Задачи со звёздочкой: реализовать самые часто используемые оптимизации (встраивание, свёртку констант, инвариантный к циклу код и так далее) и проектирование промежуточного представления (intermediate representation, IR), достаточно обобщённого для поддержки нескольких бэкендов.

Текстовый редактор (сложность = 5/10, время = 2-4 недели)

В этом пункте возможна большая вариативность. Простейшие чтение и запись в файл можно реализовать всего в нескольких строках на Python. Сложнее написать то, в чём можно редактировать тексты в повседневной жизни. При помощи тулкита наподобие QT или GTK можно реализовать UI, но лично я предпочитаю редактор, работающий в консоли. Для правильной обработки Unicode, реализации подсветки синтаксиса, перемещения курсора, поддержки нескольких буферов, панелей/окон, вкладок, функций поиска, поддержки LSP может понадобиться дополнительное время от недели до месяца. Но если вы будете упорны, то сможете присоединиться к элитной компании разработчиков, пользующихся собственным редактором.

ZTE
ZTE

Асинхронная среда выполнения (сложность = 6/10, время = 1 неделя)

Определение асинхронности сильно зависит от языка. Например, в Rust это означает библиотеку, способную потреблять задачи impl Future и конкурентно опрашивать их до завершения. Задача со звёздочкой: добавить поддержку пробуждения по вводу-выводу.

Хэш-таблица (сложность = 4/10, время = 3-5 дней)

Хэш-таблицы (или множества/словари, как они могут называться на языках высокого уровня) — это то, чем программисты зарабатывают на хлеб с маслом. Тем не менее, лишь немногие из нас знают, как они устроены внутри. Можно добавить сюда и множество других методик: открытую и закрытую адресацию, tombstone, хэширование Робина Гуда и так далее. Вы разберётесь, когда и почему они быстры, а также поймёте, когда следует использовать векторный + линейный поиск.

Растеризатор / движок наложения текстур (сложность = 6/10, время = 2 недели)

Многие из нас рано или поздно экспериментировали с 3D-графикой, но кто по-настоящему понимает, как работает графический конвейер и как исправить его, когда что-то идёт не так? Вы получите эти знания, написав собственный программный растеризатор, параллельно с этим восприняв красоту векторной математики и полупространств, применяемых во многих других областях. Задачи со звёздочкой: реализация правильного отсечения, Z-буфера, растеризации N-угольников, перспективного наложения текстур, затенения по Фонгу или Гуро, наложения теней и так далее.

euc

SDF-рендеринг (сложность = 5/10, время = 3 дня)

Поля расстояний со знаком (Signed Distance Field) — это изящный и простой способ рендеринга 3D-пространств, определяемых через математику. Он идеально подходит для шейдеров демосцены. Приложив относительно малый объём усилий, вы сможете создать милую небольшую визуализацию или движущиеся фигуры, напоминающие графические демо 80-х. Параллельно с этим вы охватите языки шейдеров и векторную математику.

Signed Distance Fields

Воксельный движок (сложность = 5/10, время = 2 недели)

Думаю, почти все из читающих эту статью играли в Minecraft. Можно на удивление быстро создать подобный воксельный движок, особенное если у вас уже есть опыт в 3D-графике или разработке игр. Простота воксельного движка в сочетании с почти безграничными творческими возможностями, которые можно реализовать на его основе, не перестают меня радовать. Задачи со звёздочкой: добавить работу с текстурами, более сложную процедурную генерацию, floodfill-освещение, коллизии, динамические жидкости, передачу воксельных данных по сети и так далее.

Виртуальная машина шитого кода (сложность = 6/10, время = 1 неделя)

Писать интерпретаторы очень интересно. Но ещё интереснее писать быстрые интерпретаторы. Если вы продолжите выжимать производительность из интерпретаторов, не вдаваясь при этом в кодогенерацию под конкретные архитектуры (наподобие AOT или JIT), то рано или поздно обнаружите для себя шитый код (не путать с многопоточным, это совершенно другое). Это красивый способ переплетения программ из высокооптимизированных миниатюрных программ; качественная реализация даже может дать фору в производительности AOT-компилятору.

GUI-тулкит (сложность = 6/10, время = 2-3 недели)

Большинство из вас, вероятно, уже создавало GUI-программы при помощи tkinter, GTK, QT или WinForms. А почему бы не попробовать написать собственный GUI-тулкит? Задачи со звёздочкой: реализовать работающий движок макетов, качественную работу с текстом (в том числе и поддержку Unicode), поддержку accessibility и так далее. Предупреждение: не рекомендуйте другим людям пользоваться своим инструментом, если только он не проверен временем: в мире и так уже достаточно GUI с почти отсутствующей поддержкой accessibility и локализации.

GUI

Симулятор орбитальной механики (сложность = 6/10, время = 1 неделя)

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

Bitwise Challenge (сложность = 3/10, время = 2-3 дня)

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

Snake
Snake

ECS-фреймворк (сложность = 4/10, время = 1-2 недели)

Предлагаю всем читающим статью разработчикам игр реализовать собственный ECS-фреймворк. Это не так сложно, как можно подумать (возможно, вы уже случайно создавали нечто подобное!). Задачи со звёздочкой: встроить фичи безопасности и корректности, реализовать качественную интеграцию с фичами системы типов языка программирования.

Я создал собственный ECS для моего проекта Super Mario 64 on the GBA; он понадобился мне из-за уникальных ограничений производительности и памяти платформы, и процесс разработки мне очень понравился.

Эмулятор CHIP-8 (сложность = 3/10, время = 3-6 дней)

CHIP-8 — это прекрасная в своей простоте виртуальная машина в стиле 70-х. Полностью отвечающий спецификации эмулятор можно создать за один-два дня. Для этой платформы создано бесчисленное множество фанатских игр. Я тоже написал для неё игру.

Emul8
Emul8

Шахматный движок (сложность = 5/10, время = 2-5 дней)

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

Chess

Оболочка POSIX (сложность = 4/10, время = 3-5 дней)

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

Tosh
Tosh

Про обучение и LLM

Возможно, вы пользуетесь LLM, что вполне понятно, ведь модели — это удобный инструмент. Они полезны при определённом виде обучения. Но стоит всё-таки отказаться от их использования в подобных проектах. Не нужно есть знания с ложечки. Если вам нравится такой стиль обучения, то прочитайте книгу — радость от создания хобби-проектов связана с исследованием неизвестного без вмешательства кого-то стороннего в поиск решения. Если вы уже давно работаете с LLM, то поначалу это может показаться мучительным, но будьте упорны. Без боли радости не бывает.

Эйфорию бегуна невозможно поймать, катаясь на автобусе.

Комментарии (2)


  1. lea
    30.06.2025 15:56

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


  1. AlexxxxAlex
    30.06.2025 15:56

    Интересно было бы посмотреть на проект с оценкой 10/10 и прикинуть, сколько времени он мог занять.