gopnik

Приступ «гопникомании»

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

Исходный код оригинальной игры, по всей видимости, канул в лету, но мне когда-то повезло наткнуться на неоконченный порт этой игры под Линукс. С тех пор я ей иногда занимаюсь.

Пиксельный портрет мужчины в кепке с сигаретой и надписью «ГОПНИК-2», подзаголовками «ОКОРЕНИЕ», «УЛЬТУРНОЙ», «ТОЛИЦЫ» на тёмном фоне.
Заставка оригинальной игры, взятая из текстового файла описания

Недавно в мой репозиторий пришёл некий активный гражданин и навёл там суеты, за что я ему благодарен. В частности, он подчеркнул кое-какие изъяны в балансе, плюс оказалось, что в процессе перевода кода с сишного printf на модуль Си++ fmt, я поломал буферизацию в Винде, которую когда-то чинил простым макросом.

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

Тем не менее, как мне кажется, с нейросетью я делал исправления куда быстрее, чем это вышло бы у меня без неё. Кстати, очень здорово выручают тесты — если попросить нейросеть написать тест, а потом добиться чтобы он заработал (или хотя бы не сломался), то участие человека требуется минимальное.

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

16 комментариев

Накрыло «Гопником-2»

Что-то мой закрывшийся, было, гештальт опять открылся — думал, что меня этот старинный текстовый квест уже не интересует, ан нет, вчера что-то совершенно не спалось, я снова расчехлил игру «Гопник-2» и играл в неё до поздней ночи.

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

Скриншот текстового квеста: описание стычки банд и списки участников «Ваша басота» (зелёные) и «Их басота» (красные) с уровнями.
Меня позвали на «стрелку» в игре «Гопник-2», если бы не шокер, я бы не выжил

Оставить комментарий

«Гопник-2»: убрал printf

Закончил убирать функцию printf, сегодня вколотил последний гвоздь в крышку её гроба. Я почему-то наивно полагал, что на этом моя работа по избавлению от char * будет окончена, но не учёл, что в коде довольно много (больше 150) других мест, где ещё используется этот тип.

В процессе замены встретилось вот такое. Загадка, всё ли хорошо в следующем коде?

std::cout << fmt::format(" {}(+{})", main_hero->inv[i].name, main_hero->inv[i].armo)

Мой компилятор считает, что всё, но сборка на «Гитхабе» падает с ошибкой «Binding packed field error».

Получается, я по неведомой причине не могу обратиться по ссылке на поле внутри упакованной структуры (fmt::format принимает параметры по ссылке).

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

const auto name = main_hero->inv[i].name;
const auto armo = main_hero->inv[i].armo;

std::cout << fmt::format(" {}(+{})", name, armo);

Выглядит, как костыль, но самое главное — почему один компилятор требует промежуточные переменные, а другой умеет и без них?

Я бы понял, если бы «Гитхаб» собирал мне бинарники для какой-то экзотической архитектуры, где есть какие-то особенности адресации, но тут такого ведь и в помине нет.

2 комментария

«Гопник-2»: что нового?

Можно подумать, что я совсем забросил заниматься игрой «Гопник-2», про которую ещё недавно так много писал, но это не так. Просто ничего особо интересного я там пока не делаю, — в основном довольно механически заменяю сишные строки (char *) на сиплюсплюсный класс std::string.

Недавно появившиеся контрибьюторы добавили мне в проект библиотеку fmt, что упростило работу, — во-первых, теперь не приходится костылить собственные обёртки, чтобы чем-то заменить сишную функцию форматирования printf, а во-вторых, из-за гибкости fmt можно оставлять какие-то места почти нетронутыми, если сходу не удаётся перевести их на новые рельсы. Удобно.

Осталось примерно 260 замен, не так много, было около 400 или около того.

Скриншот терминала: вывод теста gop2_tests с сообщениями о займе у пацанов и понтовости, завершающийся зелёным «All tests passed (12 assertions in 1 test case)».
Тесты прошли успешно

Ещё ребята постарались добавить мне тесты. Я ещё не смотрел, но планирую ознакомиться с тем как это делает. Так как на Си++ я раньше не писал, то совершенно без понятия как они тут выглядят, любопытно.

Оставить комментарий

«Гопник-2»: контрибьюторы

Фантастика! У меня на проекте буквально за эти выходные появилось ещё два контрибьютора.

deadem перевёл проект на сборку cmake, принёс библиотеку форматирования fmt и приделал к нему CI «Гитхаба», теперь сборка идёт прямо там. kartaris убрал fmt в зависимости, принёс менеджер пакетов conan и дописал код для использования в нём fmt.

Это для меня новый интересный опыт — у меня не было возможности поработать на «Гитхабе» с контрибьюторами, да и само по себе приятно, что к проекту подключились новые люди и затащили в него достаточно сложные штуки.

Графики активности bolknote, deadem, kartaris (2011–2023): коммиты и изменения строк
Активность по контрибьюторам в проекте на «Гитхабе»

Оставить комментарий

«Гопник-2»: переход на нормальный Си++11

Как я писал прежде, когда я адаптировал «Гопника-2» для запуска под «Виндоузом», столкнулся с тем, что не все тамошние компиляторы игру собирали. Не хватало двух функций — strdup и _fileno. Проблема решилось переключением компилятора на стандарт gnu++11, но меня это беспокоило — вдруг найдётся компилятор, который его не поддерживает.

Тут у нас в Татарстане выдались длинные выходные, — в праздник «Ураза-байрам» у нас выходной, я решил этим воспользоваться и поковырять эту тему подробнее.

Вызов _fileno у меня использовался для получения номера дескриптора входного потока, так что тут всё решилось просто, — для этого есть специальная константа STDIN_FILENO. А вот с strdup пришлось повозиться.

Сначала я, разумеется, сделал свою реализацию — там всего-то три строки и заменил все вызовы на неё. Но мне показалось, что это слишком простое решение. А когда я программирую для души, мне хочется либо чему-то поучиться, либо сделать всё позамороченнее.

Первым делом пошёл на поклон к «ЧатГПТ», спросил совета. Советы не заработали, но дали направление мысли.

Первая мысль была забахать макрос, который заменял бы собой strdup в проблемном компиляторе, а остальные не трогал. Тут надо сказать, что под «Виндой» далеко не во всех наборах утилит компиляторы не содержат функцию strdup, например в msys2 она есть.

Мне хотелось как-то отличать между собой обычный mingw без strdup от того, который внутри msys2. «ЧатГПТ» тут не помог, хоть и подсунул несколько макросов на пробу, которых в действительности не существует.

Пришлось пошарить по исходникам. Оказалось, есть ряд макросов, которые присутствуют в msys2, но отсутствуют в msys. Из них я выбрал __MINGW64_VERSION_MAJOR:

#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
#define strdup(s) (__extension__({ const char* __s = (s); size_t __l = strlen(__s) + 1; char* __d = (char*)malloc(__l);\
__d ? (char*)memcpy(__d, __s, __l) : nullptr; }))
#endif

Тут используется расширение, которое позволяет писать многострочные макросы. Хотя этот вариант мне и нравится, но опять используется не нормальный Си++, а расширение компилятора.

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

Если упрощать, то символы — это экспортируемые именованные сущности. Те, что какой-то модуль может отдать во внешнее пользование. Если символ «сильный», то его имя никто не может занять, такой код просто не соберётся — компилятор скажет, что существует два символа с одним именем, а если он «слабый», то его можно заменить.

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

Если перевернуть ситуацию, и считать мой код библиотекой, а тот код, где должна быть определена strdup основным, то всё должно получиться.

«ЧатГПТ», к сожалению, помочь не смог, — сначала подсовывал нерабочий код, а потом зациклился в своих советах. Поэтому пришлось разбираться самостоятельно.

Всё оказалось не так уж и сложно. Сначала в заголовочном файле определяем прототип функции:

#ifdef __MINGW32__
char *strdup(const char *s1);
#endif

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

Потом в самом коде создаём слабый символ для strdup:

#ifdef __MINGW32__
#pragma weak my_strdup
char *strdup(const char *src) {
    size_t len = strlen(src) + 1;
    char *s = (char *) malloc(len);
    return s == nullptr ? nullptr : (char *) memcpy(s, src, len);
}
#endif

Слабый символ я определяю через директиву #pragma weak, у которой надо указать имя слабого символа, причём оно должно отличаться от имени функции. Я пока не до конца понял зачем это нужно делать, но без этого не работает.

Кстати, #pragma weak тоже расширение, но оно легко заменяется на атрибут weak, надо только будет изучить его синтаксис, я не успел этого сделать.

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

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

Дополнено: в итоге все ситуации я побороть не смог и откатился на самое простое решение со своей собственной реализацией strdup.

Оставить комментарий

«Гопник-2»: новости

Может показаться, что после релиза «Гопника-2» я игрой больше не занимался, так как ничего про неё не пишу.

Как можно догадаться по этой заметке, это не так. За последнее время я исправил несколько незначительных багов и реализовал кое-что из своих планов.

Текст битвы в игре: игрок наносит урон шоком, получает ответные удары, побеждает врага, получает 90 качков опыта; в конце — «А у Нарка был косячок. Пиво победителю!
Новая штука в игре — шокер, можно бить противника током

Я долго не понимал как во внутреннем АПИ игры формируются прайс-листы, но теперь разобрался и сделал, как и планировал, на новой станции «Чёрная речка» ларёк. В нём можно покрепиться семечками и шавермой (мы же в Питере), а так же купить батарейки для шокера — нового игрового предмета.

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

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

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

2 комментария

«Гопник-2»: версия 1.24

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

Там универсальный бинарник под МакОС и статически собранные файлы под 64-битные «Виндоуз» и «Линукс». Ссылка для скачивания выше, а ниже скриншот, в нём ссылки не работают.

Релиз 1.24: исправлен баг с «Чёрной речкой», герой не может драться при побеге, сборка под Android; доступны бинарники для Linux, macOS, Windows и исходники.

Оставить комментарий

«Гопник-2»: теперь «Андроид»

В полку не совсем обычных платформ, где я попробовал собрать «Гопника-2», прибыло. В этот раз, пока обедал, листал экраны на смартфоне и взгляд упал на терминал Termux, который я когда-то ставил, чтобы иметь возможность зайти экстренно куда-нибудь по работе.

Решил попробовать скомпилируется ли. В принципе проблем почти не возникло. Всё необходимое поставил командой pkg install make clang git, после чего выписал проект и поправил путь до заголовочного файла — в «Андроиде» он находится в другом месте.

Скриншот текстовой RPG: игрок «bolk» в Купчине, уровень 0, здоровье 35/35, точность 30%, пива и бабла нет; начал битву с Гопником 1 уровня, ударил на 33 урона, враг промахался.
Так выглядит запущенный «Гопник-2», запущенный в терминале Termux под «Андроидом»

Правки в репозиторий внёс, теперь всё будет собираться ещё и под «Андроид». Проверять в будущем я не буду, вряд ли кто-то будет собирать для себя, но проверить было интересно.

4 комментария

«Гопник-2»: фан-клуб

Тем временем, у игры «Гопник-2», с которой я вожусь почти каждый день в последнее время, отрос небольшой фан-клуб. Самый заметный его участник, bairog, прошёл всю игру вдоль и поперёк, завёл мне десяток багов, которые я постепенно исправил и даже начал писать игре краткое описание. За что ему огромное спасибо!

Когда будет готово, надо будет это должным образом оформить, снабдить скриншотами и перенести в вики проекта.

В принципе уже почти всё готово, но кое-что хочется ещё дописать — пресловутый ларёк, сохранение перед выходом, работу с несколькими сохранениями. Остальное, вроде, всё уже дописано и поправлено.

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

Оставить комментарий

«Гопник-2»: разные mingw

Надо по-быстрому дописать посты про портирования игры на «Виндоуз», пока свежо в памяти. Так что продолжу.

Сильнее всего меня удивило в процессе, что поведение mingw, — инструментария для компиляции приложений под «Виндоуз», различается под разными операционными системами.

Поскольку мне не хотелось заморачиваться с установкой софта на виртуальную машину, я развернул mingw у себя под «Маком» и внёс правки, чтобы всё благополучно компилировалось именно на этой ОС.

Запустив получившееся на первой попавшейся виндовой виртуалке, я успокоился. Но оказалось этого недостаточно — под самой «Виндоуз» приложение не собиралось!

Во-первых, под «Виндой» отсутствовала функция strdup, интернет ничего не подсказал, но я случайно решил эту проблему, установив стандарт языка в GNU C++11: -std=gnu++11.

Во-вторых, почему отсутствовали-то ряд важных констант. Cледуя совету на «Стековерфлоу», я просто определил их нужными значениями.

В-третьих, функцию usleep пришлось заменить на Sleep из windows.h.

После этих правок игра начала собираться под «Виндой» тоже.

Недавно прочитал в одной из статей на Хабре, что «язык Си++ достаточно сложен, чтобы позволить нам писать на нём просто», как же это верно! Неожиданно много времени занимает борьба с какими-то вещами, которые, как мне кажется, должны просто работать.

10 комментариев

«Гопник-2» на Haiku

В 2000-е у меня был друг, который фанател от «BeOS». Послушать его, так это лучшая система на Земле, где всё сразу продумано, нет родовых травм и легаси. Судя по деталям, которыми он сыпал в своих рассказах, во многом так и было, — многие вещи, которые бесили в других операционках, там были сделаны на удивление хорошо.

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

А мне тут что-то до того понравилось водружать «Гопника» на всё новые и новые операционные системы, что я решил пока не останавливаться, и, порывшись в памяти, вспомнил про BeOS, установил себе на виртуалку Haiku и попробовать собрать игру.

Скриншот терминала с текстовой игрой «гопник2: gop2» на рабочем столе Haiku; виден диалог, выбор роли (подтсан, отморозок и др.), уровень сложности и начало боя с беспредельщиком.
«Гопник-2», запущенный под Haiku (наследницей BeOS), собралось без правок, но с приключениями

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

Вот как выглядит рецепт компиляции и запуска:

pkgman install gcc make haiku_devel
git clone https://github.com/bolknote/gopnik2.git
cd gopnik2
make
./gop2

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

Оставить комментарий

«Гопник-2»: UTF-8

Продолжаю писать про портирование «Гопника-2» под «Виндоуз», ибо там ещё есть о чём рассказать.

Я уже очень давно не работаю под этой операционной системой, поэтому некоторые обычные, возможно, для многих вещи для меня являются открытием. Когда я начинал процесс портирования игры под эту платформу, я был уверен, что столкнусь в трудностями совершенно в других частях кода. Одной из неожиданностей была плохая работа «Виндоуз» с кодировкой ЮТФ-8.

Если вывод в консоль удалось победить сравнительно легко, то со вводом возникли проблемы — вызов SetConsoleCP(CP_UTF8), который должен был помочь, не помог. В интернете пишут, что он, по всей видимости, не реализован — просто не делает ничего.

Если с латинскими буквами проблем не возникает, они кодируются одним байтом, это ничем не отличается от того как программы до этого работали десятилетиями, а вот с русскими буквами беда — для них требуется два байта и в таком виде Виндоуз их не понимает.

Рекомендуемый специалистами способ — переключить консоль в режим ввода кодировки ЮТФ-16, а потом перекодировать полученную строку в нужную кодировку. «Виндозу» ЮТФ-16 родная, поэтому проблем вообще никаких не возникает.

#ifdef __MINGW32__
        int wlen = 100;
        int save = _setmode(_fileno(stdin), _O_U16TEXT);
        wchar_t *wstr = (wchar_t *) malloc(wlen * sizeof(wchar_t));
        fgetws(wstr, wlen, stdin);

        int len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, 0, 0, 0, 0);
        user_name = (char *) malloc(len);
        WideCharToMultiByte(CP_UTF8, 0, wstr, -1, user_name, len, 0, 0);
        _setmode(_fileno(stdin), save);

        free(wstr);
#endif

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

Оставить комментарий

«Гопник-2»: буферизация

Как я писал уже сегодня, мне пришлось вчера выключить буферизацию вывода, так как текст визуально «застревал» на экране. Добавление fflush проблему решало, но не будешь же выставлять этот вызов везде, где есть вывод, это несколько сотен мест.

В общем, вчера я сделал попроще, а сегодня пришла в голову более удачная идея обернуть printf в макрос:

// включаем буферизацию вывода
setvbuf(stdout, nullptr, _IOFBF, 1000);
// делаем макрос со сбросом буфера
#define PRINTF(...) { printf (__VA_ARGS__); fflush(stdout); }

Работает просто отлично, вывод текста стал выглядеть комфортно.

6 комментариев

«Гопник-2»: адаптация под Windows

В итоге, вчерашняя мысль адаптировать «Гопника-2» под Виндоуз меня не отпустила. Открыл вечером «ЧатГПТ» и попробовал с его помощью сделать первые шаги.

Несмотря на то, что «Чат» у меня последней, четвёртой версии, всё равно, даже на простых примерах он допускает совершенно детские ошибки, — не подключает нужные заголовочные файлы (мы программировали на Си), упускает важные части.

ChatGPT объясняет, что код на C с Unix-вызовами не переносится на Windows, но предлагает аналог через conio.h: функцию get_key с _setmode и _getch для чтения символа без эха.
Пытаемся программировать на пару с «ЧатГПТ-4»; подсказанный пример не скомпилируется

На скриншоте у меня как раз такой пример — он не скомпилируется из-за отсутствия констант и не содержит условия для обработки комбинации Ctrl+C, как было в том коде, который я попросил «ЧатГПТ» переписать.

Вот как в итоге стал выглядеть этот кусок после нескольких уточняющих вопросов и гуглежа:

#ifdef __MINGW32__
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
    DWORD mode = 0;
    GetConsoleMode(hStdin, &mode);
    if (echo) {
        mode &= ~ENABLE_ECHO_INPUT;
    } else {
        mode |= ENABLE_ECHO_INPUT;
    }

    SetConsoleMode(hStdin, mode);

    int ch = _getch();
    if (ch == 0x03) // Ctrl+C
    {
        printf("Ctrl+C hit, exiting...\n");
        gracefulexit();
    }

    return ch;
#endif

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

#ifdef __MINGW32__
    SetConsoleCP(CP_UTF8);
    SetConsoleOutputCP(CP_UTF8);
    setvbuf(stdout, nullptr, _IONBF, 0);

    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD mode = 0;
    GetConsoleMode(handle, &mode);
    SetConsoleMode(handle, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
#endif

Пришлось полностью выключить буферизацию, чтобы нормально отрабатывал printf с UTF-8. Работает на троечку — вывод текста стал подтормаживать, такое себе.

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

Из заметных багов — игра падает при попытке загрузки сохранения и совсем не работает ввод русских букв. Второе мне нужно только одном месте (где запрашивается ввод имени игрока), так что есть надежда это починить. Остальное как будто работает.

2 комментария

«Гопник-2»: попробовал под Windows

В моём иррациональном увлечении дописыванием «Гопника-2» есть и практическая сторона — получаю много интересного нового опыта. Вчера как раз был такой случай.

Стало интересно посмотреть — соберётся ли игра под Виндоуз. В конце концов она консольная, чего бы ей не заработать?

Скриншот терминала Cygwin: меню игры «Выбери, чё те надо» с опциями начать/загрузить/выйти, сюжет про студента в Питере и диалог с комендантом.
Игра «Гопник-2», собранная и запущенная через cygwin под Windows Server 2019

Раньше я таким не занимался, но из виндового прошлого я помню, что способы есть. Простых нагуглилось два — среда cygwin и набор инструментов mingw.

Через cygwin всё скомпилировалось и запустилось вообще без проблем, но у такого решения есть фатальный недостаток — собирать приходится в виртуальной машине с Виндоузом.

Набор mingw выглядит с этой точки зрения интереснее — есть и под мой «Мак», но там нет совместимости с «посикс», поэтому часть работы с терминалом не собралась, — проблемы с функциями tcsetattr и tcgetattr. Меня теперь так и подмывает отложить в сторону все планы и попробовать затащить игру ещё и Виндоуз, переписав эти два места.

Кстати, надо не забыть попробовать это сделать через ChatGPT. Я уже делал с ним несколько «подходов к снаряду», но каждый раз опыт был не очень. Например, пытался разобраться с тем как работать io_uring, рабочий пример так и не удалось получить. Но сейчас вышла новая версия, можно попробовать ещё раз.

8 комментариев

«Гопник-2»: итог выходных

Человек предполагает, а череда неконтролируемых случайностей располагает. Я думал, что все выходные буду тихонечко пилить список запланированных изменений в игре, а на деле пришлось править совсем другое.

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

Терминал с пиксельным логотипом «ГОТНКИ2», надписями «ОКОРЕНИЕ», «УЛЬТУРНОЙ», «ТОЛИЦЫ», версией 1.17 и списком авторов: V.P., d-maxx, tiandrey, bolknote.
Баг, доставшийся в наследство от попытки портирования предыдущего автора — не выставляет чёрный цвет фона

Например, у одной моей подруги, которой я прислал «Гопника», программа «Терминал» почему-то имеет белый фон и игра на нём выглядела странно, пришлось это поправить.

Кстати, я не знал какой у неё «Макбук» — на процессоре «Интела» или «Эпла», поэтому пришлось научиться делать так называемые «универсальные бинарники».

Это несложно: компилируем программу дважды, сначала — под «интел» (-target x86_64), потом — под «эпл» (-target arm64-apple-macos11), после чего собираем оба бинарника в один:

lipo gop2-x86 gop2-arm -create -output gop2-universal

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

Автор первой попытки портирования игры из ДОСа в Линукс зачем-то убрал из исходников код сохранения и восстановления состояния героя, мне пришлось писать его самостоятельно. А так как я в коде игры ориентируюсь не блестяще, оказалось, что то, что я принимал за инвентарь, структура, отвечающая за что-то другое.

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

fread(&inv_amount, sizeof(inv_amount), 1, load_file);

inv = (inventory *) malloc(sizeof(inventory) * inv_amount);
fread(inv, sizeof(inventory), inv_amount, load_file);

for (int i = 0; i < inv_amount; i++) {
    size_t len;
    fread(&len, sizeof(len), 1, load_file);

    inv[i].name = (char *) malloc(sizeof(char) * len);
    fread(inv[i].name, sizeof(char), len, load_file);
}

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

В общем, из задуманного не сделал ничего, зато поправил некоторые вещи поважнее.

4 комментария

«Гопник»: команда «run»

У меня тут дописывание второй части «Гопника» превратилось их хобби в серьёзный геймдев прям! На трекере завели уж два бага и, пока дочка смотрела на проекторе еженедельный мультик, поправил оба.

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

У меня «run» появляется только на простом уровне и сбежать удаётся не всегда, — шансы начинаются с 50% и постепенно растут до 75 с ростом удачи (в игре есть такой параметр). Сбежать не получится, если сломана нога, а если сбежать во время стрелки, упадёт понтовость, когда она падает до нуля, братва перестаёт за тебя впрягаться в драках.

Скриншот текстовой игры: загрузка из "gop2_1.sav", встреча с беспридельщиком 4 уровня, выбор «наехать» или «бежать», реакция на побег — «тебе удалось ссаться».
Демонстрация новой команды «run» (сбежать)

В ближайших планах небольшие усовершенствования:

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

Есть чем заняться в ближайшие выходные, у меня, вроде, образовалось свободное время.

Оставить комментарий

«Гопник»: нулевые

Пытаюсь вымучить из себя что-нибудь для игры «Гопник-2», порт которой на Линукс и МакОС я доделываю. Я там добавил свою станцию метро и придумал поставить на ней игровой автомат — в нулевые были распространены «столбики», куда кидали пятаки, но дальше фантазия мне отказывает. Что ещё можно добавить, может кому-то придёт какая-то идея?

Пока писал, пришло в голову, что можно ещё добавить ларёк (торговый киоск), но что в нём продавать? Шаверму? Хот-доги? Они в ларьках вообще продавалась в нулевые? Я вообще не помню.

10 комментариев

«Гопник-2»: лицензия

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

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

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

В интернете остался только момент обнародования автором исходного кода игры; не знаю тянет ли это на какое-то волеизъявление.

Сообщение от urajazz от 15 декабря 2008: автор прекращает поддержку проекта, исправил глюки, добавил смену графического режима и выложил исходники; ссылки на игру и код.
Момент передачи автором исходников остальному миру

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

Если «Гитхаб» всё же возмутится, уберу сомнительные исходники, опубликую отдельно патчи и исходный код. Если обвязать это правильным скриптом сборки, с точки зрения возможных пользователей ничего и не изменится.

Оставить комментарий

← 1 2 →