Проект: Giper Blitz Quiz  Публичный пост
19 марта 2026  447
Giper Blitz Quiz
https://b-on-g.github.io/blitz/

Как-то на митапе — то ли красного банка, то ли желтого — был интерактивный квиз для разогрева зала. Формат простой: на экране вопрос, зрители отвечают с телефонов, на табло лидерборд. Зал был в восторге. Я захотел такое же, но в открытом доступе таких инструментов не нашёл плохо искал, наверное ( хорошо ). Решил сделать сам — бесплатный, open-source, для любых митапов.

Результат: Giper Blitz Quiz — real-time квиз-платформа. Без бекенда, без сервера, деплой стоит 0 рублей. 4 дня от идеи до прода.

хост стримит игру
хост стримит игру

Как это работает

Хост открывает квиз на большом экране, участники сканируют QR-код с телефона и попадают в лобби. Дальше — цикл вопросов:

  1. Чтение — на экране появляется вопрос, у хоста есть обратный отсчёт 3-2-1, со звуком для игроков в зале
  2. Ответ — игроки выбирают вариант или вводят текст ( есть вопросы с открытым ответом )
  3. Результат — показывается правильный ответ, считаются очки
  4. Лидерборд — анимированная таблица лидеров

Очки зависят от скорости ответа: базовые_очки × множитель^(оставшееся_время / общее_время). Ответ за секунду — максимум очков. Думал до последнего — получил базу. С одной стороны мне говорили что так теряетя азарт, но я так сделал что бы уравнять всех. На тех митапах где я увидел идею для квиза, победили самые быстрые игроки, как они сами признавались, они просто угадывали, я так не хочу

Стек: $mol + Гипер База

Писал конечно же на $mol и Гипер Базе. Собстна это база с реактивной синхронизацией. Не нужно поднимать сервер, писать бэк, поднимать базу тоже не нужно, в коде вы просто описываете модельки и всё, дальше всё само синхронизируется

Хост создаёт квиз → данные сохраняются в ленд Гипер Базы. Игроки подключаются по ссылке → их клиенты синхронизируются с этим лендом напрямую. Всё реактивное, любое изменение состояния мгновенно прилетает всем подключённым клиентам

Деплой: GitHub Pages + Гипер База = 0 рублей.

Архитектурный косяк

В Гипер Базе права доступа задаются на уровне лендов. Один ленд — один набор прав, который нельзя поменять, но можно выдать форк с другими правами. Я по наивности свалил все данные в один общий ленд, и обнаружил это уже когда всё работало: любой игрок мог отредактировать чужой квиз. Причём я даже не заметил этого во время разработки)

Пофиксил, конечно, квизы теперь живут в домашнем ленде пользователя, а когда стартуешь игру — делается форк ленда квиза для игровой сессии. Но внутри этого форка всё равно всё вместе: и вопросы, и ответы игроков, и состояние игры. Разделение прав между данными хоста и игроков — чисто на уровне UI через флаг в коде. Ушлые ребята через консоль всё равно теоретически могут достучаться до данных, но на кой чёрт кому-то нужно редактировать ваш квиз?)

Фичи

Есть AI-генерация квизов. Пишешь боту «квиз про JavaScript для мидлов, 10 вопросов», он генерирует структурированный JSON и квиз сам появляется в списке. Не нужно вбивать вопросы руками. Но картинки нужно руками! Сувать картинки в json геморно, и костыльно.

ушёл запрос
ушёл запрос

я ничего не нажимал, квиз сам добавился
я ничего не нажимал, квиз сам добавился

Ещё можно делиться ссылкой на квиз и редактировать его вместе одновременно в реальном времени, Гипер База синхронизирует всё сама.

После каждой игры статистика сохраняется в профиль: сыгранные игры, общий счёт, победы, лучший результат. Есть система рангов — от «Новичка» до «Грандмастера» по количеству сыгранных игр. Знаете вот у фурри есть фурсона, а у нас квизсона :)

профиль со статой!
профиль со статой!

Ещё прикрутил реакции — игроки кидают ❤️ 🔥 👏 😊 💩 прямо во время игры, у хоста на экране отображается, а в финале отдельный экран «самых реактивных». Ну и встроенное радио на 5 станций (lofi, chill, house) и красивые QR-коды для подключения игроков.

С нейронкой накидал блог с поясняющими статьями, и настроил SEO для роботов, возможно вы даже увидите прилу в поиске)

AI-агенты

Пока писал — почти не пользовался агентами, и получилось сильно качественнее моих более ранних поделок. Старался писать код сам. Зачастую это конечно всё равно копипаста из LLM из окна IDE, но тут появляется время обдумать код и принять решение, переспросить у нейронки, найти лучшее решение. В итоге без агентов вышло даже быстрее, потому что не пришлось потом переделывать за ними. Правда в 3 часа ночи я сдался, и отдал управление, так как устал, не делайте так)

По времени где-то 4 дня сидел. Первые два дня ушли на лобби и админку, на третий собрал игровой цикл, на четвёртый фиксил баги и прикрутил AI-генерацию.

Попробуйте и вы

Я планирую использовать на разогревах на митапах @PiterUX и @PiterJS. На UX я в числе оргов как раз, опробуем на дизайнерах)

Смотрите пробуйте играйте, формируйте своё мнение, и всегда помните — хост это не игрок, он не может выбирать ответы, но вы можете запустить игру с ПК, и зайти с телефона. Или с одного ПК на разных браузерах.

Это мой текущий магнум опус.

5 комментариев 👇

Привет, Кирилл! Офигенски, спасибо за тулзу? Прям сегодня думал, где бы такой легковесный сервис найти.

До этого пользовался Kahoot, но он из России без ВыПыНа на открывается, с чем могу быть проблемы.

  Развернуть 1 комментарий

@mainsdorff, привет, Кирилл! Незачто )
Тут правда тоже может без впна не оокрыться
У клуба есть бесплатный ВПН для клубней, попробуй его

  Развернуть 1 комментарий
Kirill Chuprov СТО домашнего розлива 13 июля в 15:31

Привет, Кирилл! Выглядит круто, напиши о том как работает гипербаза, звучит интересно а кроме тг канала я про эту штуку ничего не нашел

  Развернуть 1 комментарий

@Crypto_mate, да, надо бы)
пока нет прям инфы, база в бете

есть статьи от Димы https://habr.com/ru/articles/956154/
https://habr.com/ru/articles/943606/

они в целом описывают философию

если кратко - пишем код так, как будто у нас локальная база и орм, синкается само без конфликтов с помощью crdt
шифрование не обязательно. при мерже на сервеной ноде синхронизации, такой же как в браузере, не происходит расшивровки данных

  Развернуть 1 комментарий

@Crypto_mate, еще с нейнорной набросал

Под постом про Blitz Quiz спросили: выглядит круто, а как эта ваша гипербаза работает? Кроме тг-канала почитать про неё особо негде. Справедливый упрёк, исправляюсь)

Короткий ответ: для разработчика это что-то типа ОРМ как в джанге. Описываешь модель данных и используешь её. Но под капотом оно ещё само синкается! Причём бесконфликтно.

Вот модель квиза из Blitz Quiz, целиком:

export class $bog_blitz_quiz extends $giper_baza_dict.with({
	Title: $giper_baza_atom_text,
	Questions: $giper_baza_list_link_to( ()=> $bog_blitz_question ),
	Time_read: $giper_baza_atom_real,
	Time_answer: $giper_baza_atom_real,
	Time_leaderboard: $giper_baza_atom_real,
	Time_reveal: $giper_baza_atom_real,
	Points_base: $giper_baza_atom_real,
	Time_multiplier: $giper_baza_atom_real,
	Manual_mode: $giper_baza_atom_bool,
}) {}

Читаешь поле так: quiz.Title()?.val(). Пишешь так: quiz.Title('auto')?.val('Столицы мира'). На этом взаимодействие с базой заканчивается. Ни ручек на сервере, ни кода синхронизации писать не нужно.

Философия в том, что мы как будто работаем с локальной базой. Синк реализован под капотом, задумываться о нём не нужно, как и о примитивах синхронизации. В моле это сделано заранее: поле поменялось локально или прилетело с другого устройства, для твоего кода разницы нет, интерфейс просто перерисовывается.

Теперь куда оно синкается. На серверах крутятся такие же ноды синхронизации, как у клиентов. При этом на сервере не происходит расшифровка. Никогда, даже при мерже: нода мержит чужие зашифрованные изменения, не зная, что внутри. Мерж бесконфликтный, через CRDT. Тут есть прикол: у половины решений, которые заявляют CRDT, при реальном использовании вылезают косяки, по типу очень быстрого роста базы. Есть известный замер: трейс из 260 тысяч правок текста, итоговый документ 100 тысяч символов. Automerge жевал его 291 секунду и съел 880 МБ памяти, Yjs тот же трейс прошёл за секунду и 3.3 МБ. Авторы с тех пор много починили, но в релизе Automerge 3 сами пишут: вставка «Моби Дика» в документ ела 700 МБ памяти, стало 1.3 МБ. У Yjs своя особенность: документ умеет только расти, удалённый контент оставляет надгробия, и даже «удаление истории» делает файл больше. В гайде Liveblocks приводят боевые документы по 5 МБ при контенте в 75 КБ. В Гипер Базе куча таких нюансов и мелочей решена. Разбор конкурентов с бенчами тянет на отдельную статью, а за внутренностями отправляю к первоисточнику: у Димы Карловского есть «Революция архитектуры Веба» и «Что если… ( безумные идеи хранения данных )».

Шифрование при этом не тотальное, можно делать и незашифрованные блоки, открытая база читается любым желающим.

Права живут на уровне самой базы, приложение их не изобретает. Уровней пять: deny ( доступа нет вообще ), read, post ( можно постить изменения ), pull ( можно вливать форки ) и rule ( полный контроль, включая раздачу прав другим ). Владелец базы всегда rule, остальным права выдаются персонально или дефолтом для всех.

А вторая ось прав решает проблему ботов. Нам не важно, бот к нам пришёл или человек: пока процессор не подберёт запись с определённым количеством единичек, запись не уйдёт на сохранение. Это proof of work, и его сложность зашита в те же права: чем меньше тебе доверяют, тем дороже писать, от микросекунд работы CPU до дней. Ботоферма становится экономически невыгодной просто за счёт PoW, капча не нужна.

В квизе это всё видно живьём: у каждого игрока своя база с его ответами, куда чужие писать не могут, а в общей сессии лежит только ссылка на неё. Хост читает базы игроков и считает очки, никто никому не мешает. Нюансов недоделанных в квизе ещё много, но возможности показывает)

Теперь про грабли, на которые я наступил сам. Первая запись файла или создание новой базы требует того самого proof of work. Считается он внутри wire-задачи мола, и результат кешируется только в пределах одной фибры. Я запускал сохранение файлов из обычной async-функции, и получалось так: запись бросает Promise ( PoW ещё не готов ), async-функция ретраится с начала, сохранение запускается с нуля и заводит новый PoW-таск. И так по кругу: каждый заход 1-10 секунд работы CPU, main thread занят, UI висит, в логах бесконечные «start … ensure file land» без прогресса. Лечится одной строчкой: запись оборачивается в $mol_wire_async(this).save_in_fiber(...). Внутри фибры подзадачи кешируются, и при ретрае она получает уже посчитанный PoW вместо нового.

Чего пока нет, так это файлового сервера. Файлы можно грузить в саму базу, но показать их могут только приложения, которые эту базу читают. Просто скопировать ссылку на файл и переслать не выйдет, не откроется. Я хотел сделать себе блог с визивиг-редактором, чтобы он выступал источником истины, а я оттуда копировал контент во все другие места, но пока не вышло. ПР с файловым сервером в Гипер Базу уже есть, поддержать это несложно.

Ещё из заложенного архитектурно: можно поднять свою подсеть из гипер баз, это предусмотрено и со стороны приложений, и со стороны кода Гипер Базы для развёртывания.

У нас очень ламповое и дружное комьюнити, залетайте в @giper_dev)

  Развернуть 1 комментарий

😎

Автор поста открыл его для большого интернета, но комментирование и движухи доступны только участникам Клуба

Что вообще здесь происходит?


Войти  или  Вступить в Клуб