Бывает  такое чувство, что ты изучаешь что-то не то. Вроде интересно, а вроде и  нет. Именно такое чувство у меня и было, когда я изучал Unreal Engine —  мощный движок, можно сделать от шутера в открытом мире до платформера,  но интереса нет. До Unreal Engine я испробовал Ren’Py, Unity, Java и C#,  но, как и с Unreal Engine, у меня не было интереса. Мне хотелось  чего-то одновременно интересного и сложного. Именно в декабре  2020 года я и решил — хочу написать собственный движок для визуальных  новелл на C++. Почему для визуальных новелл? Мне они просто нравятся,  вот и весь ответ. Зовут  Никита, проживаю в Красноярске. С 13 лет занимаюсь программированием,  успел выпустить 2 визуальные новеллы на собственных движках, 5 раз  собирал команду для разработки своих проектов. Изучал C#, Java, Python,  Kotlin. Сейчас мне 16 лет, программирую на C++, пишу собственный движок — Oneiro Engine.  Взяв  первый попавшийся плейлист с видеоуроками по C++, я приступил к его  изучению. Каждый день я выделял минимум 4 часа на уроки, чтобы как можно  быстрее начать писать движки. Кстати,  для каждого урока я создавал отдельный проект, чтобы можно было потом  вернуться для повторения материала. Как итог у меня набралось около 200  проектов весом 5-10 Гб (точные цифры не помню, так как проекты удалил). Спустя  около 4 месяцев я уже знал основы C++: ООП, STL, многопоточность,  алгоритмы и так далее. Хоть знания и были поверхностными их всё равно  хватило на попытку написания движка. Первым же делом я начал  искать нужные мне библиотеки и информацию о том, как написать движок для  визуальных новелл. В итоге была найдена библиотека для 2D графики —  SFML. А вот информация о том, как написать движок для визуальных новелл —  не была найдена, но я не отчаивался. Из-за  нулевой (или около нулевой) информации о том, как создать движок для  визуальных новелл мне пришлось идти на GitHub и искать там уже  готовые/wip движки. Поняв, как можно написать движок, я создал проект в  Visual Studio и пошёл писать код, точнее — копипастить его.  Пересказывать, как я копипастил код, думаю, не надо — это будет  неинтересно. Ссылку на репозиторий моего и чужого движка, с которого я копипастил код, вы можете найти в конце статьи. Когда  я пытался писать движок на SFML, я понял одну вещь: данная библиотека  весьма ограничена. Как минимум изменение размера окна работало не так,  как нужно было, мало возможностей в 3D и так далее. Поискав информацию в  интернете о замене SFML, я наткнулся на OpenGL. Увидев  треугольник на OpenGL, который я сам вывел, я получил массу дофамина.  Тогда я решил — я хочу быть программистом графики. Потом я вывел 3D куб,  сделал базовый свет, попробовал ImGui, но было одно “но” — я не понимал  базовых вещей в OpenGL. Именно это одно “но” мне помешало в дальнейшем  написании движка на Anivisual Jam #3. 11  июля 2021 года я увидел пост на Anivisual о новом джеме под номером 3.  До этого я и сценарист команды, в которой я состоял как кодер, пытались  поучаствовать во 2-ом Anivisual джеме, но из-за нехватки ресурсов мы всё  забросили. А на 3-ем Anivisual джеме у нас были шансы, так как я знал  художницу, которая точно не откажется рисовать нам спрайты. Все  остальные ассеты (например музыку и бэкграунды) мы могли найти в  интернете. До анонса 3-его Anivusal джема я уже писал второй движок,  который как раз таки был использован для новеллы на джеме. После  начала джема и анонса темы мы почти сразу же определились с сюжетом,  персонажами и так далее. Потом опубликовали тему в специальном разделе  на форуме анивизы и начали кранчить.  За  неделю мне надо было дописать движок, перенести сценарий в код и  выложить все это на анивизу. Мне повезло, что до анонса темы я уже успел  написать ядро движка и базовый рендер, поэтому мне оставалось просто  написать абстракцию для визуальных новелл. Казалось бы, что сложного?  Надо просто выводить текст, спрайты, бэкграунды и проигрывать музыку.  Но из-за того, что я базово представлял, как это сделать, это потом  обернулось мне десятками багов: спрайты и текст уезжали при расширении  окна, не было возможности откатить прогресс, громкость музыки была  неизменяема и так далее.  На  релизе большинство багов было исправлено, но костылями. К примеру, для  решения проблемы со спрайтами и текстом было запрещено изменять размер  окна, но на других мониторах (не 16:9) всё плыло. Что  касается кода, то он очень и очень плох. Я не задумывался над  оптимизацией, да и над качеством кода тоже, так что если сейчас  взглянуть на код, к примеру, показа спрайта, то можно в прямом смысле  умереть от ужаса. Хотя не всё так плохо:) К примеру, у нас есть две команды:  1. Покажи спрайт sprite;2. Выведи текст “Hello World!”. Движок  парсит их всех и собирает в единый контейнер команд для дальнейшего  разбора. Когда игрок переходит на следующую команду (т.е нажимает  пробел/левую кнопку мыши), то движок просто увеличивает текущий итератор  на 1 и начинает разбирать команду по кусочкам: какой у неё тип, какие  данные и так далее. Вернёмся к примеру, мы зашли в игру, потом движок  автоматически пропарсил наши команды до вывода текста. В начале игры мы  увидим сам спрайт “sprite” и текст “Hello World”. Если дальше есть  команды и игрок нажал пробел, то логика идёт таким же образом до показа  текста: show bg — it++ и разбор командыshow sprite — it++ и разбор командыme “Hello, World!” — ждём нажатие кнопки мыши или чего-то другогоme “Next command.”  — it++ и разбор командыhide sprite  — it++ и разбор командыhide bg  — it++ и разбор командыme “Goodbye!” — следующих команд нет, ожидаем выход из игры Из-за  того что я не был знаком с кодировками текста и библиотекой freetype,  мне пришлось делать костыли для загрузки русских символов (глифов). Для  того чтобы написать русские символы, надо было сменить кодировку файла  на windows 1251. При этом кодировку не простого скриптового файла, а C++  исходника, так как у движка не было скриптового языка. Для работы с  аудио я взял библиотеку irrKlang free, которую нельзя использовать в  коммерческих проектах. Как я писал раньше, я не сделал изменение  громкости в игре, из-за чего игрокам приходилось изменять громкость в  микшере. Про кривые спрайты и кнопки, я думаю, не надо рассказывать, так как тут и так всё понятно. На  удивление, после релиза всё работало более или менее. Загрузка  сохранений и их создание работало нормально, сама логика работала более  чем хорошо, но не было анимаций переходов. Спрайты резко появлялись и  резко исчезали. Некрасиво, но сделано за неделю. Точно  не помню, как и когда я наткнулся на канал The Cherno, но именно от Яна  Черникова я впервые познал, что такое движки и с чем их едят. Тогда он  только начинал писать свой движок — Hazel Engine. Посмотрев парочку  видео Яна, у меня появилось представление о том, как можно написать ядро  движка, нормальный рендер на OpenGL и так далее. Именно по его видео я  пытался писать движок в третий раз. Кстати, по сей день я смотрю его видео и иногда стримы, чтобы узнать что-то новое, да и просто получить вдохновение. Перед  разработкой 3-его движка я решил испробовать Vulkan API, при этом не  зная как устроена графика внутри. Как итог спустя 2 недели я решил  бросить изучение Vulkan API. Где-то в сентябре 2021 года было решено начать разработку третьего движка — Rebirth Engine 2.0. Как  и всегда, представления о том, как будут работать и взаимодействовать  компоненты движка, не было. Зато была идея использовать скриптовый язык  lua для написания скриптов новелл с похожим на синтаксис Ren’Py. В  принципе, движок был написан по той же самой схеме, как и все прошлые,  но были добавлены анимации (простой dissolve эффект), синхронизация с  разными разрешениями и соотношениями сторон и так далее. Основным  нововведением был скриптовый язык Lua через который я пытался  реализовать похожий на Ren’Py синтаксис скриптинга новелл. Кстати, схема разбора скрипта новелл была такая же. Вместо полноценной статьи получилось сочинение на тему “Чем вы занимались весь год?” :D Кстати,  после изучения Vulkan API я пошёл пилить демки на OpenGL (OGLD), но там  ничего интересного нет, а после разработки Rebirth Engine 2.0 я решил  впервые в жизни зайти на реддит и сделать пост по поводу следующего  движка (ссылка на пост будет в конце). Следующая  статья уже будет о текущем движке, его структуре, используемых  технологиях, проблемах с которыми я столкнулся при разработке и так  далее. GitHubДвижок, который использовался как пример в разработке первого движкаПервый движок (Simple Visual Novel Engine)Второй движок (использовался на Anivisual Jam #3)Новелла созданная на втором движкеПроект для изучения Vulkan APIТретий движокПост на реддите