Как написать собственный игровой движок

Для начала, всё ниже описанное лишь мой опыт, в целом это просто хобби. Я слишком странно могу описывать некоторые вещи, ибо пишу нечто подобное первый раз. Надеюсь всем всё будет понятно (=_=)

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

АТЕНШОН, МНОГА ТЕКСТА НЕТ ПИКЧ

Предостережение

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

Поясню — что бы написать минимально рабочую игру, тебе нужно: обработка ввода, вывод графики и игровой цикл с логикой. Можно сказать — «всего 3 компоненты и ты уже можешь делать свои крестики-нолики или тетрисы!». Но для звания «великого игрового движка», при мысли о котором ты возбуждаешься, явно не хватает всего 3х компонент. Различные механизмы подгрузки данных, гибкие системы рендера, система скриптов, встроенные редакторы уровней — всё это требует времени на реализацию, и чем больше ты хочешь, тем больше времени у тебя уйдёт на разработку «движка с 0», а сколько времени потратится на написание самой игры?

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

А как писать?

Для начала нужно подвести черту между двумя кардинально разными подходами в написании этих ваших «движков». Я обозвал их так…

  • «Динамические движи», это те в которых вся игровая логика содержится внутри объектов, которые можно передать в другие бинарные модули. (Прим — .dll библиотеки)
  • «Статические движки», это те в которых вся логика содержится внутри самого движка и определяется на этапе компиляции.

Какие нюансы я обнаружил при такой классификации?
«Статические движки»

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

«Динамические движки»

  • Требуют глубокого понимания матчасти, из-за виртуализации объектов.
  • Код можно разбить на независимые модули и подключать буквально на лету. В некоторых играх есть моды которые реализуют «движок в движке», которые используют другие подключаемые модули.
  • Большинство инструментов для отладки придётся писать самому, если это не встроено в сам язык. То есть, если ты не пишешь на .NET/JAVA/Lua?
  • «Скрипты» могут быть реализованы в виде скомпилированных бинарников обёрнутого в объекты, от чего «потанцевал» при добавлении контента может быть больше (в плане производительности).

Большинство «индюшачьих» игровых движков описаны как «статические». Их гораздо проще писать и ещё проще поддерживать. Использование «динамического» подхода, даст тебе ненужную модульность. Возможно написание своего крутого интерфейса для аллокатора памяти хорошая затея, но ты бы мог потратить это время делая игру, а не натирать цепь разобранного велосипеда.
*** Рекомендация — пиши «статику»
*** Самый наивный способ сделать «динамику» — писать классы с виртуальными методами или их аналогами.

Кроссплатформенность

Это боль. (вся глава моё нытьё…)
Первая мысль которая должна посетить твою голову — как распространить игру на максимально широкую аудиторию.
Ты можешь использовать кроссплатформенные библиотеки, но их функционал крайне ограничен, так как они пытаются создать абстракцию которая «будет жить на любой платформе». Ты конечно можете написать свою библиотеку… Но вот в чомъ мем
Проблема в том, что платформы достаточно сильно отличаются даже в самых базовых вещах. Как пример — Windows при старте программы не имеет потоков ввода-вывода и для этого ей нужно создавать консоль, но консоль можно создать 2 различными способами и у каждого способа есть куча параметров, для лююююбых потребностей. В Linux же всё проще, у тебя со старта приложения есть потоки ввода-вывода и что бы «увидеть их» нужно просто перенаправить их в файл или создать окно-терминал. КАК ты даже ТАКУЮ простую проблему будешь решать, я не представляю. (я это уже сделал)
Чего уже говорить о создании графического контекста…

Вот ты пытался в OpenGL на Windows? Знаешь что на официальном сайте написано использовать GetDC() при связывании контекста окна и OpenGL? А ты знал что это DC на самом деле может быть принтером? Может быть целым монитором? Видеокартой? Просто окном? «Ресурсом менеджера окон»? А то что в Linux ты должен ручками выбрать нужный тебе монитор для запуска? Всякие драйверы-сервера запускать? И не один. И это надо как-то собрать в одну единую абстракцию и непринуждённо дёргать по воле случая…

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

И всё же… Написать(наговнокодить) хотя бы простенькое приложение на API платформы, как по мне, важно. Так, ты будешь лучше понимать, что в конкретной системе значат абстракции которые дают фреймворкиязыки.

Делаем игры, наивно

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

Любой код можно разбить на некое число компонент-модулей. Самое примитивное приложение состоит всего из 3 модулей

  • Обработка ввода
  • Вывод изображения
  • Логика (зачастую на стейт машинах)

Уже это позволяет писать тебе довольно простые игры. Скажем крестики нолики или «давилку мух»? Давай вместе представим как оно может работать.

  • Загружаем нужные ресурсы
  • — В цикле…
  • Рисуем: фон > картиночки
  • Обрабатываем ввод
    — Если нажата мышка, проверяем хитбоксы объектов
    — Если прошли проверку, меняем «игровое состояние»
  • (для «давилки мух») Раз в Х циклов запускаем новую муху по некоторой траектории. И обрабатываем перемещение живых мух.

И это уже можно назвать игрой. «Погоди» — скажешь ты — «Но фактически тут 4 модуля, загрузка ресурсов!!». Хах, но если ты чуть-чуть разбираешься в линковке приложения, то ты можешь вшить данные в бинарник) И тебе не нужно будет загружать никаких данных. Поведение мух, также, вшито в движок и относится к логике, потому фактически тут именно 3 модуля.

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

Я бы сказал так — «движок занимается обработкой пользовательских данных и может иметь изменяемую логику»

Из такого определения давай же опишем некий «сферический движок для платформера».
Для начала, тебе потребуется описать больше чем один модуль, а логика самого движка будет гораздо сложнее.

  • Конкретная загрузка ресурсов
  • Обработка ввода, который конвертируется в абстракции
  • Вывод изображения, который обходит множество объектов
  • Игровая логика, которая уже разбита на несколько частей
    — Обработка загрузки-переходов уровней
    — Информация о сцене
    — Нахождение коллизий и проверки на триггеры
    — Обработка поведения ИИ?
    — Обработка ввода от игрока
    — Скриптовый процессор

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

  • Информация о сцене (уровне)
    — Какой фон
    — Набор тайлсетов (2D матрица)
    — Предметы
    — Юниты
    *** Всё кроме фона должно иметь информацию о себе, типа — «текстура», «какие-то свойства», есть ли «триггер», «скрит» или «поведение»
  • Вшитые в движок «примитивы»
    — Триггеры (какие бывают, что проверяют, что вызывают. прим — если хибоксы пересекаются — запускает смену уровня)
    — Поведение (хардкодное поведение, что делает объект. прим — триггернутый предмет увеличивает свойство Х, у объекта который триггернул. Объект Х движется в одну сторону и случайное время меняет направление. Это можно оформить в виде «функций» для скриптового языка. )
    — Свойства (Что за свойства, определяемые скриптами свойства)
    — Процессор скриптов
  • Обработка передвижений-триггеров-физики?

Ну и сам игровой цикл будет состоять примерно из такой логики

  • Загружаем информацию об уровне (описание уровня)
  • Загружаем нужные ресурсы (текстуры и скрипты)
  • — В цикле…
  • Рисуем: фон > тайлест > предметы > юниты
  • Обрабатываем ввод
    — Абстрагируемся от кнопок и просто передаём «Идти влево»
  • Обрабатываем логику
    — Проходимся по всем единицам со скриптами
    — Проходимся по тем, у кого базовое поведение
    — Что-то делаем с игроком?
    — Проверяем коллизии-физику? (вызываем триггеры если что-то нашли)
    — Двигаем юнитов-предметы

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

И… Вот примерно в таком виде это уже можно назвать своим полноценным движком! Ахаха… Можно постоянно добавлять функционал, добавить графические эффекты, анимации или сделать меню с кнопками. В какой-то момент ты поймёшь, что хардкодить объекты не самая лучшая затея и перепишешь свой код, который будет использовать какие-то обобщённые абстракции. В целом, писать не так уж и много, не так ли?

Поясню за скрипты — для многих это будет открытием, но скрипты можно делать и в виде виртуальной машины-процессора. Твоя задача будет — написать парсер текста, описать виртуальную машину и придумать как именно получать информацию о сцене-объектах. В качестве примера, можно использовать многострадальные стековые процессоры, по типу forth. Они очень легко делаются, но к их логике нужно привыкать. По сути это единственный выход написать «быстро» ваш собственный «скриптовый процессор».
*** Обязательно сделай вывод логов при сборке скрипта, или при его работе.
*** Старайся избегать логики типа [INT a += «Lord»]. Писать нетипизрованный код опасно, но можно выделить отдельные команды для работы с конкретными типами.
*** ДА, ТЫ БУДЕШЬ ПИСАТЬ СКРИПТЫ НА АССЕМБЛЕРЕ.
*** Для написания простого ассемблера, хватит и знаний типа — Sting.indexof(«ADD»); и подобного говнокода. Но что бы написать нормально, или хотя бы простенький язык, вам нужны знания о «регулярных выражениях» или «парсерных комбинаторах».
*** Не надо упарываться в «полноценный язык», посмотрите как писались языки программирования в бородатых 80х, даже тот же Pascal. Они работают просто и честно, такие реализации займут у вас в разы меньше времени, чем описание «очередного» ???CRustHaskell???

Типа канец?

В целом написать некий «движок в вакууме» не такая сложная задача, как кажется. На ранних этапах большинство поведений-абстракций можно вшивать в движок. Да и в целом, большинство вещей работают довольно просто, и требуют от вас лишь знаний и понимания. Но я напомню, написать свой движок для игры — плохо. Это отнимает огромное количество времени, которое вы можете потенциально потратить на разработку самой игры. А любая гордость проходит, после осознания того, что ты делал свою игру примерно 20% времени пока писал код.

Изначально, решился написать эту статью, ради привлечения инвестиций, на время разработки своей «базовой +18 новеллы». (инициатива друга)
Так что ты это, кнопочку то нажми, а?

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

  • Как лучше работать с памятью-данными.
  • Проблемы STL библиотек. (C++)
  • Детали виртуализации объектов, микро рекомендации.
  • Как можно делать «моды».
  • Профилирование и Логирование, почему это важно.
  • Что нужно знать о многопотоке, вводные-подводные.
  • Асинхронно или параллельно? Как это работает?
  • Работа с текстом-кодировками, и почему это настоящий ад.

На счёт моего кода — не будет опенсорса. Когда я релизнусь, я выложу лишь API к бинарнику. По сути, я использую «динамический» подход, который описывал выше. Потому запустить свою игру, можно будет просто собрав .dll и запустить бинарник запихнув либу в аргументы строки. Но вот когда это случится… Когда я перестану морить себя голодом? Кто знает

PS — Под конец получилось немного сумбурно, ибо я писал всё за один заход. В целом я описал лишь поверхностно многие вещи. Если будет спрос, могу углубится.
PPS — Мне тут говорят что бы я сделал бусти и публиковался впредь там, раз в месяцок публикуя «фри контент». Может в следующий раз? Я просто не знаю о чём там можно писать, лол.
PPPS — «Статья слишкам длинная устал читать, пиши кароче»

Так что… Ещё свидимся?


Download Article


Download Article

  • Programming Basics
  • |

  • Planning
  • |

  • Development
  • |

  • Completion

You can create a game engine to simplify the programming process for all of the games you make. If you’re a developer looking to create your own game engine from scratch, check out this tutorial for coding your own a simple game engine!

  1. Image titled Make a Game Engine Step 1

    1

    Choose your Language. There are a variety of languages from which programs are made. The language you choose doesn’t matter too much, but the most important thing is that you start somewhere.

    • There are many programming languages to choose from, but most go with C++ or Java and they are also the most useful in Game Development.
    • Once you learn one language, it’s much easier to learn another.
  2. Image titled Make a Game Engine Step 2

    2

    Find a course. The most effective way (in my opinion) to learn programming/computer science is to take a class! Whether this is a class at your school, or outside of school shouldn’t matter.

    • No matter who you are, you can find a programming class that suits you.
    • MIT OpenCourseWare (http://ocw.mit.edu/) has a variety of free classes.
    • If you look around on Google, you’ll find a number of other sites that also have free lectures and classes available.
    • You could also have a friend teach you a language, sharing is caring.

    Advertisement

  3. Image titled Make a Game Engine Step 3

    3

    Practice. You don’t want your first game to be you big, important game. You want a chance to screw up and not care too much about your project.

    • Try to make a simple game.
    • If you learned Java, check out the Swing package.
    • Don’t worry too much about this project(s), they should only take up a few weeks of your time.
    • Learn from your mistakes.
  4. Advertisement

  1. Image titled Make a Game Engine Step 4

    1

    Think of a Game Idea. Try to challenge yourself. That way if you don’t achieve all you set out to, you’ll still (probably) have a pretty good game left over.

    • Think for a while, don’t feel pressured to do this in one sitting.
    • Sit on your idea for a while so you know it is good.
  2. Image titled Make a Game Engine Step 5

    2

    Formalize your Idea. Technical communications is important in any kind of engineering, including software engineering. You don’t want to tell someone that you’re making an apple and they go and make you audio for a pear.

    • Write up a «Game Design Document». These are used in professional game development, but more importantly, they easily communicate your idea(s) to others. There are many free templates available online.
  3. Image titled Make a Game Engine Step 6

    3

    Recruit Help. You don’t have to go at this alone. It’s also more fun and exciting in a group.

    • You can’t make a custom game engine and manage the project without help.
    • Ask your Friends first before going to strangers or advertising for help, you’d be surprised who would love to get into the game industry.
  4. Advertisement

  1. Image titled Make a Game Engine Step 7

    1

    Research. Look into what you’re going to do before you do it. Even when you make an engine from scratch, there are still a number of tools that you could make your engine out of.

    • Look into «OpenGL» if you learned C and «JOGL» if you learned Java.
    • Maybe buy a textbook on OpenGL, «Redbook» is the most famous one, but it is online for free.
  2. Image titled Make a Game Engine Step 8

    2

    Draw Something. Render a primitive or 2D object to get started.

    • Make a 2D triangle, or a cube.
    • Look into «Display Lists» so you can draw many primitive objects.
  3. Image titled Make a Game Engine Step 9

    3

    Make Perspective. There aren’t many games where you can’t change where you’re looking.

    • Make the perspective of your game (First person perspective, top-down, etc.)
  4. Image titled Make a Game Engine Step 10

    4

    Move Around. One step at a time! Except not actually because stepping is actually kind of complicated.

    • Either move everything around the camera or move the camera view port, but they are the same to the processor.
    • Be able to move in all angles, not just along the axis.
  5. Image titled Make a Game Engine Step 11

    5

    Add Textures (Images). That default color will get old after a while, and not many games are used with only solid colors.

    • Splice them into your display list(s).
  6. Image titled Make a Game Engine Step 12

    6

    Add Audio. This makes your game much more interesting and realistic.

    • Perhaps footsteps for when you walk.
  7. Image titled Make a Game Engine Step 13

    7

    Add Lighting. This also adds to the realism.

    • Learn the different kinds of lighting.
    • Use a sphere instead of a cube to make sure the lighting is working.
    • You could put a primitive object where the light should be coming from to debug. Just make sure the light can get out of the box/sphere you put it into.
  8. Image titled Make a Game Engine Step 14

    8

    Add Collision Detection. The biggest thing people notice when you show them an incomplete game engine is the lack of proper collision detection.

    • Make it impossible to walk through the cube.
    • Make it possible to move (in other directions) when you are colliding with the cube.
  9. Image titled Make a Game Engine Step 15

    9

    Add Gravity. Most games have falling things somewhere.

    • Make a floor, and jump around on it.
  10. Advertisement

  1. Image titled Make a Game Engine Step 16

    1

    Finish Your Game. Don’t forget to market it. You may want to enlist a marketer (friend) to help you. Assume your game is going to be a hit so that way you can work towards that.

    • Have Fun!
  2. Image titled Make a Game Engine Step 17

    2

    Manage Other Games. Don’t be coy, tell other developers that you made a game engine. You don’t have to be the only one to develop with your engine. When you let other people use it, you have the right to some of their royalties, but also you get constructive feedback and perhaps improvements to your engine.

    • Game Engines are valuable and impressive.
    • Did you notice how much those other engines are charging indie developers? (You could be that engine!)
    • Use your engine to get wannabe game developers into the industry!
  3. Image titled Make a Game Engine Step 18

    3

    Good Luck! Start your journey into the booming game industry!

    • Now you can laugh at your friends who said «Unity was easier».
  4. Advertisement

Ask a Question

200 characters left

Include your email address to get a message when this question is answered.

Submit

Advertisement

Thanks for submitting a tip for review!

About This Article

Thanks to all authors for creating a page that has been read 83,778 times.

Did this article help you?


Download Article


Download Article

  • Programming Basics
  • |

  • Planning
  • |

  • Development
  • |

  • Completion

You can create a game engine to simplify the programming process for all of the games you make. If you’re a developer looking to create your own game engine from scratch, check out this tutorial for coding your own a simple game engine!

  1. Image titled Make a Game Engine Step 1

    1

    Choose your Language. There are a variety of languages from which programs are made. The language you choose doesn’t matter too much, but the most important thing is that you start somewhere.

    • There are many programming languages to choose from, but most go with C++ or Java and they are also the most useful in Game Development.
    • Once you learn one language, it’s much easier to learn another.
  2. Image titled Make a Game Engine Step 2

    2

    Find a course. The most effective way (in my opinion) to learn programming/computer science is to take a class! Whether this is a class at your school, or outside of school shouldn’t matter.

    • No matter who you are, you can find a programming class that suits you.
    • MIT OpenCourseWare (http://ocw.mit.edu/) has a variety of free classes.
    • If you look around on Google, you’ll find a number of other sites that also have free lectures and classes available.
    • You could also have a friend teach you a language, sharing is caring.

    Advertisement

  3. Image titled Make a Game Engine Step 3

    3

    Practice. You don’t want your first game to be you big, important game. You want a chance to screw up and not care too much about your project.

    • Try to make a simple game.
    • If you learned Java, check out the Swing package.
    • Don’t worry too much about this project(s), they should only take up a few weeks of your time.
    • Learn from your mistakes.
  4. Advertisement

  1. Image titled Make a Game Engine Step 4

    1

    Think of a Game Idea. Try to challenge yourself. That way if you don’t achieve all you set out to, you’ll still (probably) have a pretty good game left over.

    • Think for a while, don’t feel pressured to do this in one sitting.
    • Sit on your idea for a while so you know it is good.
  2. Image titled Make a Game Engine Step 5

    2

    Formalize your Idea. Technical communications is important in any kind of engineering, including software engineering. You don’t want to tell someone that you’re making an apple and they go and make you audio for a pear.

    • Write up a «Game Design Document». These are used in professional game development, but more importantly, they easily communicate your idea(s) to others. There are many free templates available online.
  3. Image titled Make a Game Engine Step 6

    3

    Recruit Help. You don’t have to go at this alone. It’s also more fun and exciting in a group.

    • You can’t make a custom game engine and manage the project without help.
    • Ask your Friends first before going to strangers or advertising for help, you’d be surprised who would love to get into the game industry.
  4. Advertisement

  1. Image titled Make a Game Engine Step 7

    1

    Research. Look into what you’re going to do before you do it. Even when you make an engine from scratch, there are still a number of tools that you could make your engine out of.

    • Look into «OpenGL» if you learned C and «JOGL» if you learned Java.
    • Maybe buy a textbook on OpenGL, «Redbook» is the most famous one, but it is online for free.
  2. Image titled Make a Game Engine Step 8

    2

    Draw Something. Render a primitive or 2D object to get started.

    • Make a 2D triangle, or a cube.
    • Look into «Display Lists» so you can draw many primitive objects.
  3. Image titled Make a Game Engine Step 9

    3

    Make Perspective. There aren’t many games where you can’t change where you’re looking.

    • Make the perspective of your game (First person perspective, top-down, etc.)
  4. Image titled Make a Game Engine Step 10

    4

    Move Around. One step at a time! Except not actually because stepping is actually kind of complicated.

    • Either move everything around the camera or move the camera view port, but they are the same to the processor.
    • Be able to move in all angles, not just along the axis.
  5. Image titled Make a Game Engine Step 11

    5

    Add Textures (Images). That default color will get old after a while, and not many games are used with only solid colors.

    • Splice them into your display list(s).
  6. Image titled Make a Game Engine Step 12

    6

    Add Audio. This makes your game much more interesting and realistic.

    • Perhaps footsteps for when you walk.
  7. Image titled Make a Game Engine Step 13

    7

    Add Lighting. This also adds to the realism.

    • Learn the different kinds of lighting.
    • Use a sphere instead of a cube to make sure the lighting is working.
    • You could put a primitive object where the light should be coming from to debug. Just make sure the light can get out of the box/sphere you put it into.
  8. Image titled Make a Game Engine Step 14

    8

    Add Collision Detection. The biggest thing people notice when you show them an incomplete game engine is the lack of proper collision detection.

    • Make it impossible to walk through the cube.
    • Make it possible to move (in other directions) when you are colliding with the cube.
  9. Image titled Make a Game Engine Step 15

    9

    Add Gravity. Most games have falling things somewhere.

    • Make a floor, and jump around on it.
  10. Advertisement

  1. Image titled Make a Game Engine Step 16

    1

    Finish Your Game. Don’t forget to market it. You may want to enlist a marketer (friend) to help you. Assume your game is going to be a hit so that way you can work towards that.

    • Have Fun!
  2. Image titled Make a Game Engine Step 17

    2

    Manage Other Games. Don’t be coy, tell other developers that you made a game engine. You don’t have to be the only one to develop with your engine. When you let other people use it, you have the right to some of their royalties, but also you get constructive feedback and perhaps improvements to your engine.

    • Game Engines are valuable and impressive.
    • Did you notice how much those other engines are charging indie developers? (You could be that engine!)
    • Use your engine to get wannabe game developers into the industry!
  3. Image titled Make a Game Engine Step 18

    3

    Good Luck! Start your journey into the booming game industry!

    • Now you can laugh at your friends who said «Unity was easier».
  4. Advertisement

Ask a Question

200 characters left

Include your email address to get a message when this question is answered.

Submit

Advertisement

Thanks for submitting a tip for review!

About This Article

Thanks to all authors for creating a page that has been read 83,778 times.

Did this article help you?

Игра с нуля — интересный челлендж для разработчика. Но если хотите пройти его на сложности Nightmare, можно еще и сделать собственный игровой движок, заточенный специально под проект. Подводных камней много, рассказываем, что важно знать при разработке такого гейм-дизайнерского софта, и что в него добавить.

Итак, вы задумались о создании собственного игрового движка. Отлично! У этого варианта множество плюсов в сравнении с использованием коммерческого — такого как Unity или Unreal. В этой статье разберемся, зачем разрабатывать свой движок, какие системы необходимо предусмотреть и как правильно подойти к процессу. 

Зачем?

Начнем с главного вопроса, который стоит задать себе, если вы решили разработать собственный движок: зачем это вам?

Резонными причинами могут быть, например, такие:

  • Хотите создать игру с использованием новой технологии, которую не поддерживают другие движки. Или поддерживают, но реализация слишком сложна и костыльна. Это может быть масштабная симуляция (Factorio), нестандартный проект, который не вписывается в готовые шаблоны (Noita, Miegakure), и множество других идей. В таких случаях нет иного выхода кроме как писать собственный движок под проект.

  • Хотите оптимизировать рабочий процесс под игры, которые создаете. Если для проекта не нужен полный объем возможностей коммерческого движка, есть смысл создать кастомизированный вариант с подходящими для конкретной игры редакторами и функциями. Если движок не затачивается под конкретный проект, стоит задуматься, так ли нужно самописное решение или все-таки достаточно готовых вариантов?

  • Не хотите в долгосрочной перспективе зависеть от чужих технологий. Если вы хотите иметь полный контроль над проектом, готовы самостоятельно исправлять ошибки (а не сидеть в ожидании багфикса от создателей) и не бояться, что очередное обновление сломает игру, то собственный движок — подходящий вариант! И не придется зависеть от прихотей крупных корпораций

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

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

  • Вам кажется, что вы придумаете движок покруче, чем Unity или Unreal (или Godot, или GameMaker). Не выйдет. Разработать подходящий для специфических нужд софт можно  (см. предыдущий список), но в одиночку или маленькой командой невозможно создать универсальный движок, который будет конкурировать с известным универсальным ПО. Особенно при первой попытке.

  • Думаете, что иначе вы «ненастоящий программист»? Использование готового движка не делает гейм-разработчика хуже. Для того они и придуманы! Это просто инструмент для создания игр. 99% проектов можно разработать при помощи уже существующего софта — в этом нет ничего постыдного. Ведь главное — это сама игра!

  • Если вы хотите таким образом сэкономить время или деньги — забудьте! Создавать движок с нуля долго, а время = деньги. Использовать готовый софт выгоднее, чем пытаться разработать собственный. В долгосрочной перспективе это может стать выигрышной стратегией, но только если движок будет основой для нескольких прибыльных проектов, и при этом значительно удобнее в работе, чем коммерческие. Такое ПО разработать сложно, особенно если это первый опыт (и почти невозможно, если речь о 3D).

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

Я начинал с флэш-игр в 90-00х, и ни один движок того времени не поддерживал импорт флэш-анимаций. Единственным выходом было создать собственный софт. Намного приятнее и быстрее закидывать swf-файлы в папку с ресурсами и сразу использовать анимации в игре без промежуточных шагов типа экспорта в списки спрайтов.

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

Что?

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

Разные движки выполняют за вас разное количество работы. Некоторые просто отображают графику на экране (Flash, Pico-8). Другие сами по себе — целая игра с возможностью кастомизации или узко заточены под определенный жанр (RPGMaker, Ren’Py). А между ними — бесчисленное количество вариантов.

Игровые движки обычно основываются на простых фреймворках типа SDL и OpenGL, и включают в себя специализированные библиотеки для аудио, видео, физических и математических вычислений и чего угодно еще. При создании движка нет необходимости каждую мелочь прописывать вручную, практически на каждую потенциально полезную опцию доступна соответствующая библиотека.

Базовые функции движка. 

Это основы, необходимые для того, чтобы начать создавать игры.

Инициализация системы.

Приводит программу в боевую готовность после запуска — открывает окно, загружает данные. С этим (и не только!) справится стандартная библиотека SDL, проще ее и использовать. 

Контроль частоты кадров

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

Ввод

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

Рендеринг

Большинство (ну как минимум 75%) игр так или иначе используют графику, и за нее отвечает как раз движок. В 2D-игре минимальному рендеру достаточно отображать на экране текстурированные четырехугольники. Шейдеры, буферы вершин, однобуферная прорисовка, меши, материалы и так далее — это прекрасные опции, которые можно добавить позднее, если понадобится. Если хочется заморочиться с OpenGL или Vulkan и кастомизировать рендерер — на здоровье! Но помните, нет ничего постыдного в том, чтобы использовать для рендеринга готовые библиотеки типа Ogre3D. Выбор зависит от целей и потребностей разработчика, а также от того, какие задачи интереснее решать самостоятельно.

Математические и прочие утилиты

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

Дополнительные функции

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

Управление игровыми объектами и сценами

Можно кодить и вручную, но практичнее предусмотреть систему для обработки отдельных игровых объектов и коллекций. Это один из ключевых механизмов в движке, ведь он управляет логикой игры. Из каких компонентов состоят объекты, на какие типы событий реагируют, как происходит взаимодействие, что со структурой памяти, используется ECS? (Кстати, «чистый» неадаптированный ECS лучше применять только для специфических кейсов.) Эти и не только  вопросы должна покрывать система управления объектами и сценами. Для таких задач доступны готовые библиотеки (особенно для чистого ECS), но, поскольку эта структура сильнее остальных влияет на игровой код, я склоняюсь к принципу «сделай сам». Использование существующего решения вынудит постоянно думать о том, как вписать логику игры в рамки. А надо наоборот — адаптировать движок под выражение задуманной игровой логики.

Аудио

Звуковые эффекты и музыка здесь разделены, хотя и прячутся под одним названием. Основные необходимые функции — это запуск и остановка звуковых циклов и воспроизведение звуковых эффектов от начала до конца. Этим аудио не ограничивается, но даже с двумя базовыми опциями можно далеко продвинуться. Минус в том, что стандартные звуковые фреймворки (FMod and Wwise) — коммерческие и с кучей лицензионных ограничений. Однако большинство ресурсов с открытым кодом раздражают неудобством (передаю привет OpenAL). Сам я использую FAudio — на мой вкус, простая и комфортная в использовании база для построения сложных звуковых механик. 

Загрузка и управление файлами

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

Нетворкинг

Окей, нетворкинг (онлайн-мультиплеер) — это ОЧЕНЬ опционально. Если не планируется режим p2p, то и не заморачивайтесь. Однако эту систему чрезвычайно сложно встроить в движок, который разработан не с расчетом на многопользовательские игры. Поэтому, если вы планируете или допускаете добавление мультиплеера, подготовьте почву заранее, потому что иначе придется переделывать все системы. 

Это базовый набор систем, которые входят в игровой движок. Другие варианты типа обнаружения столкновений, физики, сериализации, анимации и UI уже опциональны. Они распространены, поэтому входят в большинство движков, но для создания игр не обязательны. Например, предотвращение столкновений можно обеспечить при помощи математических утилит и прописать алгоритм в коде игры. Простейшую гравитацию и ускорение можно настроить без физических движков типа Box2D or Bullet. А полная сериализация вообще лишняя, если нужно попросту сохранить чекпойнт. 

В самописном движке однозначно будет меньше систем и функций, чем в универсальном коммерческом. Такова цель! Unity и Unreal — огромные монолиты, и каждая отдельная игра использует лишь малую часть предложенных опций. Добавляйте только то, что нужно для вашего конкретного кейса и сосредоточьтесь на том, чтобы сделать инструменты разработки лучше и комфортнее в использовании. 

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

Как?

Итак, вы взвесили за и против, поняли, чего хотите, и решили все-таки взяться за создание движка. И как же это сделать?

Сразу к делу: делайте игру параллельно с разработкой движка. Это правило нельзя нарушать. Изучите основы как можно скорее и сразу же начинайте создавать на этой базе игру. Движок — ничто без игры. 

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

Не программируйте того, что не нужно. Если единственный UI в игре — кнопка Play в главном меню, поздравляю! Не придется создавать мудреный пользовательский интерфейс. В The End Is Nigh нет ни физического движка, ни детектора столкновений. Там даже нет камеры, потому что она там не нужна. Я использовал электронную таблицу .csv, чтобы собрать карту мира, вместо всяких сложных редакторов. Делается легко и нормально работает.

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

Что касается языков программирования — выбирайте, каким лучше владеете. Разработка движка — сама по себе непроста, а если делать это параллельно с изучением С++, обе эти задачи станут в два раза сложнее. C# идеально подойдет для создания движка. Медленнее, чем на С++, но не критично. Более медленный язык типа Python может вызвать затруднения, если в игре много движущихся объектов… но для некоторых игр пойдет. Используйте, что удобно. 

И еще — с первой попытки идеально не получится. Моей первой игрой на самописном движке стала Closure, и в ней полный бардак (забавно, что ее номинировали на награду «Техническое совершенство» на фестивале независимых игр в 2010 году). Системы рендеринга и обновления вдвоем обрабатывали всю игру. Добавлять новые объекты было крайне трудоемко, приходилось дописывать кучу кода и  работать с кривыми редакторами анимации, так что в итоге осталось с дюжину интерактивных предметов. У некоторых из них было несколько вариаций, кардинально менявших поведение объекта — это было проще, чем добавлять новые. Так что прожекторы, зеркала и турели по сути один и тот же объект! 

Но с ошибками приходит и опыт. Движок Closure написан кое-как, но оказался достаточно хорош, чтобы запустить игру на PS3. Идея переписать некоторые части движка была заманчивой, но это лишь отложило бы выход игры. Вместо этого я писал заметки о том, что получилось плохо, чтобы учесть ошибки в следующий раз. Особенно о том, что мешало непосредственно созданию игры. То же и с The End is Nigh. В ее движке (который, кстати, НАМНОГО лучше, чем в Closure) все равно была куча ошибок, которые я решал, стиснув зубы. Как только игра вышла, я сразу начал улучшать движок для следующего проекта, исправлять раздражающие баги и добавлять новые функции. 

И так раз за разом: учишься, создаешь игру, запускаешь, и все по новой. До тех пор, пока движок не станет действительно хорош. 

Не стал вдаваться в технические подробности, как внедрить в движок каждую отдельную систему. Это зависит от конкретных вариантов использования, есть сотни способов — и каждый из них правильный. Понять, что вам подходит — ВОТ в чем суть разработки движка, с таким настроем стоит браться за создание собственных проектов.

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

Ответ на твой вопрос зависит от того что ты хочешь получить на выхлопе?
По тому что если тебе нужен CryBiteUnrealUnity 10K5000 то запросы одни, а если тебе двиг для майнкрафта то запросы другие.

Добавлено через 1 час 0 минут
Я предположу, что ты делаешь CryBiteUnrealUnity 10K5000.

С языком все просто, c# это по сути скриптовый язык. В C# есть встроенный менеджер памяти, что для риалтайма — зло.
В с++ есть возможность прямого управления памятью. У с++ есть шаблоны, что часто очень полезно. В остальном по сути братья близнецы. Хочется тебе с# бери его, если же не хочешь потом жалеть, то с++.

Те же фростбайты, анриалы, юнити и край энжины написаны на c/c++, сам сделай выводы.

Не по теме:

У шарпа вообще плюсов нет :), помогите их найти? Единственный аргумент в таких спорах что я слышал, это дот нет и куча библиотек, так ведь у с++ тоже их море, один qt если вспомнить, а в контексте разработки с нуля с# не о чем

Опять же, если ты будешь писать свой серьезный движ то использовать сторонние библиотеки не будешь, по тому что все будешь писать под свои запросы. По тому openTK тебе не нужен, тебе нужно что-то типа glfw+gluw, которые только лишь создают окно и импортируют функции api opengl (ты же на opengl смотришь?), но можешь и по хардкору #include <GL/gl.h> и самому импортировать функции и создавать окна.

Все что нужно знать об openGL есть тут.

Конкретно тебе нужно знать:
1.1) как создать окно
Первый самый простой этап.
2.1) ты должен узнать что такое шейдер, как его скомпилить на гпу, как его применить.
2.2) как создать vao (обязательно нужно разобраться как использовать несколько атрибутов), и как его выводить (рисовать), тут ты узнаешь что заходит на вход вершинному шейдеру и что выходит из фрагментного.

Тут ты уже поймешь как работает opengl, тебе станет очень радостно если ты добрался до сюда.

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

Вот от сюда будет начинаться что-то серьезное.
3.1) Нужно будет разобраться с тем что такое fbo, как его создавать, как его применять/чистить и как в него рендерить.
3.2) Зная что такое fbo, нужно будет в первый раз что то отрендерить в текстуру (тобишь в fbo), сделаешь тени.

Вот на этом моменте кончается 90% работы. Можешь начать с этого после изучения языка.

Потом ты еще должен будешь выбрать аудио апи аля OpenAl.

Что нужно знать о языке?
Само собой нужно уметь работать с массивами, циклами (for, while), блоками ветвлений (if/else, switch/case), структуры. Потом ты должен знать как алоцировать память динамически, аля new и delete, указатели ( не умные, а обычные, умные таковыми только называются).
Не плохо бы знать ооп (классы, наследование), опять же, перегрузка и таблицы виртуальных функций для риалтайма зло.

Самые важные вопросы ты не спросил. Это что нужно знать о том что нужно знать о программировании.
Так вот, знать нужно алгоритмы и патерны проектирования. Если с первым все ясно, то второе нужно по тому что иначе твой вдиж станет лапшой с такой скоростью что ты не заметишь.

Эту статью я написал для своего блога в октябре 2017 года.

Речь идёт об игре Speebot, которая сейчас выпущена в Steam. Бесплатная demo версия прилагается.

Я разрабатывал эту игру с января 2016 года в своё свободное время в одиночку. Мною выполнено всё программирование, дизайн игрового процесса, создание графики и музыки. Кроме того, я написал собственный игровой движок с нуля.

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

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

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

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

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

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

Ну и наконец: написание собственного движка — это очень интересно.

Разработка движка началась в январе 2016 года. Я назвал его YUME («мечта» по-японски). Он написан на Haxe, C++ и OpenGL. Я использую модифицированную версию библиотеки Lime, которая включает в себя несколько полезных функций, например, позволяет загружать ресурсы и открывает доступ к OpenGL.

Вот так движок выглядел после первой недели разработки.

До начала создания движка я почти ничего не знал о разработке 3D игр. Нужно было разбираться в OpenGL читая документацию, форумы и уроки, предназначенные для других языков (Java и C++). Через пару месяцев у меня получился довольно стабильный 3D-визуялизатор.

Кроме самого 3D-визуализатора, нужно было с нуля создать множество разных систем: 2D-визуализатор, машину состояний, систему временных шагов (об этом позже), систему интерфейсов, систему управления мышью, клавиатурой и джойстиками, динамические тени, 3D звуковую систему (используя OpenAL), загрузку моделей (в собственном формате, основанном на IQM), «скелетные» анимации, иерархию объектов, эффект зеркального отражения в реальном времени, отображения текста и так далее.

В конце концов, получилась 3D библиотека, которую можно использовать для чего-то конкретного. Многое из того, что я перечислил, присутствует и в других движках, но в YUME есть несколько отличий. Одно из них — система временных шагов.

Система временных шагов гарантирует, что движок обрабатывает и показывает кадры игры с определённым интервалом. В YUME нет ограничения по количеству кадров в секунду, т.е. нет привязанности к 30 или 60 кадрам в секунду. Частота кадров может быть любая, а игра всё равно будет работать с одной и той же скоростью, потому что частота обновления логики не связана с частотой обновления экрана. На компьютерах разных мощностей может быть разная производительность, и время для показа одного кадра может быть любым. А логика всегда привязана к частоте 62.5 циклов в секунду (16 миллисекунд на каждый цикл). В этом основной принцип системы временных шагов, хотя есть некоторые крайние случаи.

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

Ранняя версия YUME.

Ранняя версия YUME.

У меня была готовая библиотека, но пока ещё не движок. Пришла пора начать разрабатывать игру, и принимать решения о нужных функциях. К тому времени у меня уже было несколько идей, и я знал, что хотел попробовать поэкспериментировать с 3D «плитками».

Я начал создавать систему игровых уровней, которая использовала что-то похожее на 2D плитки (tilemaps), но с одним дополнительным измерением. Получается, что уровень можно сложить из «кубиков», как конструктор. Я создал редактор карт, чтобы ускорить процесс создания уровней. В итоге этот редактор попал в финальную версию игры и доступен каждому игроку.

Движок автоматически определяет, какую 3D модель использовать для отображения каждой плитки, в зависимости от соседних плиток. Придумал способ, как объединить все плитки в одну общую 3D модель, чтобы видеокарте не нужно было рисовать каждую плитку индивидуально. Вся карта рисуется за один раз, что очень сильно улучшает производительность.

Уровни можно редактировать и тестировать сразу. Для продуктивности — то что нужно.

Я написал простую систему игровой физики и начал экспериментировать с игровым процессом. Через несколько недель был готов первый прототип игры, в котором игрок мог перемещать цилиндр по 3D уровню.

Прототип Speebot в июле 2016 года.

Прототип Speebot в июле 2016 года.

YUME продолжал развиваться параллельно с разработкой Speebot (примерно в это время я выбрал такое название для игры). Было найдено и устранено несколько проблем с архитектурой движка, добавилось несколько новых функций: физика, частицы, отражения на поверхности воды, инструменты для анимации камеры, интерактивные объекты… Постепенно библиотека эволюционировала в игровой движок.

Я продолжал добавлять новые элементы игрового процесса, оставляя элементы, которые казались мне интересными, и избавляясь от лишнего. После некоторых экспериментов с художественным направлением графики игры я создал персонажа в Blender — маленького робота с одним колесом. Персонаж нарисован и анимирован в мультяшном стиле.

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

В конце 2016 года я сделал паузу от разработки игры, и посвятил несколько месяцев изучению и практике написания музыки. У меня нет музыкального образования, но это — моё хобби. У меня уже был небольшой опыт в композиции музыки для моей предыдущей игры Hypnorain, но я хотел улучшить свои навыки, поэтому снова погрузился в изучение музыкальной теории. Для композиции музыки я использовал программу SunVox, которая является виртуальным модульным синтезатором. В финальной версии игры Speebot всего 23 трека, которые вместе составляют более часа оригинальной музыки. Я удовлетворён результатом, и продолжу улучшать свои навыки для следующей игры.

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

После выпуска нескольких демо версий, обработки отзывов от игроков и улучшения игры, Speebot был выпущен в октябре 2017 года. В финальной версии игры 200 уровней, 4 мира, редактор пользовательских уровней, несколько дополнительных режимов игры, и много другого дополнительного контента.

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

Я продолжу использовать и развивать свой движок YUME в своих будущих играх, и уже начал работать над своим следующим проектом.


После написания этой статьи я разработал и выпустил ещё две игры на этом движке: сюжетная приключенческая игра Phantom Path, и игра-головоломка Pilie Pals.

Понравилась статья? Поделить с друзьями:
  • Как написать собственный антивирус
  • Как написать собственную программу
  • Как написать собственную операционную систему
  • Как написать собственную нейросеть
  • Как написать собственное приложение для андроид