Я был там // Гендальф
Рекурсия
Всем привет. В этом посте я расскажу о своем первом опыте разработки игры для моей любимой консоли из детства под гордым названием денди (хотя раньше мы их приставками называли, но сейчас уже терминология устоялась). Далее вас ждет много интересного, так что заготавливайте вкусняшки.
Идея создать свою собственную игру для денди появлялась у меня довольно давно, но плотно занялся я этим вопросом только в конце 2022го года.
Основным стимулом для разработки игры послужило мое желание создавать свои модули расширения для консоли, так как для денди их практически не выпускалось, а у меня по этому поводу есть много идей и планов (модуль подключения обычно клавиатуры, модуль выхода в интернет и т.д.).
Изначально была поставлена задача написать хотя бы "Hello, World", который я мог бы запустить на эмуляторе. Но, начав читать переводной курс по разработке игр для денди на языке Си на хабре, мне удалось написать простейшую программу всего лишь за полчаса. И этого мне показалось слишком мало.
Более-менее освоив курс статей с хабра за 2-3 недели, в конце января 2023го было принято решение разработать пошаговую стратегию про стимпанковых мехов для закрепления навыков. Думал, что ограничусь созданием минимального геймплея, но разработка зашла немного дальше.
Такой сеттинг и жанр я выбрал, так как люблю пошаговые стратегии, стимпанк и игры про мехов (фронт мишн ван лав). Тем более у меня были наработки на эту тему в плане механик и немного лора (я делал наброски подобной игры для современных компов, но забросил).
В итоге с начала февраля 2023го началась активная разработка игры и продолжалась она до середины апреля (далее у меня появились более важные дела и игру пришлось отложить до лучших времен).
Игру я хотел анонсировать еще летом, так как базовые механики уже работоспособны и она проходима (хотя конкретно концовки у игры нет, можно просто пройти все уровни и прокачивать меха). Есть даже примерочный открытый мир, но он будет полностью перерисован и доработан.
Разработка игр для NES/Famicom консолей является крайне специфическим занятием, так как требует понимания работы приставки на аппаратном уровне, что для многих является отталкивающим фактором. Но, так как у меня есть опыт разработки софта для микроконтроллеров, эта особенность для меня была не слишком критична.
Далее стоял вопрос о инструментах для разработки игры. Традиционно игры для денди пишут на ассемблере, так как ресурсы консоли очень ограничены и важен каждый такт процессора и каждый байт памяти. Я мог бы писать и на ассемблере, но это затянуло бы проектор и увеличило шансы к его забрасыванию на свалку истории.
В итоге я выбрал компилятор CC65, который позволяет писать код для денди денди на языке си. Этот компилятор поддерживается до сих пор и регулярно выходят обновления.
В качестве среды для разработки я выбрал Visual Studio Code. Для удобной сборки и запуска проекта был написан батник и добавлены горячие клавиши (но это тоже тема для отдельного поста). Так я собираю проект и запускаю его в эмуляторе нажатием одной клавиши на клавиатуре.
Глубоко закапываться в технические особенности консоли и разработки под нее я не хочу, так как ресурс все-таки развлекательный. Хочу отметить только несколько основных особенностей.
Вся графика состоит из тайлов 8х8 пикселей. При этом каждый тайл может использовать только 3 цвета и один прозрачный цвет (прозрачный цвет отображает цвет фона, а цвет фона определяется определенными битами регистров палитр).
Это значит, что требуется сводить все используемые спрайты к трем цветам, но если если спрайт состоит из нескольких тайлов, каждый тайл может использовать разные палитры (примерно так же это работает и для фона, но там немного сложнее).
Поэтому, если вы хотите вывести случайную картинку в формат NES, то ее нужно свести в формат 4 цветов и до нужно разрешения (256×240 пикселей). Вот пример преобразования картинки в формат, который уже можно вывести в вашу игру:
Подготовку изображения в почти автоматическом режиме легко сделать в фотошопе или гимпе (я использую гимп).
Но самая сложная часть разработки - это рисования пиксель арта в условиях очень низкого разрешения и ограниченности в количество цветов.
Для первых версий игры я использовал готовые спрайты из Front Mission без дополнительной подготовки. Они выглядели так себе, так как игра выходила на 16-битных консолях. Вот так это выглядело:
Когда я показывал людям эти спрайты и не уточнял, что это такое, большинство говорило, что похоже больше на месиво пикселей (я с этим согласен, меха там разглядеть сложно).
Но для тестов мне таких спрайтов хватало. И после рисования сетки поля я решил ее немного украсить травой, что в итоге породило вот такое кислотное чудо:
На скриншоте выше видно, что трава действительно вышла даже немного симпатичная и в меню я тогда использовал некрасивые рамки.
Помимо режима битвы в игру был добавлен режим открытого мира. Карту мира я набросал довольно быстро и больше ее особо не переделывал. Выглядит она на данных момент вот так:
На карте мира каждая локация обозначена постройкой и войти в нее можно с помощью нажатия кнопки "A" на геймпаде. Локация в верхнем-левом углу - это локация-хаб с магазином, а остальные запускают сценарий битвы при входе (в каждой локации разный набор врагов, они отличаются комплектацией мехов и их количеством).
После того, как основные механики были реализованы, был начат процесс перерисовки мехов.
Как я уже говорил, одновременно можно использовать 3 цвета и один прозрачный цвет, который использует цвет фона. 3 цвета на при разрешении 16х24 пикселя на одно меха - это очень мало.
Поэтому я использовал решение, которое дало мне дополнительный цвет. Для этого я отказался от травы на экране и залил весь экран черным фоном. Это дало мне черный четвертый цвет для рисования мехов. Т.е. если я делаю прозрачный пиксель в спрайте, он выглядит как черный. Это позволило нарисовать более-менее адекватных мехов, которые выглядят как мехи. Вот так это выглядит в редакторе:
Уже намного интереснее, но для анимации ходьбы нужно нарисовать для каждого положения по два спрайта (этим я пока не занимался, так как такой мелкий пиксельарт приходится рисовать буквально по пикселю, это очень муторно).
Многие технические ограничения консоли можно обойти за счет использования мапперов, но я пока обхожусь без него, так как хочу сделать создание реального картриджа максимально дешевым и простым. Стараюсь уложиться в стандартные 32 килобайта (место я потратил еще не все, музыка и прочее туда должно поместиться, тем более многое можно оптимизировать).
Резюмируя особенности разработки, можно сказать, что разработка игр для ретро-консолей особо ничем не отличается от разработки программ для микроконтроллеров. По этой причине постоянно приходится смотреть даташиты, описывающие разные узлы консоли.
Игра представляет собой классическую пошаговую стратегию, основанную на механике использования очков действия (AP). Каждое действие тратит очки действия, примерно как в лучшей в мире игре Fallout 2 (только у меня клетки квадратные). Система с фазами (как в X-COM) мне нравится меньше.
В режиме битвы игрок управляет своим мехом и пытается уничтожить вражеские мехи. Мех считается уничтоженным, если он лишается тела или обеих рук (без рук мех бесполезен). При этом, если мех лишается головы, он сильно теряет в точности, а если у него взрываются ноги, то он не может передвигаться. Битва заканчивается уничтожением всех вражеских мехов или гибелью игрока. Если игрок побеждает, он получает деньги за каждую сохраненную деталь вражеского меха.
Все оружие в игре делится на 4 типа:
Рукопашное оружие (может атаковать на одну клетку и есть возможность выбора точки атаки)
Пушки (наносят урон по случайной части меха с расстояния)
Снайперское оружие (наносят урон с расстояния и имеют возможность выбрать деталь вражеского меха для атаки)
Дробовики/картечницы (наносят урон по нескольким случайным частям меха)
Возможно будут еще какие-то типы оружия.
Вот пример меню выбора части меха для атаки:
Еще есть режим осмотра мехов (отображает имя, состояние частей меха и вооружение):
В режиме перемещения вы перемещаете меха курсором (каждый шаг тратит одно очко AP). Кнопка 'A' подтверждает перемещение, а кнопка 'B' возвращает меха на начальную точку (отменяет перемещение).
Механика использования экипировки пока не реализована.
Следующей важной частью игры является прокачка меха.
Вот так выглядит список доступных мест в локации-хабе:
А вот для примера магазин оружия:
Кнопка А покупает оружие в правую руку, В в левую, а Select возвращает вас на карту мира.
Вот мы и рассмотрели все основные особенности игры. Остальное вы можете попробовать сами используя эмулятор (ссылку на скачивание эмулятора и рома игры я дам в конце, если пикабу ссылки не уберет).
Планов по развитию игры у меня довольно много. Давайте приведу основные планы в виде списка:
Создание нормальной карты мира и проработка локаций на ней
Динамические анимации движения мехов в режиме битвы
Создание возможности ходить персонажем по хаб-локации и общаться там с людьми (но это сильно упирается в 32 килобайта памяти)
Написание лора с сюжетом и добавление его в игру
Создание диалоговой системы
Добавление звуков и музыки в игру (музыка на денди особенно специфическая штука)
Добавление новых спрайтов для мехов
Добавление различных построек и препятствий в режиме битвы (для оживления поля битвы)
Улучшение ИИ и добавление новых механик в битву
Расширение количества доступных частей и оружия для мехов
Режим игры для двоих игроков (PvP и PvE)
Для первого поста и анонса игры, я думаю, информации более-чем достаточно. Очень жду ваших предложений и замечаний по игре. Весь этот текст был написан в первую очередь ради получения обратной связи от потенциальных игроков, так как я не могу знать, что нравится другим людям, а исходить только из собственных соображений - это путь в никуда.
Поэтому жду вас в комментариях, готов ответить на все ваши вопросы. Спасибо за внимание.
Цикл статей по разработке игры для денди - https://habr.com/ru/articles/348022/
Википедия по разработке для NES (там все оч подробно описано и с примерами кода, но английским) - https://www.nesdev.org/wiki/NES_reference_guide
Живой форум по разработке ретро-игр (и не только) - emu-land.net
Сайт компилятор СС65 - https://www.cc65.org/
Еще несколько хороших статей про устройство консоли (на русском) - http://dendy.migera.ru/nes/g00.html
Эмулятор который я использую для отладки игры - fceux.com
Страница проекта. Там можно скачать ROM-файл для эмулятора (Нужно ли делать отдельный паблик для игры?) - http://73-it.ru/the-iron-steam.html
С начала этого года я взялся изучать C#. Некоторое представление о программировании уже было т.к. в школе, году так в 2005-м, закончил курсы по Delphi. В принципе каких либо проблем с пониманием материала при изучении Шилдта, статей и видео-уроков у меня не возникало. Проблемы есть с большими перерывами в обучении и иногда отсутствием желания. С начала обучения прошло уже почти 9 месяцев, но в общей сложности занимался дай бог месяца 4. Не знаю на сколько глубоко можно постичь программирование за такой срок самообучаясь, но хочу показать свой маленький проект.
Это простенькая программка для учета товара в цветочном магазине. Функционал минимальный и есть над чем работать. За внешний вид прошу не пинать. С визуальным оформлением я еще не знакомился.
Это главное окно. Тут думаю все понятно
2. Это форма добавления товара в базу данных. КомбоБоксы связанны с базой, все работает, база обновляется. Ошибок пока не выявил.
3. Это форма редактирования базы данных. Так же все связанно с БД и можно поправить данные. Все работает корректно.
4. Это форма сборки букета. Тут по кнопкам добавить\удалить происходит добавление или удаление строки которая формирует один из ингредиентов букета. Каждый ингредиент это отдельный экземпляр класса
Ну поле названия и поля цен на дополнительные материалы... По кнопке "сформировать" считается цена букета, а по кнопке "сохранить" происходит редактирование основной таблицы базы, где хранится инфа о цветах, и запись в таблицу для букетов (название и цена).
5. Это форма продажи. Выбираем вид цветка, его сорт и количество, потом добавляем в чек. Чек это тоже объект класса имеющий поля в которых хранится цена, название и количество цветов или букета. Можно добавлять в чек много позиций на случай если покупают несколько сортов. Так же в чек можно добавить букет из списка собранных.
Вот такая вот программка. Уверен, что более или менее опытный шарпист размажет мой код, найдет кучу косяков и сделает более грамотно))). Так же программа требует серьезного допила. Но все же она работает и выполняет свой минимум, и для меня это дополнительная мотивация учиться дальше)))
Я изучаю C# уже несколько месяцев, но так как мне уже 33 года, то на работу особо не рассчитываю, это больше для себя, для тренировки мозга и, думаю, что в будущем смогу помочь сыну, если программирование его заинтересует. И вот из всего этого (по ощущениям бесконечного) объема знаний у меня складывается впечатление, что вот эта вот иерархия от начинающих до синьоров, складывается лишь из опыта и количества решеных задач. Такое впечатление, что синьор будет так же как и джун несколько часов гуглить и думать как правильно написать код, если ранее он не сталкивался с подобными задачами или тупо забыл что-то, что давно не использовал. Разница их лишь в том, кто какой сложности задачи решает. И если джуну надо пару тройку часов, то синьору минут 15.
Я вот берусь за очередную тему, изучаю, понимаю ее и вполне могу прочитать и понять код и логику программы из примера, но вот чтоб написать что-то подобное или более сложное... на это мне понадобилось бы дофига времени с перелопачиванием гугла и учебников. А информация как будто бесконечная: спросишь на форуме какие темы изучить, чтоб решить данную задачу, а тебе целый список выкатывают, и кто на что горазд. Хочешь работать с БД? Ну возьми для начала вон ту книжку на 400 страниц. Хочешь, чтоб в этом комбоБоксе, в зависимости от другого, появлялись разные списки из таблиц в БД? На тебе еще инфы на денек другой. А если код тебе кидают, то там обязательно будет что-то новое и непонятное, хотя задача элементарная. Так пока я до лямбда выражений и LINQ не дошел, большинство скинутых примеров вообще были темным лесом. И забывается инфа на раз два. Например помню, что легко понял тему по ref/out, но т.к. не пользуюсь, то сейчас блин не помню как пользоваться - надо повторять. Я хоть и вижу, что некоторые аспекты сейчас уже получаются чуть ли не на автомате, все эти объемы демотивируют, и кажется, что до вменяемого уровня джуна как до луны. Короче бодрящего пинка хочу))
И меня не обошло сие новомодное поветрие. Нашел чат в телеграме с доступом к ChatGPT и стал думать: а что бы такое его спросить? Давайте сначала теста ради что-нибудь простенькое:
Потрясающе! Но может ли оно объяснить, что там в коде за что отвечает?
Обалдеть. Оно почти понимает. А вот интересно, оно умеет только стандартный Си?
Однако. Оно умеет под STM32, причем самым пионерским ардуиновским способом - считая такты процессора. Но, тем не менее, под SPL. Умеет ли оно использовать таймер?
Так, и что мы видим? Мы видим, что инициализировать таймер оно умеет. И с правильными значениями. Но в процедуре прерывания оно не использует! И вместо этого вводит дополнительную процедуру, считающую такты процессора.
Таймер же оно использует, чтобы сделать задержку в 1 секунду в главном цикле! Напоминает известный анекдот: как вскипятить пустой чайник? налить воду и поставить на огонь. а если в чайнике уже есть вода? Вылить и тем самым свести условия задачи к предыдущему :) Возможно, робот неправильно меня понял :)
Охренеть. Во-первых, используется совсем другой метод - через флаг, устанавливаемый в прерывании. В самом прерывании оно не захотело вставлять команду переключения выхода. Во-вторых, все-таки необходимо было конкретизировать.
Вердикт - человек пока что пишет программы под STM32 лучше этой штуки. Но эта штука пишет уже лучше ардуиновского пионера. Где-то и такой подход сойдет.
Я студент, первый курс МФТИ. Думаю, неплохо разбираюсь в C, и сейчас могу написать на нём что угодно (что не работает с сетью, эту тему я пока не трогал). C++ желания "учить" нет, особых отличий между этими языками не вижу.
Недавно стала интересна подработка на лето, прочитал про то как искать первую работу, посмотрел реальные вакансии и резюме.
Первое: вакансий для C практически нет, и это при том, что он достаточно популярен, если верить этому сайту (сайт выбран по принципу "много встречал в сети"). Я неправильно ищу и есть отдельные сайты для вакансий C/C++
Второе: есть некоторое количество вакансий C/C++(и просто много вакансий C++), но в них требуются абсолютно незнакомые мне вещи, даже в вакансиях для джунов (обычно это с десяток аббревиатур, которые не сразу и загуглишь) + небольшая часть знакомых, но без уточнения уровня (например, git / unix-системы / работа с сетью / графическое программирование). Как понять требуемый уровень? Спрашивать каждого работодателя отдельно?
Знаю ли я git, если не пользуюсь им, но понимаю принципы (как он работает), и могу написать свой (только локальный)?
Третье: в примерах резюме часто (почти всегда) упоминают "пет-проекты", иногда даже приводят примеры. Конечно, половина программистов это что-то из веба (тема, которой я стараюсь не касаться), и для них проекты - создание сайтов, но у остальных что-то мне понятное, однако совсем с моей точки зрения несложное. Пример: чуваки пишут калькулятор (пару сотен строк), и называют это проектом. Я тоже могу написать калькулятор, но (почти), как говориться " from scratch* ", используя только openGL и стандартные
*какой-нибудь glfw для создания окошек и считывания нажатий с клавиатуры я бы всё-таки использовал
Так что же мне делать? Раньше я думал, что достаточно просто шарить в C, посмотрев вакансии приуныл, посмотрев резюме посмеялся. Я уже джун, или мне до него как до Египта& (идти до него примерно полгода)