The joiner-side filter only runs on builds that HAVE it -- a stale-zip
player runs an old exe with no filter, finds the lobby, and joins anyway.
The host must do the rejecting, and the lever already ships in every old
build: a member omitted from btl4map hits its own "the host's map is
missing us" path and fails the join cleanly.
1. PublishSelf stamps per-member data bv=BT_VERSION_STRING; an old exe
cannot fake a key it never sets.
2. Host GO mint: any non-self member with absent/mismatched bv gets NO
token -- omitted from the map, loud REJECT LobbyLog with both builds.
3. Room screen: mismatched members show [WRONG BUILD -- WILL NOT LAUNCH]
so the host sees who's stale BEFORE pressing GO, not after the match
starts short-handed.
Verified in the deployed exe by string scan (btl4ver, REJECT-at-GO,
BUILD MISMATCH ascii + WRONG BUILD utf16 all present). Field behavior to
verify on the next Steam night.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>