Придумал игру Radio Attack
Скриншот, сделанный вручную
Я программист, но обычно разрабатывал какие-то простые вещи, разработка которых мне уже надоела. Я давно мечтаю о том, как бы научиться электронике, и строить разные схемы. Но я не работаю, и пенсия по инвалидности не такая большая, чтобы я мог себе позволить заниматься электроникой, для этого нужны деньги. Просто так получиться только в программе строить схемы, и нужно продвигать своё обучение в том, что я уже умею.
Так как меня привлекает электроника, то мне бы хотелось спуститься на низкий уровень кодинга, и пока-что учиться писать код для железа. Пока я этим не занялся.
Давным давно я вынашивал план создать 3d игру, где программист то ли на космической станции, то ли на дне океана на станции, ходит с отладчиком и взламывает устройства, и возможно за ним ещё монстр охотиться, и надо в страхе побыстрее что-то сделать и спрятаться в шкаф. :)
Начитавшись некоторых книг, у меня начал немного проясняться сюжет игры. Сначала я хотел сделать игру про 80-е в Америке. Для этого я задумал сделать свою операционную систему, компилятор и разные программы. Уже насоздавал некоторые модели в blender, скачал документацию по i386, распечатал, и начал изучать. В этой документации ещё предлагалось почитать руководство по системному программированию для i386. Я скачал, сходил в салон, мне сделали книгу-брошуру.
Первоначальная цель была делать ОС, эмулятор и компилятор. Я понимал, что просто так сложно будет за это взяться, так как эмоциональный интеллект у взрослого человека требует какое разумное объяснение тому, чем ты должен заниматься. Поэтому создание ОС, эмулятора и компилятора я решил делать в рамках игры. Так общественность бы не сильно давило вопросами, — зачем это нужно. Да и мне эмоции подсказывают, что это правильное решение.
Читая документацию по i386, я вновь вспомнил о таких понятиях как задача, что есть специальный транслятор виртуальной памяти, который для программиста прозрачен (если я правильно помню). И только читая неделю, я понял, что мне не нужно сразу делать такой сложный эмулятор процессора, я просто сломаюсь. Нужно брать что-то попроще и делать. И так пришло решение делать свою архитектуру процессора, немного поглядывая на 8086 и процессор, который использовался в NES, 8-битный.
Я вдохновился! Сделаю более простую архитектуру эмулятора, я смогу сделать более быстрый эмулятор, так как будет требоваться меньше работы. Читая про операционные системы, я узнал, что раньше вместо ОС были так называемые мониторы. Я подумал, что может быть даже сделаю тоже монитор, а не ОС, посмотрим.
Также купив книгу по операционным системам, я также купил книгу crafting interpreters, но английский в ней для меня чуть более сложноват оказался, я понимаю только некоторые формулировки, которых вроде бы достаточно. В данный момент я не читаю ни по ОС, ни по компиляторам.
Когда я только прочитал первую и вторую главу по компиляторам, я подумал, что попробую сначала сам сделать компилятор ассемблера. Если не получиться, то буду читать.
Первая версия получилась неудобной и невозможной для поддерживания, я удалил код. Подумав над ошибками, я сделал более лучший вариант компилятора, который до сих пор делаю. Он умеет работать с метками, понимает команды, требует указывать размер для [BX + SI]. У меня свой байткод. Я решил не делать как в i386 некоторые двухбайтные операнды, каждый операнд один байт имеет плюс его разновидность. На всякий случай оставил один байт для расширения как это делается в i386, в i386 байт 0×66 служит тому, что вместо AX будет EAX. Так называемый префикс байт (если я правильно выражаюсь).
Сначала я делал компилятор вместе с эмулятором, но в последнии дни я занимаюсь только компилятором. У меня был ужасный код, я его привёл чуточку в порядок. Я понимаю, что хакеры компиляторов на многие годы усовершенствовали свой код так, что его трудно понять. Мой же код пока простой и я не могу придумать что-то более сложное и крутое. Например для описания опкодов команд я сделал так.
#define BEGIN_STRUCT_OPCODE_DEFINE() \
14 static struct asm_code asm_code[] = {
15
16 #define END_STRUCT_OPCODE_DEFINE() \
17 };
18
19 #define ADD_OPCODE(lbl, level, req) \
20 {#lbl, level, lbl, req},
21
22 struct asm_code {
23 char *label;
24 uint8_t level_rm;
25 uint8_t opcode;
26 uint8_t req_ops;
27 };
28
29 BEGIN_STRUCT_OPCODE_DEFINE ()
30 ADD_OPCODE (INT, IMM8, 1)
31 ADD_OPCODE (ADD, RM_IMM_2, 2)
32 ADD_OPCODE (SUB, RM_IMM_2, 2)
33 ADD_OPCODE (XCHG, RM_RM_2, 2)
34 ADD_OPCODE (MOV, RM_IMM_2, 2)
35 ADD_OPCODE (MUL, RM_1, 1)
36 ADD_OPCODE (DIV, RM_1, 1)
37 ADD_OPCODE (INC, RM_1, 1)
38 ADD_OPCODE (DEC, RM_1, 1)
39 ADD_OPCODE (AND, RM_IMM_2, 2)
40 ADD_OPCODE (OR, RM_IMM_2, 2)
41 ADD_OPCODE (CLI, VOID, 0)
42 ADD_OPCODE (STI, VOID, 0)
43 ADD_OPCODE (CMP, RM_IMM_2, 2)
44 ADD_OPCODE (XOR, RM_IMM_2, 2)
45 ADD_OPCODE (CLC, VOID, 0)
46 ADD_OPCODE (STC, VOID, 0)
47 ADD_OPCODE (CLD, VOID, 0)
48 ADD_OPCODE (STD, VOID, 0)
49 ADD_OPCODE (SAL, RM_R_IMM_2, 2)
50 ADD_OPCODE (SAR, RM_R_IMM_2, 2)
51 ADD_OPCODE (SHL, RM_R_IMM_2, 2)
52 ADD_OPCODE (SHR, RM_R_IMM_2, 2)
53 ADD_OPCODE (IN, AX_R_IMM_2, 2)
54 ADD_OPCODE (OUT, IMM_R_AX_2, 2)
55 ADD_OPCODE (PUSHA, VOID, 0)
56 ADD_OPCODE (PUSHF, VOID, 0)
57 ADD_OPCODE (POPA, VOID, 0)
58 ADD_OPCODE (POPF, VOID, 0)
59 ADD_OPCODE (PUSH, RM_R_IMM_1, 1)
60 ADD_OPCODE (POP, RM_1, 1)
61 ADD_OPCODE (NEG, RM_1, 1)
62 END_STRUCT_OPCODE_DEFINE ()
63
64 static uint32_t size_asm_code = sizeof (asm_code) / sizeof (asm_code[0]);
Да, я пробовал читать чужой код компиляторов, но совсем чуть-чуть, просто я не понимал вообще ничего тогда, и решил, что буду развиваться самостоятельно.
Продумывая эту игру про космос я придумал мини игру по военной симуляции. Эта идея ошеломила меня. Я подумал, а неплохо бы её выделить в отдельную игру, как раз протестирую компилятор с эмулятором.
Идея игры заключается в том, что нам нужно разработать код прошивки для каждого юнита и здания. Писать нужно на ассемблере 16-битном. Я подготовил картинки как будут выглядеть юниты.
Коллектор:
Коллектор
Коллектор собирает жидкость из под земли, которая требуется для производства юнитов и сборки зданий.
Сканер:
Сканер
Сканер может перехватывать данные в радиусе нескольких клеток и сообщать оператору. Оператор, это мы. Мы следим за ходом действий и можем вмешиваться. Например, если сканер перехватил команды от командного центра к танку, то мы будет знать куда он отправиться. Конечно если поймешь язык общения, ведь его можно зашифровать. :)
Танк:
Танк
Боевая единица, пока сказать особо нечего.
Инжектор:
Инжектор
Может внедрять свой код врагам, дезинформация, внедрение своих прошивок, это всё его работа.
Дрон:
Дрон
Дрон может обнаружить вражеские юниты, если они не замаскировались. Юнит может замаскироваться полностью, то-есть если на клетке 120 единиц, то маскируются все, но можно замаскировать например 100 единиц и оставить 20 на виду. Это я прочитал в книге «Искусство войны», когда ты специально делаешь вид, что отряд слабый и тем самым привлекаешь врага в ловушку.
Доставщик:
Доставщик
Доставщик доставляет боеприпасы, так как у киборгов и танков они кончаемы.
Киборг:
Киборг
Боевая единица
Ещё я подумываю сделать флот, но пока это только в планах.
Сделан кстати командный центр:
Командный центр
Может выглядит не очень круто, но это же роботостроение, здесь дизайн придумывал не человек. :)
Также хочется сделать игру по локальной сети. Здесь код компилируется в байткод, и поэтому можно делиться с друзьями или дать эту прошивку ИИ боту, чтобы он играл против вас.
Делаю игру на своём простеньком движке с opengl. У меня ещё такое желание есть. В windows при падении приложения можно получить coredump файл. Это настраивается через реестр. Думаю сделать возможность, чтобы игроки могли скинуть мне coredump по почте или в мессенджере, чтобы я мог изучить где ошибка. Очень бы этого хотелось, но специально баг не буду делать. :)
Ссылку к игре я оставлю здесь, если кого заинтересовала игра, то буду рад, если вы добавите в список желаемого. Я вчера вообще хотел бросить разработку, но потом понял, что надо продолжать делать сложные вещи и будь что будет.
https://vkplay.ru/play/game/radio_attack/