Running a match
How to get from a bag of taggers to a finished game with a scoreboard. There are two ways to run one, and the simpler way needs nothing but a laptop.
The two ways to run a game
A laptop on its own. Your laptop holds a Bluetooth link to every tagger and runs the whole game. Everyone has to stay within Bluetooth range of it, which is a room or a small yard. This is the simplest thing that works and it is proven on hardware: on 2026-08-25 one command ran a full scored Team Deathmatch on two real taggers, with spawn, hits, deaths, host-driven respawn, a frag limit and the correct winner. A three-tagger synced start is proven too. The command is:
python -m brx_mcp play tdm <addr1> <addr2>Get the addresses from python -m brx_mcp scan. Add outdoor=1 volume=90 outdoors: the default
volume of 80 is set for indoors.
Mission Control plus a phone on every tagger. Each player carries a phone running the BRX Companion, which holds the Bluetooth link to that player's tagger and runs that player's game. Mission Control on a laptop writes the game, starts it and adds up the results over the field Wi-Fi. This is what scales to a real field, because the Bluetooth link rides the player instead of sitting on the laptop. It has run whole matches: a 300 second free-for-all on 2026-08-30 with two iPhones and a MacBook host, and an outdoor Team Deathmatch on 2026-09-01 with two Android phones. It is also unfinished and changes week to week, and the published Android build can be behind the current game rules. Four things have never been run: a dispersed start with players out of Wi-Fi range before T-0, a recovery after real coverage loss, more than two phones, and a 20 minute soak.
What you need
For the laptop-only way:
- A laptop with a Bluetooth radio (Windows, macOS or Linux).
- The software: clone the repository and run
./start.sh --setup-only(start.cmdon Windows). See Install. - Your taggers, each with a charged headset switched on.
For Mission Control plus phones, all of the above, and:
- A Wi-Fi router for the field. It needs no internet. A battery travel router is the recommended option and is what both live matches used. The laptop's own hotspot works for a small game.
- One phone per player, with the BRX Companion installed and paired to that player's tagger before match day. Install it at home, where there is internet.
- The armory map for your taggers (
~/.brx-mcp/armory.json) on the machine that will host. - Optional, for phones that have a data plan: internet at the laptop and
cloudflaredinstalled (the start script offers to install it for you). See Reaching phones over the internet below.
Every python -m brx_mcp command on this page runs through the virtual environment the install step
created: .venv/bin/python on macOS and Linux, .venv\Scripts\python.exe on Windows, or activate the
venv first and drop the .venv/bin/ part.
Before the players arrive
Once per tagger (the armory). Do this at home, once, and again only if you re-pair a headset or rename a tagger. Stock taggers are identical and unlabelled, so this is what makes each one self-identifying.
- Power on exactly one tagger and switch every other one off. With a single tagger visible on Bluetooth, the advert you see is certainly the tagger in your hand.
- Cable it to the machine over USB (the "Programing Port") and run
python -m brx_mcp enroll <GunName>. That reads the device record, saves a backup, binds the serial number to the Bluetooth address and writes the tagger's name. - Name the tagger its headset sticker code, not a player's nickname. The tagger then announces itself on every scan, and nicknames stay a display layer in Mission Control.
- Print that same code on a label and stick it on the tagger, so anyone can grab a tagger and its correct headset without guessing.
- Power-cycle the tagger and run
python -m brx_mcp armoryto confirm the row.
~/.brx-mcp/armory.json holds headset PINs. Keep it out of any repository, and copy it to the
match-day machine: a fresh laptop has an empty one and will show no taggers.
Every match. Charge everything. Use taggers that have been powered off since the last session, because a tagger left powered all day starts refusing links. Put the router up, join the laptop to it, and start Mission Control:
./start.sh(start.cmd on Windows.) Every launch saves its own log under
~/.brx-mcp/sessions/<launch-id>/mc.log, so there is nothing to redirect by hand.
Open the exact link it prints, including the #tok= part. That is the operator token, and it is
new every launch. On each phone: join the game Wi-Fi and turn Do Not Disturb on. Leave every
other connection setting alone: players never change mobile data or Wi-Fi options.
Muster
This is the per-game arming, and it is where a bad start gets caught.
- Eyeball every headset first. A headset slow-blinks rainbow when it is disconnected or unpaired, and a tagger with a dark or unpaired headset silently refuses to join, with no error and no voice line. This is the single most common cause of "only two of the three taggers started". A settled headset shows its team colour before the game and goes dark once play begins, which is normal.
- Get each player onto a tagger. Add the player in Mission Control and assign their tagger; the player opens the HUD and taps Set My Tagger. The player's row goes from "no node" to linked.
- Kit them out. Set display name, team, weapon and voice. A weapon change can push a silent try-out so the player fires and reloads to feel it. A configured but unspawned tagger ignores incoming shots, so try-outs are safe in a crowd. Point the tagger away from people anyway.
- Ready up and push. Players ready up on their phones, then you push the configuration to every tagger. Each tagger answers with an echo. A tagger that does not echo is almost always a headset problem, and it blocks the start. Add every player before the push: a player added afterwards is not sent a game and needs a re-push.
- Check the board has no reds. Amber never blocks a start. Reds do, and each one names its own fix.
- Start with a runway. The default is 30 seconds; pick a longer one for walk-to-your-base time. Every phone counts its own tagger down and spawns it at zero, so no signal is needed at the moment of start. Confirm every player shows armed and counting. If you need to abort, do it before players scatter: a phone already out of range never hears the cancel.
On the laptop-only way, muster is the same eyeball check plus the one play command, which
configures every tagger first and then spawns them together.
Reaching phones over the internet
By default the field is an island: phones reach Mission Control over the field Wi-Fi and nothing else. If the laptop has internet (a travel router with a SIM, or tethered to a phone), you can also let any player phone that has a data plan reach Mission Control from wherever it has signal. Nothing is installed or configured on the phones. This is optional, and a match never depends on it.
- Install
cloudflaredon the laptop once (brew install cloudflaredon a Mac). No account, no login. - Start Mission Control as usual. On the Armory screen, in the join panel, find REACH and press TURN ON under INTERNET. The row reads STARTING, then UP with a hostname. If it reads ERROR, the text beside it is the reason; the usual one is no internet at the laptop. When every phone on the board is green, the Armory also shows ENABLE BACKHAUL beside HARDWARE READY. It does the same thing as TURN ON, and you can go on to PLAY while the link starts.
- The join QR now carries both addresses. New phones scan it as always. Phones that already joined over Wi-Fi pick the internet address up by themselves; nobody rescans.
- In the Lobby, each row shows LAN or BACKHAUL, and the header says how many phones are on backhaul. A phone on backhaul keeps getting kill confirms, score and the result anywhere it has signal. The chip also says how many of those are on mobile data. Only a phone on backhaul AND on mobile data counts as covered; when every phone is, the score-cap and last-one-standing ends reach every phone that keeps its signal.
What it needs and what it does not do: the laptop must have internet; the phone must have a data plan and a
signal, so a park with no cell service plays exactly as it does without it; the time limit is still required.
If the tunnel dies, a banner says so on every screen and the phones fall back to Wi-Fi on their own. Turning
it back on gives a new hostname, which only matters for a phone that never comes back into Wi-Fi range: that
one rescans the QR. You can also start with the tunnel on: ./start.sh -- --tunnel (anything after
-- goes to Mission Control).
Two rules from the first field run: do not turn the tunnel off during a session (every phone on it drops and must rescan), and wait for the row to read UP before anyone scans. A new hostname can take a few minutes to reach some home routers; a phone that asks too early may need to wait that long before its scan works.
During the match
Mission Control is setup, start and recap only. It is not Bluetooth-connected to any tagger while you play. Each phone runs its own tagger's game loop and reports over the Wi-Fi when it can.
You can watch the live board, end the match early, recall a running game, and (with an explicit confirmation) panic-stop the reachable taggers. A panic leaves a tagger unable to register hits until it is re-armed or power-cycled, so it is a stop, not a pause. You cannot change loadouts, add players or re-push a game once it is live.
A player who walks out of Wi-Fi range is stale, not gone. Their row shows the last known values and how old they are, their events queue on their own phone, and everything flushes and is credited exactly once when they walk back into coverage. So a scoreboard can be behind while the final result is still correct. Tell players not to press the power button and not to take calls: a locked or backgrounded phone pauses the HUD's timers until it is back in front.
After
At the time limit, or when you end the match, Mission Control works out the winner, per-player kills, deaths, accuracy and medals. The recap stays provisional until every player's phone has flushed its events, so a player still walking back can still change a number.
The kill medals (First Blood, Double Kill up to Killionaire, Killing Spree, Unstoppable) are named after the voice lines built into the Battle Company tagger's own sound bank, except Beat Down (Halo's name, over the gun's "Fatality" line) and Killjoy (text only, no line). Open BRX ships no audio. If a rights holder objects to a name, we will rename it.
Before anyone closes the app, have each player hit Share log. The HUD keeps its log and the last
60 raw Bluetooth frames in memory only, and closing the app loses them. The launch folder
~/.brx-mcp/sessions/<launch-id>/ already holds the session database (session.sqlite) and the
Mission Control log (mc.log); copy it off if you want to keep it. Results export as CSV,
and every finished match of the session stays available. Starting the next game is one action, and
you can keep or clear the roster. Power the taggers off between sessions.
Reporting a problem
Found a bug? Make a report and file it on GitHub:
./start.sh --report(start.cmd --report on Windows, or press Report a problem in the console.)
The command finds your newest Mission Control session and writes a zip file,
open-brx-report-<launch-id>.zip, in that session's folder under ~/.brx-mcp/sessions/. It prints
the full path. It replaces player names, tagger ids, PINs, IP addresses, your
home folder and tokens first. It does not change names shorter than 3 letters, bare numbers, or
text you typed (team and game names). So open the zip and check it before you post: the issue
you file is public.
It then opens a prefilled GitHub issue in your browser and shows the zip in your file manager.
Drag the zip into the issue form, describe what happened, and submit it.
When something goes wrong
Only some of the taggers joined. A headset that is off, unpaired or flat makes its tagger refuse to join, silently. Look for the rainbow blink, fix the headset, power-cycle that tagger and push again.
A phone shows as on the wrong Wi-Fi, or Mission Control unreachable. The field router has no internet, so Android decides the network is dead and sends new connections over mobile data, where the game network cannot be reached. A current Android app is built to keep its own link on the game Wi-Fi, which is not yet proven on a phone. Do not ask the player to change anything on the phone. Turn the internet tunnel on (see Reaching phones over the internet): that phone then reaches Mission Control over mobile data by itself, and its row reads BACKHAUL. A phone with no mobile data at all is simply on the game Wi-Fi and is not affected.
A tagger will not connect, or connects and drops straight away. A tagger left powered all day
starts doing this: power-rest the taggers between sessions. Establishing a Bluetooth link succeeds
roughly one attempt in three anyway, and the automatic retry is the fix, so give it a moment. If a
tagger never appears at all, a forgotten brx_mcp process from an earlier session may still be holding
it: a held tagger stops advertising and looks broken. Kill the old process and it comes straight back.
A tagger is called Tactix2 again. Someone opened the Callsign app on it, which wipes the name you
enrolled. Re-stamp it with python -m brx_mcp rename <address> <name>, and do not open Callsign on
an enrolled tagger.
The console says the operator token is required, or shows Mission Control offline while the server
is plainly running. That is nearly always a stale token: a bookmark without the #tok= part, or a
restart, which mints a new one. Open the link the server printed this time.