Программирование

Snakes.run: 100 млн пикселей/с через SSH — как работает

Разбор технологии snakes.run: серверный рендеринг на Go, Unicode блок-элементы для 2 пикселей/символ, stateful rendering с VT100. 2500 игроков при 10 FPS и трафике 2,5 КБ/с. Архитектура, оптимизации и вызовы SSH протокола.

6 ответов 1 просмотр

Как проект snakes.run достигает рендеринга 100 миллионов пикселей в секунду через SSH? В чём суть технологии и как это реализовано?

Проект snakes.run достигает рендеринга 100 миллионов пикселей в секунду через SSH за счёт серверного рендеринга на Go, где каждый символ Unicode (▀, ▄, █) представляет два пикселя, а обновления передаются только для изменённых областей экрана с помощью stateful rendering и VT100-последовательностей. Это позволяет обслуживать 2500 игроков одновременно при 10 FPS с трафиком всего ~2,5 КБ/с на клиента, минимизируя накладные расходы SSH-протокола. Суть технологии — в комбинации bubbletea для терминального UI и forked wish для SSH-сессий, где вся графика генерируется на сервере и стримится как текст.

Диаграмма архитектуры snakes.run: каждый клиент получает сессию bubbletea/wish, общающуюся с игровым сервером через SSH

Содержание


Введение в snakes.run: змейка через SSH

Представьте: вы вводите ssh snakes.run в терминале — и вот вы уже в многопользовательской змейке, где тысячи игроков дерутся за лидерство. А под капотом? Никакой графики, только текст. Но этот текст рисует 100 миллионов пикселей в секунду. Звучит безумно? Именно так работает snakes.run, проект Nolen Royalty, который перевернул представление о terminal performance в играх.

Это не просто забава. Snakes.run показывает, как терминальные игры могут масштабироваться до 2500 одновременных сессий без лагов. Сервер на Go генерирует кадры, клиент их отображает — и всё через стандартный SSH. Почему это круто? Потому что SSH обычно жрёт трафик на пустяках, а здесь оптимизировано до предела. Давайте разберёмся по частям.


Архитектура системы snakes.run

В сердце системы — forked версии библиотек bubbletea (для TUI) и wish (SSH-демон). Каждый подключающийся игрок получает свою сессию: wish обрабатывает SSH-соединение, bubbletea рендерит UI. Но логика игры централизована на одном игровом сервере, который рассылает обновления всем.

Диаграмма архитектуры snakes.run

Как это выглядит? Клиент → SSH-сессия (wish/bubbletea) → игровой сервер. Нет WebSocket’ов или кастомных протоколов — чистый SSH. Сервер держит состояние игры (положения змей, еда, лидерборд), а рендеринг делегирует сессиям. Это позволяет масштабировать: 2500 игроков = 2500 лёгких сессий, но один тяжёлый игровой цикл. В итоге terminal performance взлетает, потому что нагрузка распределяется умно.

А что насчёт безопасности? SSH из коробки шифрует всё, плюс “secure massively multiplayer snake” — это не шутка, а реальная защита от читеров через серверную валидацию ходов.


Unicode рендеринг: как достигается 100 миллионов пикселей/с

Вот где магия. Обычный терминал — 80x24 символа, ~2000 ячеек. Но snakes.run делает каждый символ пикселем… точнее, двумя. Использует Unicode Block Elements: верхняя половина (▀), нижняя (▄), полный блок (█). Комбинируя их с цветами переднего и заднего плана, получает 2 пикселя на символ.

Расчёт прост: 2500 игроков × 2200 символов × 2 пикселя × 10 FPS = 110 миллионов пикселей/с. Без единого растрового изображения! Клиент просто парсит ANSI/VT100 escape-коды и красит терминал.

Почему это работает быстро? Терминалы (iTerm2, Kitty, Alacritty) оптимизированы под Unicode rendering. Нет bitmap’ов по сети — только текст, который SSH жуёт на завтрак. Но без хитростей это бы лагало. Переходим к оптимизации.


Stateful rendering и оптимизация производительности терминала

Ключ — stateful rendering. Вместо полного перерисовывания экрана каждый кадр (что сожрало бы полосу), сервер отправляет только дельту: “измени символ в позиции X,Y на ▄ с цветом Z”. VT100-последовательности типа \033[38;5;{fg}m\033[48;5;{bg}m▀ — и готово.

Трафик? Всего 2,5 КБ/с на игрока. Предвычисленные строки, баннеры в пуле — аллокаций минимум. GC в Go дергается 0,5% времени. Профилирование показало: горячие споты в рендеринге ушли после кэширования.

График профиля производительности snakes.run

Раньше CPU горел на 6,5 секундах из 10 — теперь летает. Bubbletea модифицирована: рендер только diff’а, батчинг обновлений. Terminal performance на пике, потому что нет лишних redraw’ов. А вы знали, что терминалы сами throttl’ат FPS? Snakes.run это учитывает.


Сетевые вызовы SSH и их решение

SSH — не для игр. Одно нажатие клавиши = 100+ пакетов (до 270!). 66% — 36-байтовые heartbeat’ы. Без оптимизации CPU на сервере проседает на 50% даже без данных.

Решение: минимизация пакетов через stateful подход. Wish форкнут для снижения оверхеда. Сервер батчит обновления, клиент — лениво парсит. Плюс, цвета в 256-палитре (SGR), а не truecolor — экономит байты.

В исследовании автора чётко: SSH жрёт трафик сам по себе. Snakes.run обходит это, фокусируясь на текстовом стриме. Результат? 2500 игроков без просадок.

Но есть нюансы: не все терминалы одинаково хороши. Kitty лидирует в unicode rendering, старые tmux — тормозят.


Реализация на Go: код и масштабирование

Всё на Go: concurrency из коробки. Игровой сервер — tick’и 100мс (10 FPS), pub/sub для обновлений. Сессии wish/bubbletea — goroutines.

Код открыт? Частично, через блоги eieio.games. Пример рендера:

func renderPixel(x, y int, fg, bg rune) string {
 return fmt.Sprintf("\033[%d;%dH\033[38;5;%dm\033[48;5;%dm%c", y, x, fg, bg, pixelChar)
}

Батчинг: собираем diff, отправляем одним пакетом. Масштаб: Kubernetes? Нет, просто мощные инстансы. 2500 сессий — 10 CPU cores, <1GB RAM на тысячу.

Хакер Ньюс в восторге: “уровень инженерии просто делает день” (news.ycombinator.com). Snakes.run — урок, как выжать максимум из ssh производительности.


Источники

  1. Secure Massively Multiplayer Snake — Детальный разбор архитектуры и рендеринга 100M px/s: https://eieio.games/blog/secure-massively-multiplayer-snake/
  2. Snakes.run: Multiplayer Snake over SSH — Введение в проект и базовая технология: https://eieio.substack.com/p/snakesrun-multiplayer-snake-over
  3. Secure Snake Home (SSH) — Официальная страница игры с описанием SSH-реализации: https://snake.eieio.games
  4. SSH sends 100+ packets per keystroke — Анализ сетевых проблем SSH и оптимизаций: https://eieio.games/blog/ssh-sends-100-packets-per-keystroke/
  5. Hacker News discussion — Обсуждение производительности и инженерии snakes.run: https://news.ycombinator.com/item?id=47168061

Заключение

Snakes.run — шедевр terminal performance, где unicode rendering, stateful подход и Go-конкурентность превращают SSH в платформу для 100 миллионов пикселей/с. Это не просто игра, а демонстрация: ограничения (текст, SSH) рождают инновации вроде 2px/символа и минимального трафика. Хотите повторить? Изучите bubbletea, форкните wish и оптимизируйте diff’ы. В итоге, snakes.run доказывает: высокая ssh производительность возможна даже для терминальных игр с тысячами игроков.

Nolen Royalty / Разработчик

snakes.run использует серверный рендеринг на языке Go, где каждый кадр генерируется с частотой 10 FPS и отправляется клиенту через SSH с помощью forked библиотек bubbletea и wish.

Для экономии полосы пропускания применяется подход два пикселя на символ, используя Unicode Block Elements (, , ) и комбинации цветов переднего/фонового плана. Stateful rendering минимизирует трафик до ~2.5 KB/с, отправляя только изменённые символы через VT100-последовательности.

Все строки и баннеры предвычисляются и кэшируются, минимизируя аллокации памяти; сборщик мусора работает всего 0.5% времени. Сервер обслуживает 2500 игроков, каждый рисует ~2200 символов, что даёт >100 млн пикселей/с при 2 пикселя/символ.

Диаграмма архитектуры snakes.run. Каждый клиент получает собственную сессию bubbletea / wish, которая общается с одним игровым сервером. Трафик передаётся через SSH (secure snake home)
Nolen Royalty / Разработчик

Snakes.run — это многопользовательская игра «Змейка», работающая исключительно через SSH-протокол.

Для запуска достаточно выполнить команду ssh snakes.run в терминале. Проект демонстрирует серверный рендеринг и оптимизацию передачи данных через SSH.

Игра показывает, как создать высокопроизводительную многопользовательскую систему в текстовом интерфейсе с использованием стандартных сетевых протоколов.

Nolen Royalty / Разработчик

SSH — самый безопасный способ играть в многопользовательскую змейку онлайн.

Проект реализован как современный SSH-демон с использованием библиотек wish и bubbletea для рендеринга в терминале. Данные передаются в виде текстовых блоков, минимизируя нагрузку на сеть.

Система обслуживает >2000 одновременных игроков; визуализация — ASCII-сетка, обновляемая клиентом.

M

Проект snakes.run демонстрирует высокий уровень инженерии для решения проблем производительности в очаровательной игре.

Ограничения SSH и малых систем заставляют решать неочевидные задачи, такие как маскировка нажатий клавиш. Это показывает впечатляющие возможности стандартного SSH-протокола для высокопроизводительных приложений.

Игра делает день лучше благодаря инновационному подходу к инженерным вызовам.

Nolen Royalty / Разработчик

SSH-протокол генерирует значительный трафик: одно нажатие клавиши — до 270 пакетов, 66.3% — 36-байтовые сообщения.

Это создаёт проблемы для высокопроизводительных игр. Решение: stateful rendering и минимизация пакетов.

Даже без игровых данных CPU падает только на 50%, показывая накладные расходы SSH. Оптимизации автора снижают трафик существенно.

График горящего дерева профиля производительности. Использовано 6,5 секунд CPU
Авторы
Nolen Royalty / Разработчик
Разработчик
M
Технологический энтузиаст
Проверено модерацией
НейроОтветы
Модерация