---
status: accepted
---

# Perception gating — per-player visibility is server-computed from progression + spatial state

Legacy BNO is fully client-authoritative (the Master only relays): hidden tiles self-reveal
client-side, public chat is a proximity rebroadcast, and appearance/inventory are unvalidated, so
the original could not meaningfully enforce *who sees what*. ReBNO is server-authoritative, so we
adopt **perception gating** as a core pillar: what a player perceives — which avatars they see,
whose chat they receive, which map markers and friend-location text are shown — is **computed
server-side from that player's own progression + spatial state**, never trusted from the client.

The rule has a deliberate boundary: **avatar and chat visibility are spatial/progression-only**
(you see a Navi only if you share their contiguous hidden-tile body / reachable geometry, and
within chat proximity). **Friendship grants metadata markers only** (e.g. a friend's marker when
visible), **never raw in-world avatar or chat sight** — with one deliberate exception: an active
**Duo** lets its two partners always see each other (including on hidden tiles), and thus each
other's chat (chat inherits avatar visibility). This is the co-op carve-out. The whole thing is a
*new* system — legacy had no equivalent — and an intentional exception to ReBNO's otherwise
parity-first scope principle.

## Consequences

- The server performs **interest management**: it computes a per-recipient visibility set and
  filters position + chat broadcasts accordingly — not a single room-wide rebroadcast.
- **Contiguous-hidden-tile-body** membership becomes server-tracked state.
- **Chat routing is visibility-filtered** (can't see the avatar → don't receive the chat).
- **Markers are a separate, relationship-aware metadata channel**, decoupled from avatar streams.
- Higher server CPU + per-recipient payloads than legacy's blind rebroadcast — acceptable at the
  <50 CCU target.
- **Duo carve-out:** active Duo partners always see each other (including on hidden tiles either
  stands on) — the one relationship that overrides spatial visibility; the server enforces the
  pairing.

## Considered alternatives

- **Faithful client-relay (legacy model)** — rejected: client-authoritative, unenforceable, and
  contradicts CLAUDE.md Hard Rule 1.
- **Room-wide broadcast with client-side hiding** — rejected: leaks position/chat to the client
  and is trivially cheatable.

See `CONTEXT.md` → "Perception gating" for the living definition.
