Разработка игр на Rust. Обзор экосистемы
Здравствуйте! Я занимаюсь разработкой игры на Rust и хочу рассказать об этом.
Моя первая статья будет полезна тем, кто хочет начать делать игру на Rust, но не уверен, какие из пакетов (крейтов) стоит использовать и что вообще происходит в экосистеме Rust для игрового разработчика.
Небольшое отступление — зачем всё это? Есть же готовый X?
Под впечатлением вот этого выступления, я начал писать свой игровой движок на Haskell. Далеко дело не зашло, но я написал рендер моделек, простое освещение, немного сети.
Haskell дал возможность вынести контракты из проверок в рантайме на уровень системы типов. Ну и остальные вещи, о которых рассказывает Кармак — быть уверенным, что функция делает именно то, о чём декларирует в своём типе. Быть чуть ближе к настоящей формальной верификации нашего игрового кода — то есть, в теории, иметь гарантию корректной работы вообще без тестов.
Но, с Haskell было несколько проблем — для вывода 3д в реальном времени он достаточно медлителен. Не было сообщества занимающегося на нём играми. Не хватало нужных для игр библиотек.
С Rust же всё пошло куда веселее.
На мой взгляд, Rust сочетает все свойства, нужные игровым разработчикам, в очень правильном соотношении:
-
мощная, но при этом простая система типов;
-
абстракции бесплатны по перфомансу — не надо платить за те абстракции, которые не используешь в явном виде;
- простая и безопасная многопоточность;
И при этом на нём очень просто писать код, язык маленький и простой.
Вернусь к экосистеме:
Работа с окнами:
Glutin — раст-альтернатива GLFW, используется в Servo, активно развивается. Создаёт окна на win/osx/linux/android. На ios еще не работает, кто-то хотел сделать, но с 2015 об этом желающем не слышно.
И есть биндинги к не-растовым библиотекам: glfw-rs rust-sdl2 rust-sfml (сайт). Все три живы и поддерживаются.
Графические API:
Есть возможность использовать напрямую OpenGL/DirectX/Vulkan, к тому же уже созданы растоспецифичные графические библиотеки.
Glium — безопасная обёртка над OpenGL, по факту — в основном над OpenGL 3, хорошо поддерживаются OpenGL < 4 и OpenGL ES. Поддержкой всех хитростей четвертой версии OpenGL автор заниматься не планирует, он считает, что тогда лучше сразу браться за Vulkan. Развивается в настоящий момент достаточно неспешно — автор в основном занимается своей игрой на вулкане.
Тем не менее на PC glium со своими функциями справляется — на нём действительно удобно писать OpenGL код.
Есть целый учебник. Он не полон, но по началу очень полезен.
Vulkano — аналог glium, но для Vulkan. Именно им занят автор glium, разработка идёт очень активно. С презентацией vulkano можно ознакомиться здесь.
Gfx — универсальное API без привязки к графическому бэкэнду. Сейчас работает поверх OpenGL и DirectX, в скором времени планируется Metal и Vulkan. Разрабатывается активнее glium. С gl es и мобильными устройствами в данный момент всё чуть хуже, чем в glium, но прямо сейчас ведутся очень активные работы в эту сторону.
Gfx и Glium отличаются по поставленным задачам — glium просто предоставляет api к стабильному opengl, gfx же сконцентрирован на своём универсальном и типобезопасном api к самым современным графическим бэкендам.
Kiss-3d — маленький, простой графический движок. Не богат на функционал, но к этому и не стремится. Позволяет создавать окна и рисовать графические примитивы. Выглядит поддерживаемым, но активной разработки не замечено. С другой стороны — оно уже полностью готово, свои функции выполняет.
Готовые графические движки:
Piston PistonDevelopers — по сути, это огромное количество проектов объединенных общей целью — стать, когда-нибудь, модульным игровым движком. «Не в каждом раст проекте есть пистон целиком, но в каждом есть немного пистона» («No Rust game project uses most of Piston, but most uses some of it!»).
Основной разработчик последние месяцы занимается исключительно своим скриптовым языком Dyon и демо играми на нём (asteroids).
В куче репозиториев PistonDevelopers есть что-то почти готовое, но, по большей части, оно всё очень разрозненное и далеко от какого-то практического использования.
Amethyst — намного моложе Piston, еще далёк от использования по назначению, однако активно развивается. Дизайн вдохновлён BitSquid/Stingray (от Autodesk). Уже есть графический пайплайн, forward/deffered rendering, asset pipeline, конфигурация через yaml. Основной разработчик пропал, но сообщество очень активно пилит дальше.
Математические библиотеки:
Cgmath — используется в примерах и gfx, и glium. Хочет стать основной математической библиотекой для игр на Rust.
Nalgebra — используется в ncollide и nphysics. По большей части используется там, где нужен ncollide/nphysics.
И то и то работает, все основные операции есть.
Glm-rs — насколько я знаю, использовалась до cgmath с nalgebra, просто биндинги к довольно известному GLM.
Поиск коллизий:
Collision-rs — система поиска коллизий, использует cgmath. Создавалась как часть cgmath. В отличие от остального cgmath так себе сопровождалась и была вынесена в отдельный крейт. Реализована далеко не вся нужная функциональность, тестовое покрытие так себе, но, зато, построено на cgmath, не надо тащить две разные математические библиотеки.
ncollide — система коллизий от nphsysics, использует nalgebra. Развивается активно, имеет красивый сайт. Тестируется и развивается всеми пользователями nphysics.
Entity-component-system:
https://shaneenishry.com/blog/2014/12/27/misconceptions-of-component-based-entity-systems/
http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/
Довольно популярная идея для проектирования игр, уже есть готовые растовые реализации:
Specs (https://github.com/slide-rs/specs) — единственная действительно многопоточная ecs. Достаточно активно развивается, используется в amethyst.
https://crates.io/keywords/ecs — целая куча систем, существовавших до specs, каждая со своими нюансами, описывать каждую — тема для отдельной статьи.
Когда я начинал specs еще не было, и я написал свой велосипед.
Работа с ресурсами:
obj — растовая реализация .obj, работает :)
Assimp — биндинги к assimp — библиотеке работающей с кучей 3д форматов
image — растовая реализация популярных форматов 2д. Работает, но есть нюанс — в cargo нет возможности подключить бинарную/релизную версию зависимости к отладочной сборке. Из-за чего отладочный Image ну очень долго открывает картинки в отладочных сборках. С релизными сборками проблем нет. Ждём пока cargo научится использовать зависимости с другими параметрами.
stb-image — биндинги к сишной библиотеке по работе с картинками. По функционалу — аналог image, но решает проблему отладочных зависимостей — даже в отладочных сборках работает быстро, потому что сишный код собирается со своими собственными флагами.
zip-rs — просто zip архиватор, cжимать ресурсы.
Работа со звуком:
ears — просто биндинги к OpenAl. Я пользуюсь именно им, для звуков — всё отлично.
vorbis — биндинги к vorbis.
rodio — более высокоуровневая работа с vorbis.
GUI:
С гуи дела обстоят не очень. Идеальной игровой гуи библиотеки пока что не существует. Однако, есть:
Imgui — биндинги к imgui. Отлично работают вместе с glium. Но заточен для инструментария разработчика, не поддерживает скины, неудобно верстать нестандартные окна.
Awesomium awesomium-rs — дорого для не инди, C API есть только у древней версии. Но работает достаточно быстро, api — удобное.
Скелетная анимация:
skeletal_animation — есть у Piston, но уже заброшен. В json описывается граф анимаций, немного похожий на Mecanim из Unity. Поддерживает gpu-скиннинг. Но, к сожалению, есть зависимости и на piston, и на gfx — не так просто интегрировать в проект на glium.
Физика:
Поскольку я делаю игру про физику — для меня это важный вопрос. Для раста есть только github.com/sebcrozet/nphysics.
Nphysics состоит из nphysics2d и nphysics3d. Для 2д, говорят, хватает, а вот в 3д дела не очень — до того же Bullet по возможностям еще далеко, приходилось довольно много дописывать. Однако, работы идут и идут достаточно активно.
Хочется использовать Bullet, но к актуальной версии C API еще нет, ждём.
Инструментарий:
cargo-apk — дополнение к cargo, позволяющее создавать android apk файл + библиотека по работе с окружением Android из кода.
cargo-profiler — использование valgrind через cargo.
hprof — фрейм профайлер, не найдя hprof я написал свой такой же, но хуже — tinyprof. Очень удобно смотреть что происходит в каждом кадре.
Как редактор сцен, материалов и игровых сущностей я использую Blender. Об этом, если это будет интересно, я расскажу в следующей части. В целом — я доволен, удобно.
С IDE же дела обстоят так:
Есть racer, отдельный проект, предоставляющий редакторам данные для автодополнения и простейшей навигации. По функционалу он еще не дотягивает даже до ghc-mod. Существуют плагины для всех популярных редакторов (Vim, Emacs, Atom, VS Code и т.д.).
Уже запланирован полноценный ide-backend «Oracle». Это тот же racer, но с поддержкой в компиляторе и более работающий.
Плагины для eclipse и visual studio могут в полноценную отладку — ходьбу по шагам итд.
Можно посмотреть результаты опроса по популярным IDE. Результаты странные — идеевский плагин (насколько я знаю) один из самых бедных по функционалу — просто обвязка над racer.
Подробнее про состояние дел можно прочитать тут.
Открытые игры в разработке:
https://github.com/bfops/playform
https://github.com/ozkriff/zoc
https://github.com/kvark/vange-rs
https://github.com/PistonDevelopers/hematite
https://github.com/kvark/claymore
https://github.com/PistonDevelopers/piston/wiki/Games-Made-With-Piston
Наша игра:
В начале статьи видео геймплея нашей игры — это сетевой шутер с синхронной разрушаемостью. Мы пока что в пре-альфе, готовимся к публичной альфе, плейтестам. Ищем людей ;)
Сообщество:
Дружелюбное раст-геймдев сообщество всегда радо ответить на вопросы в irc (#rust-gamedev) или в русскоязычном гиттере: gitter.im/ruRust/gamedev.