ESPNHow a mass Man City player exodus would warp the transfer marketPunchNGF mourns victims of Ondo aircraft crashDaily MaverickSHARE WITH US: Online schools in South Africa: what should parents know?The Jerusalem PostFormer German spy chief detained on suspicion of espionage and treason, Bild reportsZDF heuteAktuelle Pressemitteilungen des ZDFSouth China Morning PostGreenpeace catches Hong Kong geopark ‘golden week’ visitors damaging marine lifeCapital FMGovt fast-tracks passport decentralisation as Malindi, Nyeri offices near completionNHK 社会JR東日本 大雨災害を受け運転規制のあり方を検証へNPRVietnamese police arrest 12 suspected of prowling city streets at night, snatching cats for meatکیهان لندنرئیس پیشین سرویس اطلاعات خارجی آلمان به اتهام جاسوسی بازداشت شدABC NewsTrump says his super PAC will now pay for controversial taxpayer-funded promo adsAntara NewsIndonesia targets Rp3,839 tln in downstreaming investment through 2029
The Daily Newsstand · Free, Always
Tuesday, October 6, 2026

Как мы делали BLE-систему аур для ролевой игры

Translate

Всё началось с желания сделать ролевую игру по мотивам компьютерной игры Arcanum, в мире которой одновременно сосуществуют магия и технология, причём эти две силы принципиально конфликтуют друг с другом.

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

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

То есть игровой мир должен был сам реагировать на присутствие персонажей.

Первые эксперименты

После небольшого исследования доступных технологий мы пришли к идее использовать Bluetooth Low Energy.

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

Один знакомый дал мне поиграться с несколькими токенами на базе nRF51822. Проблема заключалась в том, что они достались нам практически без документации и даже без сколько-нибудь полезной маркировки на самих платах.

Вместе с моим коллегой Андреем Городецким — «Эдвином» — мы взялись разбираться с этим хозяйством. О чипах мы на тот момент не знали примерно ничего, зато энтузиазма было хоть отбавляй.

Первый подопытный

Первый подопытный

Первая попытка подключиться к чипу и как-то его перепрошить закончилась в основном чрезмерным нагревом самого чипа.

После нескольких бесплодных попыток заставить эти устройства делать хоть что-нибудь полезное мы отправились штудировать AliExpress в поисках токенов, о которых у нас будет хотя бы немного больше информации.

В результате выбор остановился на HolyIOT YJ15044, также построенном на nRF51822. У него было одно принципиальное преимущество: на плате были выведены площадки GPIO, они были подписаны, а на сайте производителя даже можно было найти документацию.

После предыдущего опыта это уже казалось роскошью.

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

Первая рабочая система

С новыми токенами всё пошло заметно веселее. С помощью документации и искусственного интеллекта мы смогли написать первые скетчи, успешно загрузить их на платы и наконец заставить код работать.

Тут же, правда, начали проявляться ограничения nRF51822.

Ресурсов контроллера не хватало на всё, что нам хотелось делать одновременно. Поэтому архитектуру пришлось максимально упрощать, и в итоге практически всё взаимодействие системы мы построили вокруг BLE advertising.

Токены периодически транслировали информацию о себе, упакованную в Manufacturer Data. Другие токены сканировали эфир, находили интересующие их пакеты и реагировали на них.

Управление токенами мы тоже решили построить поверх BLE-пакетов. Управляющее сообщение содержало MAC-адрес конкретного устройства и следующую за ним команду. Все токены могли увидеть такое сообщение, но выполнять его должен был только адресат.

Доработка железа

Сам токен тоже пришлось немного доработать.

Из всей доступной пользователю индикации на YJ15044 был только один встроенный красный светодиод. Для нашей игровой механики этого явно не хватало.

Игроку нужно было понимать, что происходит с его аурой: работает ли она, подавлена ли противоположной силой, не возник ли конфликт и вообще находится ли устройство в нормальном состоянии.

Поэтому к выведенным GPIO мы припаяли два дополнительных светодиода — красный и зелёный. Так токен получил простую визуальную обратную связь, понятную самому игроку.

Ещё одну площадку мы использовали как управляющий выход. Через неё токен мог контролировать внешнюю периферию — тот самый интерактивный антураж, ради которого всё изначально и затевалось.

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

Чип до и после модификации

Чип до и после модификации

Внешний вид в сборе

Внешний вид в сборе

Aura и Interactive

Постепенно появилась прошивка, позволявшая использовать одинаковые токены в двух основных ролях.

Первая — Aura. Это персональный токен персонажа. Он изображает ауру своего владельца: транслирует информацию о её свойствах и одновременно следит за окружающим радиоэфиром.

Вторая — Interactive. Такой токен является частью игрового устройства или предмета. Он сканирует находящиеся вокруг ауры, рассчитывает их воздействие и в зависимости от результата меняет состояние самого устройства.

Когда эта система заработала у нас дома, мы решили, что пора показать её людям.

И тут случилось фиаско.

Фиаско на фестивале

Мы собирались провести демонстрацию системы на ролевом фестивале в Иерусалиме.

Для неё подготовили небольшую сценку. Я должен был выступить в роли инженера-механика и продемонстрировать публике исправно работающее технологическое устройство. Затем ко мне должен был подойти Андрей в роли мага — и по мере его приближения магическая аура должна была нарушить работу механизма.

Мы собирались разыграть небольшую перепалку между механиком и магом и тем самым показать не абстрактное правило, а то, как эта механика будет выглядеть непосредственно на игре.

По крайней мере, таков был план.

На практике демонстрация обернулась полным фиаско.

В реальных полевых условиях токены начали вести себя совершенно непредсказуемо. Сначала мы решили, что просто неправильно откалибровали расстояние срабатывания. Казалось, достаточно немного подправить пороги — и всё заработает.

Но Interactive-токен вёл себя практически хаотически. Он включался, когда не должен был, отключался без видимой причины, через секунду снова включался и вообще отказывался демонстрировать ту красивую и предсказуемую механику, которую мы наблюдали дома.

Когда мы начали разбираться, что произошло, основной гипотезой стала производительность контроллера.

Все предыдущие испытания проходили у меня дома. Рядом находилось несколько человек и относительно небольшое количество Bluetooth-устройств.

На фестивале же вокруг были сотни людей с телефонами, часами, наушниками и прочей электроникой. Скорее всего, при постоянном сканировании BLE-эфира старый nRF51822 просто захлёбывался количеством пакетов, которые ему приходилось принимать и обрабатывать.

Снова AliExpress

После этого мы вернулись к углублённому изучению AliExpress.

На этот раз выбор пал на другой токен того же производителя — HolyIOT 21014 на базе nRF52810.

Новый контроллер был заметно мощнее: более высокая тактовая частота, больше оперативной памяти, поддержка более новых возможностей Bluetooth.

Сам токен при этом оказался даже компактнее предыдущего и тоже поставлялся в готовом корпусе.

Ещё одним приятным бонусом был встроенный RGB-светодиод. Теперь нам больше не требовалось вручную припаивать дополнительные светодиоды для игровой индикации.

Правда, удобной GPIO-площадки для управляющего сигнала у новой платы уже не было. Зато на ней имелась кнопка, к контактам которой при необходимости можно было подпаяться и использовать соответствующую линию вместо самой кнопки.

Это выглядело вполне приемлемым компромиссом.

Вторая версия до и после припайки порта для периферии

Вторая версия до и после припайки порта для периферии

Вид с корпусом

Вид с корпусом

Android-приложение и испытание баром

После фестивального фиаско стало понятно ещё кое-что: одних светодиодов совершенно недостаточно, чтобы разобраться, что происходит внутри системы.

Поэтому я навайбкодил небольшое Android-приложение для диагностики и управления токенами.

Оно позволяло видеть активные токены системы, отправлять им адресные команды, наблюдать за состоянием Bluetooth-эфира и симулировать различные типы токенов, транслируя соответствующие сообщения.

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

Ту же прошивку с необходимыми изменениями мы перенесли на новые nRF52810 и отправились тестировать её в условиях, максимально непохожих на стерильную домашнюю лабораторию.

Для этого мы взяли несколько токенов в бар.

По данным нашего приложения, вокруг в тот момент находилось порядка 400 Bluetooth-устройств. То есть это были уже не наши приблизительные ощущения, а вполне конкретный замер радиоэфира.

И в этих условиях новые токены продолжали стабильно находить друг друга и правильно реагировать.

Человеческое тело против Bluetooth

Но решение одной проблемы довольно быстро обнаружило следующую.

BLE-сигнал неплохо экранируется человеческим телом.

А токен ауры мы предполагали носить как медальон на груди. В результате получалось, что человек в некотором смысле «светит» своей аурой преимущественно вперёд.

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

Если каждый стоит в свою сторону, поворачивается, ходит и периодически закрывает собственным телом линию между токенами, Interactive-устройства могут начать постоянно менять состояние. Человек повернулся — магическая аура исчезла. Через секунду повернулся обратно — появилась снова.

Для решения этой задачи мы придумали ещё одну роль — Overseer.

Такой токен предполагалось закреплять высоко над игроками, например под потолком. Там вероятность устойчивого приёма сигналов от персональных токенов значительно выше.

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

До использования Overseer на самой игре дело в итоге не дошло — у нас просто не оказалось подходящих закрытых помещений с высокой концентрацией игроков. Но сама роль осталась частью архитектуры системы.

Как были устроены сообщения

К этому моменту протокол тоже постепенно приобрёл более определённую форму.

Сообщение начиналось с нашего собственного заголовка, позволяющего быстро понять, что перед нами пакет именно нашей системы, а не очередное постороннее BLE-устройство.

Кроме того, существовали разные служебные варианты заголовка, позволяющие различать обычные сообщения, управляющие команды, сообщения Overseer и другие типы пакетов.

Дальше данные максимально плотно упаковывались побитово.

Устройство сообщало свою роль — например, Aura или Interactive, — уровень, принадлежность к одной из сторон: магии, технологии или их объединению, а также своё текущее состояние.

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

Циклы сканирования и борьба с RSSI

Interactive-устройства не реагировали на каждый отдельно полученный advertising-пакет.

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

В конце цикла устройство рассчитывало окружающий баланс сил и решало, в каком состоянии должно находиться.

Расстояние между устройствами мы оценивали по RSSI. Для каждой задачи существовал порог: слишком слабый сигнал просто игнорировался. Это позволяло сделать ауру условно локальной, вместо того чтобы заставлять каждый токен реагировать на все устройства, которые он в принципе способен услышать.

Но RSSI оказался довольно капризной величиной.

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

Поэтому реагировать на одно измерение было нельзя.

Мы добавили временную фильтрацию. Прежде чем признать ауру действительно присутствующей, устройство должно было наблюдать её на протяжении нескольких циклов. Аналогично, если уже обнаруженная аура внезапно исчезала, она не считалась пропавшей немедленно: для этого она должна была отсутствовать несколько циклов подряд.

По сути, получился своеобразный временной гистерезис.

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

Что делал Overseer

Overseer использовал ту же базовую механику сканирования, но результат обрабатывал иначе.

Он не просто транслировал другим устройствам список обнаруженных аур или общий счёт магов и технологов.

После каждого цикла Overseer сам рассчитывал состояние, в котором должен находиться каждый класс интерактивных устройств.

Результатом становилась таблица примерно следующего смысла: магические устройства первого уровня — включены, второго и третьего — выключены; технологические первого, второго и третьего уровней — выключены и так далее.

Эту таблицу Overseer рассылал в эфир.

Interactive-токену оставалось только посмотреть на собственную принадлежность и уровень, найти соответствующую ячейку и выполнить уже принятое решение.

Таким образом, Overseer был не ретранслятором, а локальным арбитром аур.

Батарейки и другие роли

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

Например, мы добавили токен-батарейку.

Устройство, работающее от такой батареи, по-прежнему являлось Interactive-токеном и подчинялось обычным правилам взаимодействия аур. Но у него появлялось дополнительное условие включения: поблизости должна находиться заряженная батарейка.

Её присутствие также определялось через BLE и настраиваемый порог RSSI.

Таким образом, одна и та же система позволяла моделировать не только магию и технологию, но и более конкретные физические зависимости между игровыми предметами.

Конфигурация и debug-режим

У nRF52810 оказалось достаточно ресурсов, чтобы кроме основной логики использовать возможность прямого BLE-подключения к токену.

Это сильно облегчило разработку.

Мы могли подключиться к конкретному устройству и получить от него отладочную информацию: что оно видит в эфире, какие решения принимает и почему находится в текущем состоянии.

Кроме того, постепенно мы начали выносить в конфигурацию значения, которые раньше приходилось жёстко зашивать в прошивку. Например, различные пороги RSSI и другие параметры поведения можно было менять уже на конкретном устройстве.

В обычном режиме токен не держал эти сервисы постоянно доступными. Он выполнял свою игровую работу: сканировал эфир и передавал advertising-пакеты.

Чтобы перевести конкретное устройство в режим настройки, в эфир отправлялась специальная команда, содержащая MAC-адрес нужного токена.

Получив команду перехода в debug-режим, токен поднимал соответствующие BLE-сервисы, после чего к нему уже можно было подключиться напрямую для диагностики или конфигурации.

Мечта о DFU

Следующим логичным шагом казалось обновление прошивки по воздуху.

Когда токенов уже не десять, а две сотни, возможность выпустить новую версию firmware и обновить устройства через Bluetooth выглядит чрезвычайно привлекательной.

Мы экспериментировали с DFU — Device Firmware Update — через MCUboot. Идея заключалась в том, чтобы иметь возможность передавать новую прошивку по BLE, после чего загрузчик устанавливал бы обновление.

К сожалению, здесь мы снова упёрлись в ресурсы nRF52810. Реализовать всё желаемое одновременно на этом контроллере у нас не получилось.

Мы даже начали присматриваться к следующему поколению токенов того же производителя — модели 52008 на значительно более мощном nRF54L15.

С технической точки зрения это выглядело очень заманчиво.

Но обнаружилась проблема куда более прозаическая: производитель не предлагал эти платы в подходящих готовых корпусах.

Для лабораторного проекта это мелочь. Для двухсот устройств, которые нужно раздать игрокам на ролевой игре, — совсем нет. Нам пришлось бы самостоятельно решать, как каждый токен защищать и как игрок будет носить его на себе.

Поэтому от более мощной платформы пришлось отказаться. Мы остались на nRF52810 — и вместе с ним отказались от мечты о полноценном DFU.

Как прошить две сотни токенов

А это оставляло вполне практическую проблему: токены всё-таки надо было как-то прошивать.

К игре нам требовалось порядка двухсот устройств: персональные ауры практически для всех игроков плюс запас токенов для Interactive-устройств и других ролей.

Сначала мы пытались придумать что-то вроде специального сокета, куда можно было бы вставлять круглый токен и быстро его прошивать.

Попытки сделать сокет для прошивки

Попытки сделать сокет для прошивки

В результате победило гораздо более простое решение.

Мы сделали небольшое приспособление с четырьмя подпружиненными контактами — по сути, маленькую четырёхзубую вилку. Её достаточно было прижать к соответствующим площадкам на плате токена, прошить его, отпустить и перейти к следующему.

Никаких разъёмов и пайки для каждого экземпляра.

Прижал. Прошил. Следующий.

Иногда самое простое решение оказывается наиболее подходящим для массового производства в домашних условиях. Впоследствии мы нашли готовое решение, но и наш колхоз работал приемлемо.

Расчёстки для прошивки

Расчёстки для прошивки

Что подключали?

Для игры были созданы два вида устройств:

  1. Умная розетка, которая управлялась с токена. От неё же токен брал питание. Такая схема позволяла включать и выключать всё что запитано от 220 Вольт - освещение и тому подобное

  2. Интерактивная гирлянда - токен управлял реле, которое подавало питание на светодиодную гирлянду. Поскольку это довольно быстро расходовало батарейку, для активации устройства было необходимо дополнительно нажать кнопку.

Спроектировал оба устройства Юра Глушков - единственный человек в нашей компании работавший с электроникой и понимавший что он делает. Ещё раз ему за это спасибо.

Гирлянда с реле и активацией кнопкой

Гирлянда с реле и активацией кнопкой

Что получилось на полигоне

Наконец система добралась до настоящей игры.

Overseer в итоге не понадобился: подходящих закрытых помещений, в которых концентрировалось бы достаточно игроков, у нас на полигоне не было.

Основным видом Interactive-устройств стали магические фокусировки.

Фокусировка магов

Фокусировка магов

Фокусировка магов

Фокусировка магов

Это были носимые на руке устройства, которыми пользовались маги. Игрок нажимал кнопку, и фокусировка проверяла окружающую ситуацию.

Если загоралась являвшаяся частью устройства световая гирлянда — маг мог колдовать.

Если не загоралась — значит, окружающая технологическая аура подавляла магию и заклинание не происходило.

Таким образом, игроку не требовалось самостоятельно считать находящихся вокруг технологов, выяснять их уровни или обращаться к мастеру. Он нажимал кнопку — и игровой предмет сам давал ему ответ.

Часть токенов мы также разместили на различных игровых артефактах.

В этих случаях дополнительную периферию мы уже не всегда успевали делать, поэтому о состоянии предмета сообщал непосредственно RGB-индикатор самого токена: активен артефакт в текущем поле аур или нет.

Жалоб на стабильность системы во время игры к нам практически не поступало.

Батареи персональных Aura-токенов спокойно пережили два дня игры (запас был на все четыре) и не потребовали замены.

С Interactive-устройствами ситуация была немного сложнее. Там, где от той же батареи питались светодиоды, гирлянды или реле, расход энергии был заметно выше. Батарейки пришлось заменять непосредственно во время игры.

Аурометр

Одной из центральных идей игры был не только локальный конфликт магии и технологии, но и изменение общего баланса сил в городе.

Игроки могли развиваться в сторону магии, технологии или появившегося по ходу игры третьего пути — объединения двух сил.

Нам хотелось, чтобы результат этих решений был виден всему городу.

Для этого на главной площади мы установили отдельное устройство — Аурометр.

Он сканировал эфир и запоминал уникальные обнаруженные токены, определяя их принадлежность. На основании накопленных данных Аурометр показывал общее соотношение магии, технологии и объединения.

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

Совсем без приключений, разумеется, не обошлось.

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

К счастью, проблема относилась именно к интерфейсу управления, а не к основной логике подсчёта.

Баг удалось довольно быстро исправить непосредственно на полигоне, обновить Аурометр — и после этого он уже нормально продолжил работать с несколькими десятками находящихся вокруг аур и выполнил свою основную игровую задачу.

Аурометр

Аурометр

Что из этого получилось

В целом система показала себя рабочей, хотя далеко не всё получилось реализовать в том масштабе, в котором мы задумывали.

Главное, чего нам не хватило, — времени на создание действительно большого количества разнообразных Interactive-устройств. Мы хотели значительно плотнее насытить полигон предметами и механизмами, которые самостоятельно реагировали бы на окружающие ауры.

В реальности значительная часть этих идей так и осталась на уровне прототипов и планов. Поэтому потенциал системы на самой игре раскрылся лишь частично. Было много проблем с физической выносливостью устройств - часть развалилась в условиях реального ношения. Мы явно зря пожалели горячий клей и не залили им всё что могли.

Тем не менее сам принцип оказался жизнеспособным.

Несколько сотен небольших автономных устройств могли находиться на игроках и игровых предметах, взаимодействовать друг с другом без центрального сервера и превращать довольно абстрактное правило «магия и технология мешают друг другу» в физическое свойство игрового пространства.

Причём сама архитектура оказалась достаточно универсальной. Aura, Interactive, Overseer и Battery — это только те роли, которые понадобились нам на этой конкретной игре. Ничто не мешает придумать другие типы токенов и совершенно другие правила их взаимодействия.

И, наверное, именно это оказалось самым интересным результатом проекта. Мы начинали с довольно узкой задачи — сделать ауру мага, от которой ломается механизм. А в результате получили небольшой конструктор для создания электронных игровых механик, которому вполне можно найти применение уже на совсем других ролевых играх.

Ссылки на репозитории:
https://github.com/MrKot86/ble-aura-mesh
https://github.com/MrKot86/BleAuraMeshManager
https://github.com/MrKot86/Aurameter

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.