К нашему циклу из 12/14 космооперных романов я написал-навайбкодил две простенькие игры. Сначала о первой - СИМУЛЯТОР ПРИНЦА-ПРЕТЕНДЕНТА. Всё в стиле классических древних игрушек на Spectrum и DOS, простенькая текстовая RPG, 10 врагов, 6 локаций и парочка пасхалок.
По сюжету нашего с Д.Богуцким цикла, если кто не читал, главный герой - проснувшийся из стазис-капсулы герой галактики, 1000-й принц в иерархии престолонаследия. После 100 лет анархии, вызванной нашествием Орды на космическую империю, он начинает заново, выбрав для старта захолустную планету, прибежище пиратов и заброшенный космодром (да-да, мы звёзд с неба не хватаем, и у нас вполне классическая космоопера, вернее, космобоярка, фьюжн из Вахи, Дюны, ЗВ и Лукьяненковского "Лорда с Планеты Земля". Сергей Васильевич, кстати, по старой дружбе рекомендовал нас в своём разделе на АТ.)
Вы стартуете на Станции космических челноков, также на старте доступны локации "Животноводство" и "Развал". Ваша задача - победить в ходе сюжета 10 врагов, пополняя свой инвентарь оружия, восстанавливаясь при помощи Киберборделя или молочка мультикоровы, пополняя запас артефактов. По ходу сюжета добавляются локации и доступно несколько простеньких пасхалок, знакомых читателям по сюжету цикла.
Как это сделано под капотом Голый и одиночный, без ассетов JS-файл, за основу которого был взят репозиторий "OpenGopnik" на гите. Была когда-то в 2000ые популярная текстовая РПГ-игрушка про гопника.
При помощи Qwen я распотрошил исходники, переписал их на JS и объединил, задав в промпте названия и тип локаций, виды мини-игр, переписав последовательно боссов и оружие. В дальнейшем я скармливал исходник в Deepseek, и, насколько хватало контекстное окно, балансил врагов, добавлял пасхалок и т.п. В целом не назову это совсем уж тупым вайбкодингом, потому что плюс-минус я понимаю, как устроена игра, и многое в ходе конечных правок правил сам без нейронок.
В какой-то момент я обнаружил, что на мобильниках кнопки слишком большие и не умещаются в экран, и, не заморачиваясь, сделал сверху кнопку для переключения на "мобильную версию".
Предвосхищая вопросы
Да, я пользовался только бесплатными доступными нейронками, потому что на тот момент не обладал подписками (да и сейчас платные использую минимально, для картиночек и т.п.). Да, это, по сути, мой первый (за лет 10, не считая древних попыток освоить Godot) опыт в около-геймдеве, потому что реиграбельность и прочее вышли весьма слабенькие.
Да, я знаю, что можно сделать нормальное приложение и разместить это на нормальном веб-сервере, а не на странице тильды, но, опять же, тильда у меня была куплена ещё до этого и используется как лендинги для циклов, поэтому не видел смысла что-то сильно тратить на проект, который создавался, по сути, для фана и пробретения опыта, ну и для небольшого числа наших читателей-подписчиков в ТГ (ссылку на канал давать не буду, ищите сами).
По этой же причине - нет, непосредственно на игре я не зарабатываю (и не очень-то верю, что она может ощутимо привлечь кого-то на цикл романов, поэтому как промо-инструмент тоже сомнительный, аудитории слабо пересекаются).
Мой соавтор Дима - профессиональный нарративный гейм-дизайнер с огромным опытом работы, но тратить его трудовой ресурс я не стал, показал уже практически конечный продукт, и он порекомендовал всего несколько изменений. Всего потратил на эту развлекуху около двух вечеров и дважды-трижды по полчаса в обеденные перерывы.
Предлагаю небольшой челлендж для тех, кто пишет на JavaScript или TypeScript.
В квизе — 10 коротких фрагментов кода из известных Open Source-проектов. В каждом PVS-Studio когда-то нашёл ошибку, но вам об этом заранее не скажут.
Задача простая: найти подозрительное место за 60 секунд. Успели — получаете балл. Не успели — что ж, возможно, статический анализатор оказался внимательнее 😄
На всё уйдёт около 15 минут. А в конце ещё обещают подарок.
Проверим, насколько хорошо вы умеете замечать ошибки, которые не бросаются в глаза?
Попался мне сервис VibeCraft, помощник в создании сайтов и веб-приложений без знания программирования. Набрасываешь ИИшке свою идею, обсуждаете её и она сама начинает его делать. Если результат тебя устроит то можно опубликовать через Яндекс Облако всему миру.
Встречающий интерфейс
Я решил придумать игру, которая хорошо подходит под такой формат разработки: технически достаточно компактную, без сложной физики, огромного мира, управляемого персонажа, pathfinding и других вещей, которые моментально раздувают небольшой проект, но при этом не совсем примитивную. Хотелось, чтобы одно прохождение занимало хотя бы полчаса, чтобы во время него был заметный прогресс и чтобы после победы оставалась причина начать заново.
Идею игры я стал придумывать с другой ИИ моделью. Мы перебрали несколько концепций, и в какой-то момент появилась идея выживания после кораблекрушения. Есть небольшая группа людей, оказавшихся на острове. Их нужно кормить, распределять по профессиям, добывать ресурсы, строить поселение, исследовать остров и в конечном итоге собрать корабль, чтобы выбраться.
После этого дизайн документ на 1600 строк отправился в Vibecraft и разработка игры началась :)
Первый вариант игры
Оказался довольно полноценным, при этом игра не развивалась по классическому сценарию «сначала две кнопки, потом постепенно добавлял механики». Основные системы были задуманы практически сразу: население, профессии, несколько видов ресурсов, здания, улучшения, экспедиции, случайные события и строительство корабля как финальная цель.
Игровой цикл получился довольно простой. Игрок распределяет людей по профессиям, те постоянно производят ресурсы. За ресурсы строятся здания, которые открывают новые профессии и возможности. Часть жителей можно отправлять в экспедиции, временно теряя их как рабочих, но получая взамен редкие ресурсы, бонусы или новых людей. Постепенно открывается верфь, после чего начинается строительство корабля. Когда он готов, можно покинуть остров и закончить прохождение.
То есть довольно быстро возникла ситуация, когда игра уже формально была игрой: её можно было запустить, развить поселение и победить. Казалось бы, осталось немного отполировать интерфейс и можно выпускать.
Первая версия с доработками
На практике именно в этот момент и началась большая часть работы.
Пока механика существует только в голове или в таблице, всё обычно выглядит логично. Когда начинаешь проходить собственную игру от начала до конца, внезапно обнаруживаются очень простые проблемы. Например, для строительства Лесного лагеря требовалось волокно, а стабильная добыча волокна открывалась как раз после строительства Лесного лагеря. Формально всё было реализовано правильно, ошибок в коде не было, интерфейс работал - просто пройти игру дальше было невозможно.
Таких случаев оказалось достаточно много. Где-то один ресурс накапливался слишком медленно, где-то наиболее выгодной стратегией становилось отправить почти всех жителей в одну профессию, где-то игрок открывал новую возможность, но не замечал этого, а где-то после случайного события было совершенно непонятно, стало поселению лучше или хуже. И в какой-то момент стало очевидно, что сделать систему работающей и сделать её нормально играющейся - довольно разные задачи.
После первого варианта я уже решил утащить проект из VibeCraft и с помощью ИИ агента доделывать его.
Интерфейс
Самая большая доработка, если смотреть на игру глазами разработчика, первый вариант интерфейса был совершенно нормальным. Есть блок с ресурсами, есть профессии, здания, улучшения, экспедиции и корабль. Все данные на экране присутствуют - вроде бы чего ещё хотеть?
Но чем больше становилось контента, тем сильнее интерфейс начинал напоминать панель управления каким-то складским комплексом. Игроку постоянно приходилось искать, где именно появилось новое доступное действие, почему сейчас нельзя построить нужное здание и что вообще лучше делать дальше.
В результате интерфейс пережил несколько серьёзных переделок. Основные вещи - население, ресурсы и текущая цель - остались постоянно видимыми, а остальные системы разъехались по отдельным вкладкам. Заблокированный контент начали явно отличать визуально, а для текущей цели появилась отдельная подсказка.
Причём первая версия этой подсказки была довольно забавной. Она выглядела умной, но на самом деле просто рекомендовала следующую доступную экспедицию. Это быстро стало очевидно во время тестирования. В следующей версии подсказка уже анализировала текущую цель и пыталась предложить действительно полезное действие. Если для строительства не хватает камня - найти способ получить камень. Если есть подходящая экспедиция, предложить её. Если нет - посоветовать назначить больше людей каменщиками.
Такие изменения кажутся мелочами по сравнению с добавлением новой механики, но именно после них игра начинает ощущаться заметно понятнее.
Механики
Экспедиции были в проекте с самого начала, но позже они заметно изменились. Изначально экспедиции были максимально простыми: отправил экспедицию, ждешь получения результата. Для первых минут игры этого хватало, но довольно быстро такие события стали слишком предсказуемыми.
Тогда у них появились разветвления. Теперь одно решение может привести к следующему этапу экспедиции, где игроку снова приходится выбирать. Например, можно сразу забрать небольшую гарантированную награду или рискнуть и продолжить исследование. Во втором случае результат может оказаться значительно лучше, а может закончиться потерей ресурсов, временным негативным эффектом или другой неприятностью.
Из простых модальных окон экспедиции постепенно превратились в небольшие истории. Некоторые ветки позволяют вовремя остановиться и сохранить уже найденное, другие специально провоцируют попробовать удачу ещё раз.
Можно было продолжать добавлять в игру новые системы, но гораздо полезнее оказалось сделать интереснее те, которые уже существуют.
Метапрогрессия
А вот разные острова как раз не входили в самый первый вариант игры. К их появлению постепенно подтолкнула метапрогрессия.
После прохождения игрок получает очки выживания, которые можно потратить на постоянные улучшения: увеличить производство, получить больше еды в начале следующего прохождения, расширить склад, сделать эффективнее рыбаков или строителей, улучшить экспедиции и так далее. Но довольно быстро возник очевидный вопрос: зачем становиться сильнее между прохождениями, если после этого игрок просто снова попадает на абсолютно тот же остров?
Так появились новые острова с разными условиями. Не хотелось делать под каждый из них отдельный набор механик, вместо этого они используют ту же экономику, но меняют её параметры. На одном острове сложнее добывать определённые ресурсы, на другом сильнее давление со стороны потребления еды, где-то дольше идёт строительство, а где-то чаще случаются неприятные события.
Получилось, что одна и та же игровая система начинает требовать немного другой стратегии без необходимости создавать ещё одну игру внутри игры. С точки зрения объёма разработки это оказалось довольно выгодным способом увеличить реиграбельность.
Графика
Отдельно постепенно развивалась визуальная часть. Сначала главной задачей было просто сделать интерфейс читаемым, но довольно быстро захотелось, чтобы происходящее ощущалось именно игрой, а не таблицей ресурсов с кнопками. Появились иконки профессий, ресурсов, событий, экспедиций и улучшений, отдельные изображения островов, а затем и сама сцена поселения. Графика эволюционировала от эмоджи до полноценных (сгенерированных, но всеже) иконок.
Когда сама игра уже была проходимой, начался отдельный этап подготовки к публикации в Яндекс Играх. SDK, реклама, rewarded-реклама, сохранения, локализация, требования платформы к поведению страницы, иконка, обложка, gameplay-видео, русская и английская версия оформления. Почти ничего из этого не делает непосредственно игровой процесс интереснее, но без этих вещей игра всё ещё остаётся проектом на компьютере разработчика, а не законченным продуктом.
Итоговая версия
Немного о том, как всё устроено внутри
Технически проект получился довольно обычным веб-приложением на React и TypeScript. Сейчас он собирается через Vite. При этом игровая логика старается не зависеть от интерфейса: есть общее состояние игры и игровой tick, который занимается производством и потреблением ресурсов, строительством, таймерами экспедиций, временными эффектами и другими процессами.
Большая часть контента хранится в виде конфигураций. Отдельно описаны профессии, здания, улучшения, события, экспедиции, острова и мета-улучшения. Благодаря этому добавить новое событие или изменить параметры острова можно без переписывания основной логики игры.
По мере развития проекта вокруг этого довольно простого ядра начало появляться всё больше обычной продуктовой инфраструктуры. Появились автосохранения, русская и английская локализация, интеграция с SDK Яндекс Игр, реклама, rewarded-реклама, unit-тесты, E2E-тесты через Playwright и даже отдельный скрипт для симуляции баланса.
Проект немного вырос из первоначальной идеи «сделаем что-нибудь компактное».
Отдельной технической историей оказался переход с Next.js на Vite. Изначально проект в VibeCraft использовал Next.js, и каких-то принципиальных проблем с ним не было. Просто формат публикации в Яндекс Играх довольно простой: нужно собрать готовые статические файлы, положить их в архив и загрузить на платформу. Внутри должен находиться `index.html`, JavaScript, стили и ассеты, причём желательно с максимально предсказуемыми относительными путями.
Для такого сценария Next.js оказался просто менее удобен, чем хотелось. Серверная часть игре была не нужна вообще, а задача фактически сводилась к получению максимально обычной папки со статическим билдом. После перехода на Vite процесс стал гораздо проще: собрал проект, получил готовую директорию, заархивировал и загрузил в Яндекс Игры.
Это не столько история о том, что один инструмент лучше другого, сколько обычный случай, когда более простой инструмент лучше соответствует конкретной задаче.
И немного про AI
Почти весь проект делался с активным использованием AI-инструментов, и после этой разработки у меня осталось довольно чёткое впечатление: AI действительно очень сильно снижает стоимость реализации.
Сделать новый экран, изменить компонент, добавить тест, переделать систему сохранений или реализовать небольшую механику сейчас можно заметно быстрее, чем раньше. Иногда достаточно нормально сформулировать задачу, и значительная часть рутинной работы исчезает.
Но есть обратная сторона. Сама необходимость принимать решения никуда не делась. Кто-то всё равно должен заметить, что игрок не видит доступное здание, понять причину и решить, что именно нужно поменять. Кто-то должен обнаружить тупик в прогрессии, заметить скучную ветку события или понять, что ещё одна новая механика игре уже не нужна.
Наверное, мой главный вывод после этого проекта именно такой: AI сильно удешевил написание кода, но из-за этого ещё важнее стало понимать, что именно стоит писать.
Добавить в игру ещё одну систему теперь очень легко. Иногда даже слишком легко. Поэтому одна из самых сложных задач постепенно становится не «как это реализовать», а «нужно ли это вообще реализовывать».
В итоге проект, который начинался как небольшой эксперимент для Vibecraft, довольно быстро превратился в самостоятельную браузерную игру.
Самым важным для меня было не количество сделанных механик, а сам факт того, что игру удалось довести до состояния, когда можно перестать добавлять фичи, собрать архив и наконец нажать кнопку публикации. И на все это потратилось меньше недели времени.
Здравствуйте, сеньоры, помидоры Есть 2 файла, я их соединяю в один, в заголовок файла на выходе нужно записать хэш соединенных данных, в конец нужно записать хэш вместе с заголовком, как это сделать через браузер без перечитывания исходных файлов, без буфера в память или лишней копии на диске, перечитать финальный файл можно, то есть чтобы кроме финального файла больше ничего не создавать?
Кажется не сложно, надо просто перечитать соединённые данные для хэша, на лету посчитать без буфера нельзя так как сначала пишем середину, а потом надо вернуться записать заголовок, браузер не может открыть на чтение файл который открыт на запись, но если открыть перечитать, а потом открыть дописать он делает копию на диске.