Awesome Wasm Rust
Открыл для себя WebAssembly (Wasm) в связке с Rust. Отличная штука.
Немного теории
WebAssembly – это виртуальная машина, встроенная в современные браузеры. Wasm бинарные файлы предварительно компилируются, как Java Applets и Adobe Flash. Когда только стал писать приложения под Wasm, подумал – да это же Flash. Немного погуглив, нашел, что есть проекты по портированию flash в Wasm:
- Ruffle - эмулятор Adobe Flash Player.
- Lightspark - клон Adobe Flash Player, аналогичный тому, как ReactOS относится к Windows XP.
- CheerpX for Flash - эмулятор, позволяющий запускать оригинальные x86 файлы Flash в браузере. Основная идея при эмуляции Flash - запустить оригинальный Flash-плагин в Wasm.
Почему WebAssembly?
Пришел я к этому после того, как изучил базу по Rust, прошел контест по алгоритмам. Подумал, что слеюущим шагом по изучению языка должна стать игра. Поискал возможные варианты и нашел Wasm.
Он имеет неоспаримые плюсы по кроссплатформенности. Раньше для запуска игры потенциальному пользователю нужно было проделать не очень удобные шаги. Например, во времена университета, я написал под win на SFML свой платформер и показывал на своей машине всем одногруппникам. Для того, чтобы дать поиграть игру не у себя на компьютере, сделал установочный пакет, который отдавал. Пользователю его нужно было поставить, что не всякий захочет. Аналогично с apk пакетом для Android.
С помощью Wasm можно любые свои начинания обенуть в web и опубликовать, чтобы показать всем. Этим всем не нужно ничего ставить, только кликнуть на ссылку. Да и работает webasm на любой платформе.
Первая игра — Box2d lite
Моя первая “игра” скорее является игрушкой, а не полноценной игрой. Я переписал учебное демо физического движка box2d-lite, который изначально был написан на C++.
Переписывание движка не было основной целью, оно служило для тренировки в написании кода на Rust. Интересным оказался процесс интеграции GUI и его оптимизация под Wasm. Я добавил поддержку 2D графики, реализовал публикацию игры на GitHub Pages и добился корректной работы как на десктопах, так и на мобильных устройствах. Более того, я реализовал две разные версии GUI.
В этом проекте мне хватило одного шейдера, чтобы рисовать разноцветные квадраты. Реализовал управления с помощью мыши, “тапов” и клавиатуры.
- Проект на GitHub
- GUI на WGPU/Winit
- GUI на Macroquad
- Отдельное спасибо автору оригинальной верси Box2d lite на С++ Erin Catto.
WGPU/Winit или Macroquad
WGPU/Winit
Первоначально я разработал игру, используя связку WGPU и Winit. Эта комбинация — довольно низкоуровневая, и напоминает работу с SDL: есть такие сущности, как surface, device, render_pipeline, window, и eventloop. Возникли сложности с асинхронностью и управлением владением в структурах. Оберток для удобства почти нет. Это идеальный выбор для тех, кто хочет максимальный контроль над процессом рендеринга и оптимизирует производительность.
В ходе разработки мне пришлось столкнуться с неожиданной проблемой: одно из обновлений Winit оказалось несовместимым с WGPU в контексте Wasm. Я пытался добавить пару костылей, но они не сработали. Через месяц я нашел обсуждение, в котором разработчики обеих библиотек поднимали взаимные вопросы на исправление ошибок, поскольку произошел разрыв в совместимости. В итоге я решил оставить проект на старой версии библиотек.
Несмотря на эти сложности, мне удалось реализовать задуманное, хотя я так и не смог добиться динамического изменения размера окна.
Macroquad
Macroquad оказался гораздо дружелюбнее. Его API намного проще и “слаще” в использовании. После предыдущей реализации на WGPU/Winit я быстро смог перейти на Macroquad и адаптировать проект.
Когда я мельком посмотрел исходники Macroquad, то обнаружил знакомые фрагменты кода, которые ранее писал для WGPU — библиотека использует похожие внутренние структуры.
Динамическое изменение размера окна в Macroquad работало почти “из коробки”, что стало приятным сюрпризом. Кроме того, проект компилировался и запускался значительно быстрее, что для разработки игр критично.
Macroquad — это высокоуровневый фреймворк, идеально подходящий для разработки небольших игр, прототипов и простых проектов. Он значительно упрощает работу с Wasm.
Ghost rabbit
У вас есть код или проект, которым вы гордитесь уже много лет? У меня это культовая игра Ghost Rabbit, которую я написал на летней практике первого курса бакалавриата. Спустя 13 лет я переписал её на Rust, чтобы можно было запустить в браузере без установки на ПК или телефоне.
Игра — клон Doodle Jump. На первом курсе я собрал мини-команду из соседей: один был тестировщиком, другой — дизайнером. Они были с других профилей и не имели отношения к моему курсовому проекту. Чистый энтузиазм.
Это был мой первый проект на C#. “Си - он и в Африке Си”, — думал я. Я не знал об ООП и классах, но хотел сделать игру. У меня был туториал с примером игры “падающие яблоки в корзину” и фреймворк XNA. Этих технологий мне хватило, чтобы сдать летнюю практику.
На защите меня спросили: “Что такое this?”. Я ответил, что это фича языка/фреймворка, что это просто должно быть. Преподаватель усомнился, что я сам писал код, и попросил написать одну из функций по памяти. Я сделал это и получил зачёт.
- Поиграть
- Исходный код на Rust
- Старый код C# тоже залит на GitHub. Можно не только посмотреть, но и установить на ПК. Полноценный установщик со всеми зависимостями работает до сих пор.
Новые фишки Wasm и Macroquad
По сравнению с Box2d-lite здесь я уже:
- Использовал текстуры
- Использовал звуки
- Добавил EditBox
- Сохранил настройки и таблицу рекордов в local storage браузера
Не все задуманное реализовывается
При переписывании произошёл факап. Я хотел сделать бота на основе лабы с первого курса магистратуры “обучение нейронки с помощью генетического алгоритма”. Нейронка написана, популяции эволюционируют, но бот не обучается. Оставил эту затею, как и код в репозитории. Хоть на тестовой задаче преобразования прямого кода в обратный эволюционирующая нейронка работает.
Заключение
Wasm в комбинации с Rust — это мощный инструмент, который открывает новые возможности для разработчиков игр и приложений c GUI. Позволяет быстро создать кроссплатформенные решения. Библиотеки Macroquad и WGPU/Winit помогут вам в этом.