«Шарарам» – это старая, но до сих пор живая MMORPG по «Смешарикам». Огромный срез моего поколения, родившегося в нулевых, нашёл там первых друзей и приобрёл первые социальные навыки. Я до сих пор, в свои 23 года, возвращаюсь туда раз в один-два месяца: пообщаться с ровесниками и повспоминать золотые годы игры.

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

Это желание вылилось в эксперимент, после которого Шарарам почти перестал лагать. Честно замерить FPS сложно – разброс между локациями огромный, – но разница видна невооружённым глазом: играть комфортно даже там, где раньше было слайд-шоу. А заодно игра снова заработала в современных браузерах!

Поиграть можно через альтернативный клиент shararam.sadfun.dev (или его десктопную версию). Надеюсь, когда-нибудь это попадёт в апстрим, и игра станет приятнее для всех. А ниже будет технический разбор, как я это сделал.

Стек Шарарама

Шарарам работает на Adobe Flash Player. Для браузерной игры, запущенной в 2009 году, это естественный выбор. Но сейчас из-за этого у Шарарама есть две проблемы (обе из которых я и решал своим клиентом).

Первая - игра перестала работать в браузерах. Adobe Flash выпилили из всех браузеров в 2020 году.

Шарарам попытался выкрутиться, оставив в браузере очень обрезанную Unity-версию, и предлагая "скачать полную версию":

Внутренности полной версии
Внутренности полной версии

"Полная версия" - это Electron, в который "насильно" засунули поддержку флеш плеера. По сути это кастомный браузер специально для Шарарама. Так игра работает и по сей день.

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

В этом виноват сам Flash Player. Шарарам полностью состоит из векторной графики, и флеш рисует её прямо на процессоре. На запуске это, видимо, было терпимо из-за разрешений экрана времен нулевых. Но сегодня играть на макбуке или 4K мониторе, даже снизив настройки графики, невыносимо.


Ruffle

Окончание поддержки Flash оставило в подвешенном состоянии не только Шарарам, но и кучу игрового наследия нулевых-десятых. Поэтому неравнодушные сделали Ruffle - современный эмулятор флеш-плеера. Он решает почти все наши проблемы:

  • Нативно работает в браузере через WASM

  • Рисует графику на GPU

  • Совместим с AVM 1, на котором написан Шарарам, на 99%, и с его API на 82% (в 2020 это было не так, но сейчас пришло время)

Так что, неужели вся эта статья сводится к тому, что я подменил рантайм флеша рантаймом Ruffle?

Нет, была одна часть, к которой Ruffle все еще не готов. Шарарам - онлайн-игра, а потому сейчас нам придется реанимировать его работу с сервером.

RTMP

Какие протоколы мы с вами привыкли использовать из браузера? HTTP для RPC, WebSocket для bidi-коммуникации, WebRTC для позвонить, WebTransport для близжайшего будущего (да и то это формально HTTP/3). А вот вы задумывались когда-нибудь, что использовали во времена Flash игр?

Познакомьтесь с RTMP. На Википедии пишут, что в основном он используется для передачи потокового видео и аудиопотоков с веб-камер. Но в случае с флеш-играми (я не буду приводить примеры из Шарарама, потому что их ToS запрещает перехватывать трафик) я вижу, что поверх него работает полноценный RPC!

Итак, игра открывает обычный незашифрованный TCP-сокет, что для нее выглядит примерно так:

// ActionScript
var responder = {
    onResult: function(value) {
        trace(value); // 70
    }
};

connection.call("sum", responder, 20, 50);

Flash превращает это в RTMP Command Message типа 0x14, сериализованный через AMF0 (просто название формата сериализации), и получается что то такое:

03                   # chunk stream ID 3
00 00 00             # timestamp
00 00 22             # payload length: 34 bytes
14                   # message type: AMF0 Command
00 00 00 00          # message stream ID

02 00 03 73 75 6D                       # String "sum"
00 40 00 00 00 00 00 00 00              # Number 2 — transaction ID
05                                      # Null
00 40 34 00 00 00 00 00 00              # Number 20
00 40 49 00 00 00 00 00 00              # Number 50
02 00 07 5F 72 65 73 75 6C 74           # String "_result"
00 40 00 00 00 00 00 00 00              # Number 2 — transaction ID
05                                      # Null
00 40 51 80 00 00 00 00 00              # Number 70

Веб-разработчики уже наверняка догадались, в чем тут проблема. Даже не в том, что в Ruffle нет поддержки этого протокола, а в том, что из современного браузерного стека никто нам не даст открыть "голый" TCP сокет, сколько кода ты не пиши. А я напоминаю, что менять код Шарарама мы тоже не можем, потому что это нарушит их ToS.

Проксируем Шарарам

Авторы Ruffle почти полностью предусмотрели вышеописанную проблему. В нём есть бэкенд "сырых" сокетов с опцией socketProxy: когда WASM-сборка хочет открыть TCP-соединение, она вместо этого стучится бинарным WebSocket-ом по заданному адресу и дальше живет так, будто это и есть сокет. Расчет, тут очевидно, на проксирование.

Но вот чего авторы Ruffle еще не сделали - это не поддержали само по себе кодирование-декодирование RTMP команд. Неудивительно, зацените фрагмент с Википедии:

В 2009 году Adobe выпустила документ, названный «спецификацией RTMP»[1], однако описание было нарочито неполно для сдерживания развития альтернативных серверов. Кроме того, для прочтения этого документа требовалось согласиться с лицензионным соглашением, согласно которому допустимо создание RTMP-сервера исключительно по спецификации от Adobe без каких-либо отступлений. В некоторых местах в спецификации указаны намеренно неверные данные

С тех пор для RTMP появился разве что нормальный реверс-инжиниринг. Тут я не буду умничать и скажу прямо - я взял свой Codex и поручил ему:

  1. Взять несколько спецификаций + опенсорсных библиотек с реализацией rtmp-клиентов

  2. Написать для Ruffle точно такую же сериализацию-десериализацию без единого отклонения, с несколькими циклами самопроверки

  3. Когда реализация по его "мнению" будет закончена – поднять весь проект, залогиниться в Шарарам, погулять по нему, поиграть в мини-игры, и при малейшем отклонении поведения от оригинала проверять, не в сериализации ли дело.

Codex работал над этим делом 11 часов, и на утро я впервые увидел Шарарам в 4K 60FPS! Итоговая архитектура получилась не очень сложной:

Хотя авторизация Смешарика работает через обычный POST shararam.ru/api/user/loqin (орфография оригинала), она привязывает выданный токен к клиенту и проверяет его при загрузке ассетов и даже RTMP подключении (причем, как я понял аж через TLS/HTTP2 фингерпринтинг) - поэтому Rust-прокси всю дорогу эмулирует один и тот же официальный клиент. То есть да, при игре через shararam.sadfun.dev ваш пароль пройдет через мой сервер - если вам по понятным причинам не нравится такой вариант, на гитхабе есть standalone-сборка, которая поднимет прокси локально, и все остается строго у вас на машине.

Итог

Для меня этот рассказ неотделим от Шарарама, но в целом получился скорее общий кейс переноса онлайн-игры с Flash на Ruffle. Надеюсь, это будет полезно кому-нибудь, кто столкнется с такой же задачей - или хотя бы разработчикам Шарарама, если они захотят вернуть одной из самых культурно значимых игр работу в браузерах. Тем более, "иконка" Шарарама перестанет работать на macOS уже в следующем году, когда Apple отключит Rosetta 2. Потому что закрытый Flash уже точно не пересоберёшь под ARM.

Все права на "Шарарам" и "Смешариков" принадлежат ООО "Смешарики" и являются зарегистрированными товарными знаками.

Комментарии (2)


  1. acc0unt
    12.08.2026 20:37

    Ну что, перепись: кто новенький, а кто уже смешарик?

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


    1. sadfun Автор
      12.08.2026 20:37

      Для переписи:

      Насчёт AIR – я только что проверил, заведется ли в нем Шарарам. Заводится, но:

      • Если грузить игру «правильным» способом, AS3-обёрткой через Loader (игра становится AVM1Movie), то часть динамических текстур съезжает и ломаются анимации. Ни renderMode, ни фиксированное окно, ни компиляция обёртки под старый SWF это не лечит - но при этом производительность реально вырастает почти до уровня Ruffle

      • А вот если сделать корнем приложения сам AVM1 (я сгенерил крошечный AVM1-бутстрап, который грузит base.swf в _level0), то всё отрисовывается корректно, но производительность идентична оригинальному флеш-клиенту.

      То есть как будто бы идеальное решение - это вообще портировать Шарарам на AS3, но тут уже надо быть его разработчиком и потратить сильно больше сил. А второй вариант мало того что является костылем, так еще и для всего этого нужна коммерческая лицензия - как будто велосипед на Electron тут лучше. Ну кроме депрекации Rosetta 2, тк AIR можно нативно скомпилить.