Разработка игр на 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.

© Habrahabr.ru