Files
scrying-pool/_bmad-output/planning-artifacts/prds/prd-video-view-manager-2026-05-19/prd.md
T
2026-05-21 23:08:34 +02:00

544 lines
39 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Video View Manager — FoundryVTT Webcam Visibility Control Module"
status: final
created: 2026-05-19
updated: 2026-05-19
---
# PRD: Video View Manager
## 0. Document Purpose
This PRD is the authoritative specification for **Video View Manager**, a FoundryVTT v14 module. It is written for the module author (Morr) and future contributors, and it is the source of record for scope decisions during development.
This document uses Glossary terms from §3 throughout §4+ and keeps functional requirements globally numbered FR-1 through FR-26 for stable reference. Inline `[ASSUMPTION]` tags in §4 mark unconfirmed inferences and are indexed in §9. The primary upstream input is `_bmad-output/brainstorming/brainstorming-session-2026-05-19-221747.md`.
---
## 1. Vision
Video View Manager gives the GM granular, real-time control over webcam visibility in FoundryVTT v14. Its core value is simple: **the GM can hide or reveal any Participant's camera in one click, and every Viewer updates immediately.** Existing FoundryVTT AV controls do not provide this.
From that core, the module extends into session cinematography. Scene Presets let the GM configure camera states during prep and apply them on scene transitions. The Director's Board gives the GM bulk visibility control for larger groups. Contextual Notifications explain camera-state changes so feeds never disappear silently.
The module follows the **Progressive Enhancement Architecture**. Level 1 adds a right-click action to existing AV Tiles. Level 2 adds the Director's Board. Level 3 adds Scene Presets and automation. Participants stay informed, automation that changes an individual's on-screen presence requires explicit opt-in, and the GM always has an immediate override.
---
## 2. Target Users
### 2.1 Primary Personas
**Marcus — The Veteran GM**
Marcus runs a biweekly campaign with 6 players on FoundryVTT. He preps meticulously and wants zero friction during play. He wants camera automation he can configure once, not an interface he must reopen mid-session. Every automation needs an obvious one-click override. He will use Scene Presets and the Director's Board extensively.
**Sofia — The Privacy-Conscious Player**
Sofia joins two games a week. She has a home office setup and is comfortable on camera, but she does not want her face spotlighted unexpectedly during a dramatic moment she did not choose. She needs to know what state her feed is in at all times, and she expects a way to opt out of any effect that touches her camera automatically.
**Jake — The Actual-Play Streamer**
Jake runs a public streamed game. He needs complete independence between what his players see and what his stream audience sees. Keyboard shortcuts are essential during live broadcast. He sees the Browser Source API and Spectator View (Later roadmap) as the features that turn this module into a production stack.
**Alex — The New Player**
Alex has just joined their first online TTRPG. They are comfortable with Zoom but have never used FoundryVTT. They need the interface to use plain language ("Show" / "Hide") rather than technical vocabulary, toast notifications that explain what is happening, and a Portrait Fallback if their camera fails.
### 2.2 Jobs to Be Done
**Functional**
- Hide a distracting Participant's video feed without removing them from the session
- Spotlight one Participant for a dramatic reveal or emotional scene climax
- Apply a Scene Preset when transitioning between scenes without manual intervention
- Know at a glance which of 6+ Participants are hidden, visible, or offline
**Social / Emotional**
- Feel in control of the table atmosphere as a GM — the visual equivalent of adjusting the lights
- Trust that no Participant is hidden without knowing it (Participant transparency)
- Participate fully in the session even when camera equipment fails (Portrait Fallback, Reaction Clip System)
### 2.3 Non-Users (v1.0)
- Solo FoundryVTT users with no AV participants
- Groups using FoundryVTT v13 or earlier
- Streamers requiring independent audience layouts (served in the later roadmap — §10)
### 2.4 Key User Journeys
**UJ-1. Marcus transitions into a boss fight and spotlights the villain's lair.**
- **Persona + context:** Marcus, mid-session, activating a Scene named "Throne Room" where he wants only two Participants visible.
- **Entry state:** A Scene Preset is configured at prep time; the Director's Board is closed.
- **Path:** (1) Marcus activates the "Throne Room" scene. (2) The module auto-applies the saved preset — two Participants are visible and four are hidden. (3) A toast appears for all Participants: "Scene changed: camera layout updated." (4) Marcus glances at the AV Tile strip — hidden tiles show a grey overlay with a lock icon.
- **Climax:** The table's visual focus narrows to the two Participants in the scene without Marcus touching a control.
- **Resolution:** Marcus keeps narrating; he can override the preset with one right-click if needed.
- **Edge case:** If a Participant whose feed should be visible is offline, the hidden overlay still appears and the preset is marked partially applied.
**UJ-2. Sofia opts out of HP-Reactive Cam Styling before the session.**
- **Persona + context:** Sofia, before the session starts, opening her FoundryVTT user settings.
- **Entry state:** Authenticated as a Participant; the Player Privacy Panel is available in module settings; HP-Reactive Cam Styling is currently ON from an earlier opt-in.
- **Path:** (1) Sofia opens the Player Privacy Panel. (2) She sees HP-Reactive Cam Styling: ON. (3) She toggles it OFF. (4) The setting saves instantly; no page reload is required.
- **Climax:** Sofia knows her camera will not change appearance based on her HP.
- **Resolution:** Her opt-out flag persists for future sessions in this world until she changes it.
**UJ-3. Jake opens the Director's Board at session start to configure the layout.**
- **Persona + context:** Jake, 5 minutes before going live, with 5 Participants connected.
- **Entry state:** Authenticated as GM; the Director's Board has not been opened this session.
- **Path:** (1) Jake presses the keyboard shortcut (⌘/Ctrl+Shift+V). (2) The Director's Board opens as a floating window. (3) Jake sees all 5 Participants in a seating-chart layout with their current states. (4) He sets Participant 4 to "Hidden" (late joiner, not on yet). (5) He uses Spotlight on his own card to confirm his feed remains visible.
- **Climax:** Jake's table is visually configured for broadcast before he goes live.
- **Resolution:** The Director's Board stays open in a corner, and Jake uses it as a live monitor during the session.
**UJ-4. Alex sees a toast notification when their feed is hidden.**
- **Persona + context:** Alex, playing for the first time; Marcus has just hidden Alex's camera to manage a technical glitch.
- **Entry state:** Alex's AV Tile is live; Marcus triggers hide from the context menu.
- **Path:** (1) Alex's tile changes to Portrait Fallback mode with a grey overlay. (2) Alex receives a toast: "GM has hidden your camera. Your portrait is shown to other Participants." (3) Alex sees a small "Camera hidden" badge on their own tile.
- **Climax:** Alex understands exactly what happened and why — no confusion or anxiety.
- **Resolution:** Alex can keep playing; their audio is unaffected.
---
## 3. Glossary
- **AV Tile** — The FoundryVTT UI element that renders a Participant's audio/video feed. The primary surface for right-click interactions in Level 1 of the Progressive Enhancement Architecture.
- **Browser Source API** — A Later-roadmap streaming interface that exposes camera-layout outputs for external broadcast tooling such as OBS.
- **Combat Cinematics Mode** — An automation mode that manages the Visibility Matrix during active FoundryVTT combat, spotlighting the active combatant's feed. Part of the Later roadmap.
- **Director's Board** — The floating window for bulk Visibility Matrix management. Primary UI surface for Level 2/3 interactions. Synonyms are not permitted — this is not "the settings panel" or "the popout."
- **Director's Board Stage Lighting States** — A Later-roadmap preset vocabulary tier for cinematic bulk actions such as Wash, Focus, and Blackout.
- **Dual Layout System** — A Later-roadmap architecture that separates the Participant-facing layout from the Spectator View.
- **GM** — Game Master. The FoundryVTT user with the `GAMEMASTER` role. Has exclusive authority over the Visibility Matrix unless Player Permissions are extended (future roadmap).
- **HP-Reactive Cam Styling** — An opt-in automation effect that changes the presentation of a Participant's feed based on HP-related game events. Part of the Later roadmap.
- **NPC Presence Tiles** — A Later-roadmap feature that displays static image tiles for NPC voice actors or other non-camera presences.
- **Participant** — Any connected FoundryVTT user with an AV presence (camera, microphone, or both), including the GM.
- **Participant State** — One of eight enumerated states describing a Participant's AV presence: `active`, `hidden`, `self-muted`, `offline`, `cam-lost`, `reconnecting`, `never-connected`, `ghost`. Defined in §4.1.
- **Player Privacy Panel** — The per-user settings interface for opting in or out of cinematic automation effects. Scoped to the current user; accessible from module settings.
- **Portrait Fallback** — A static image (user avatar or actor portrait) displayed in place of a live camera feed when a Participant has no camera, or when their feed is `cam-lost`.
- **Progressive Enhancement Architecture** — The three-level UI model: Level 1 (right-click on existing AV Tiles — zero new UI), Level 2 (Director's Board), Level 3 (Scene Presets + full automation). Each level is independently useful.
- **Pull Visibility Model** — A Later-roadmap visibility model in which feeds remain hidden until a Viewer explicitly requests them.
- **Reaction Cam** — An opt-in feature that automatically spotlights a Participant's feed during key game moments (for example, taking damage in combat). Part of the Later roadmap.
- **Reaction Clip System** — A Later-roadmap fallback that shows a short video snippet when a Participant has no live camera feed.
- **Scene Preset** — A saved snapshot of the Visibility Matrix, optionally linked to a FoundryVTT Scene for automatic application on scene activation.
- **Spectator View** — A read-only camera layout independent from the Participant layout, intended for streaming audiences. Part of the Later roadmap.
- **The Living Table** — A Later-roadmap concept that exposes the full seating-chart UI for `Map<participantId, Map<viewerId, VisibilityState>>` relationships.
- **Token-Anchored Floating Cams** — A Later-roadmap feature that links camera surfaces to canvas tokens.
- **Visibility Matrix** — The authoritative data structure representing all camera visibility relationships: `Map<participantId, Map<viewerId, VisibilityState>>`. Stored in world-level settings and broadcast to all clients on change.
- **Zero-UI Full Automation Mode** — A Later-roadmap mode that minimizes manual camera control after initial configuration.
- **Visibility State** — The visibility setting for one Participant's camera as seen by one Viewer. Distinct from Participant State: a feed can be `active` but have a `hidden` Visibility State for specific viewers.
- **Viewer** — A Participant who is receiving (watching) another Participant's camera feed.
---
## 4. Features
### 4.1 Core Visibility Toggle
**Description:** The North Star feature. The GM right-clicks any AV Tile to toggle that Participant's visibility for all Viewers. The change broadcasts to all connected clients, persists across reconnections, and updates the AV Tile with a clear indicator explaining *why* the feed is in its current state. All eight Participant States render without layout disruption. Realizes UJ-1, UJ-4.
This feature implements **Level 1** of the Progressive Enhancement Architecture. It adds no new UI beyond a context-menu action on existing AV Tiles.
**Participant States (FR-5):**
| State | Description |
|---|---|
| `active` | Camera on; feed visible to permitted Viewers |
| `hidden` | Camera on; GM has set Visibility State to hidden |
| `self-muted` | Participant voluntarily turned off their own camera |
| `offline` | Participant's connection dropped entirely |
| `cam-lost` | Participant connected but camera device failed |
| `reconnecting` | Transitional; feed is expected to return |
| `never-connected` | Participant joined with no camera device |
| `ghost` | GM observing silently (no AV presence broadcast) |
**Functional Requirements:**
#### FR-1: GM toggles Participant visibility via right-click
The GM can hide or show any Participant's camera feed by right-clicking their AV Tile and selecting "Hide Camera" / "Show Camera." Realizes UJ-1, UJ-4.
**Consequences (testable):**
- Selecting "Hide Camera" sets the target Participant's Visibility State to `hidden` for all Viewers.
- Selecting "Show Camera" sets the target Participant's Visibility State to `active` for all Viewers.
- The AV Tile indicator updates on all connected clients within 500 ms.
- The context-menu entry appears on all AV Tiles when the user is logged in as GM.
**Out of Scope:** Asymmetric visibility (hiding from specific Viewers only) — deferred to Later roadmap.
#### FR-2: Visibility state broadcast via socket
All Visibility Matrix changes are broadcast to all connected clients in real time.
**Consequences (testable):**
- A client that joins mid-session receives the current Visibility Matrix on connection.
- State-change latency from GM action to all-client update stays at or below 500 ms on a local network.
- The module uses the native FoundryVTT socket API through a registered module event (for example, `module.video-view-manager.visibilityUpdate`).
#### FR-3: Visibility state persistence
Visibility Matrix state persists in world-level settings across page refreshes and session breaks.
**Consequences (testable):**
- A Participant who disconnects and reconnects returns to the previously set Visibility State.
- The saved state survives a full FoundryVTT server restart.
- A new Participant defaults to `active` on first connection to the world [ASSUMPTION].
#### FR-4: AV Tile visual indicator for Participant State
Each AV Tile displays a state indicator that distinguishes all relevant Participant States by using plain language and an icon. Realizes UJ-4.
**Consequences (testable):**
- `hidden` state renders a grey overlay, a lock icon, and the tooltip "Camera hidden by GM."
- `self-muted` state renders a camera-off icon distinct from the lock icon.
- `offline` state renders a disconnection icon and the tooltip "Participant offline."
- `cam-lost` state renders a camera-error icon and the tooltip "Camera unavailable."
- `reconnecting` state renders a spinner icon.
- All icons come from the FoundryVTT icon library; the module adds no external dependency.
#### FR-5: Eight Participant States rendered without layout disruption
All Participant States produce appropriate visual feedback and do not cause AV Tile reflow or layout shift for other Participants.
**Consequences (testable):**
- Hiding or revealing a Participant's feed does not change the position of other AV Tiles.
- Mid-combat state transitions (`active``offline``reconnecting`) do not shift the combat tracker or map canvas layout.
- A Participant in `ghost` state has no AV Tile rendered for other Participants.
#### FR-6: GM sees all activated Participant feeds; GM self-view is configurable
The GM always sees all activated Participant feeds regardless of Visibility State. The GM's own feed in their own view can be toggled in a module setting.
**Consequences (testable):**
- Hidden tiles in the GM's view render at reduced opacity with a lock icon overlay.
- The GM hears audio from all Participants regardless of Visibility State.
- The module setting "Show my own feed to myself" (default: ON) controls whether the GM's own AV Tile appears in the GM's interface.
- Other Participants do not render hidden feeds.
#### FR-7: WebRTC track disabling with CSS fallback
Real WebRTC track disabling is the preferred implementation when the FoundryVTT v14 API allows programmatic track access. CSS/DOM cosmetic hiding is the fallback.
**Consequences (testable):**
- When WebRTC track disabling is active, a hidden feed does not consume inbound video bandwidth on the receiving client.
- A world setting reports which mode is active: WebRTC track disabling or CSS fallback.
- [ASSUMPTION: FoundryVTT v14's `game.webrtc` exposes RTCPeerConnection access sufficient for track disabling; see OQ-1.]
**Out of Scope:** Audio track manipulation — this module manages video visibility only. Audio muting remains native FoundryVTT functionality.
#### FR-8: Portrait Fallback for no-camera Participants
When a Participant has no camera device (`never-connected`) or enters `cam-lost` state, their AV Tile displays a Portrait Fallback image.
**Consequences (testable):**
- The default Portrait Fallback uses the FoundryVTT user avatar and falls back to a system placeholder if no avatar is set.
- Participants can set a custom Portrait Fallback through the Player Privacy Panel (FR-26).
- Portrait Fallback renders at the same dimensions as a live camera-feed tile.
**Feature-specific NFRs:**
- Visibility Matrix updates must not block the FoundryVTT rendering loop; state changes apply asynchronously.
- The module must not interfere with FoundryVTT's native AV mute/unmute controls.
---
### 4.2 Director's Board
**Description:** The Director's Board is a floating window for bulk Visibility Matrix management in sessions with 4+ Participants. It is **Level 2** of the Progressive Enhancement Architecture. The seating-chart layout matches how TTRPG groups visualize the table. Realizes UJ-3.
**Functional Requirements:**
#### FR-9: GM opens Director's Board via sidebar button and keyboard shortcut
A dedicated button in the FoundryVTT controls sidebar opens the Director's Board. A keyboard shortcut (default: `Ctrl+Shift+V`) also opens it. Realizes UJ-3.
**Consequences (testable):**
- The Director's Board opens as a resizable, draggable `ApplicationV2` window [ASSUMPTION].
- Opening the Director's Board does not change the existing AV Tile strip.
- The keyboard shortcut is configurable in module settings.
- The window closes and reopens instantly, supporting both a pre-session setup workflow and a live-monitor workflow.
#### FR-10: Director's Board displays full Visibility Matrix in seating-chart layout
All connected Participants are shown with their current Visibility State, name, and portrait.
**Consequences (testable):**
- Every Participant card displays the name, portrait, current Participant State, and current Visibility State.
- The layout reads as a seating chart, not a list.
- Updates to Visibility State appear in the Director's Board within 500 ms, matching FR-2.
#### FR-11: Per-Participant visibility toggle from Director's Board
The GM can toggle any single Participant's Visibility State from that Participant's card in the Director's Board.
**Consequences (testable):**
- The action matches FR-1 for behavior and persistence.
- The GM toggles a Participant with a single click on that Participant card.
#### FR-12: Bulk actions — Show All and Hide All
Two bulk-action buttons apply Show or Hide to all Participants simultaneously.
**Consequences (testable):**
- "Show All" sets every eligible Participant Visibility State to `active`.
- "Hide All" sets every eligible Participant Visibility State to `hidden`.
- A one-step "Undo" action restores the Visibility Matrix state that existed immediately before the bulk action.
- Participants in `ghost` state are excluded from bulk actions.
#### FR-13: Spotlight action on a single Participant
"Spotlight" shows exactly one Participant's feed and hides all others in a single action.
**Consequences (testable):**
- Spotlight stores the current Visibility Matrix as a pre-spotlight snapshot.
- A "Restore" action reverts to that pre-spotlight snapshot.
- Spotlight remains distinct from a manual Hide All plus Show One sequence: one dedicated action and one undo step.
#### FR-14: Keyboard shortcuts for Director's Board actions
All primary Director's Board actions are accessible without a mouse. Realizes UJ-3.
**Consequences (testable):**
- `Space` or `Enter` toggles the focused Participant.
- Arrow keys move focus between Participant cards.
- `Ctrl+Shift+S` runs Show All, `Ctrl+Shift+H` runs Hide All, and `Ctrl+Shift+P` spotlights the focused Participant.
- The `?` key opens a shortcut reference panel within the Director's Board.
- All shortcuts are configurable and documented in module settings.
---
### 4.3 Scene-Aware Visibility Presets
**Description:** Scene Presets are saved Visibility Matrix configurations that can be applied manually or automatically when a FoundryVTT Scene activates. This is **Level 3** of the Progressive Enhancement Architecture: configure during prep, then use during play. Realizes UJ-1.
**Functional Requirements:**
#### FR-15: GM saves a named Scene Preset from the current Visibility Matrix
Any current Visibility Matrix state can be saved as a named preset with a single action from the Director's Board or module settings.
**Consequences (testable):**
- The preset captures the full current Visibility Matrix at save time.
- The preset name is editable, and names remain unique within a world.
- Up to 50 presets can be stored in world settings [ASSUMPTION: adequate for any campaign].
#### FR-16: GM loads a Scene Preset at any time
Applying a preset overrides the current Visibility Matrix.
**Consequences (testable):**
- All clients receive the preset state within 500 ms through the same path as FR-2.
- Loading a preset generates the Contextual Notification defined in FR-20: "GM applied preset: [Preset Name]."
- The preset applies regardless of which Participants are online; offline Participants receive the stored state on reconnection under FR-3.
#### FR-17: Scene Preset auto-applies on FoundryVTT Scene activation
A preset can be linked to a Scene; it applies automatically when that Scene is activated.
**Consequences (testable):**
- The Scene-to-Preset association is configured in Scene settings or module settings.
- Auto-apply fires on the `updateScene` hook, and a configurable 05000 ms pre-delay supports dramatic transitions [ASSUMPTION: sufficient hook timing — to be verified during FR-17 development].
- All clients receive the notification "Scene changed: camera layout updated." matching UJ-1.
#### FR-18: Scene Preset auto-apply can be disabled per scene or globally
GMs retain full manual override.
**Consequences (testable):**
- A per-scene toggle disables auto-apply for that Scene without removing the association.
- A global "Disable All Auto-Apply" toggle in module settings overrides all per-Scene configurations.
- The Director's Board always provides a manual override during play, regardless of automation state.
#### FR-19: Preset import/export as JSON
Presets can be exported to and imported from a JSON file.
**Consequences (testable):**
- Export writes all presets to one human-readable JSON file that the browser downloads.
- Import reads a JSON file and merges or replaces existing presets, based on user choice; invalid JSON shows an error.
- The module README documents the exported JSON format for community sharing.
---
### 4.4 Contextual Notifications
**Description:** Contextual Notifications use plain-language toasts to inform Participants when camera states change. They prevent silent surprises, and notification verbosity is configurable. Realizes UJ-4.
**Functional Requirements:**
#### FR-20: Toast notification on GM visibility change
When the GM changes any Participant's Visibility State, all Participants receive a toast notification in plain language.
**Consequences (testable):**
- The message uses the Participant display name: "GM hid [Name]'s camera" or "GM showed [Name]'s camera."
- The toast uses FoundryVTT's native notification UI.
- The affected Participant receives a distinct personal notification: "GM has hidden your camera. Your portrait is shown to other Participants."
#### FR-21: Notification verbosity configuration
Notification output is configurable per user.
**Consequences (testable):**
- Three modes are available: `All` (default), `GM Only`, and `Silent`.
- The configuration is stored in user-level client settings, not world settings.
- `Silent` mode still shows the personal notification to the affected Participant; the GM cannot suppress the FR-20 personal message.
#### FR-22: Persistent feed status indicator on own AV Tile
Each Participant always sees the current state of their own feed through a persistent status badge on their own AV Tile.
**Consequences (testable):**
- The badge shows one of these states: "Live," "Hidden by GM," "Muted," or "No Camera."
- The badge updates within 500 ms when the state changes.
- Only the owning Participant sees the badge; other Participants do not see badges on other AV Tiles.
---
### 4.5 Player Privacy Panel
**Description:** The Player Privacy Panel contains per-user settings for consenting to, or withdrawing consent from, cinematic automation effects that touch individual Participants. Design principle: **automation effects that touch a Participant's on-screen presence require explicit opt-in and remain off by default.** The GM retains unconditional hide/show authority under FR-1. Automation that auto-spotlights or visually modifies a Participant remains opt-in by user choice. Realizes UJ-2.
**Functional Requirements:**
#### FR-23: Player Privacy Panel accessible from module settings
Each user can open their Player Privacy Panel from the module settings tab in FoundryVTT.
**Consequences (testable):**
- The panel lists every automation effect that can touch the owning user, along with the current opt-in status.
- The owning user can edit the panel; the GM can view but not edit another Participant's panel settings.
- The settings persist in world-level user flags.
#### FR-24: Opt-in to Reaction Cam automation
A Participant must explicitly opt in before Reaction Cam (Later roadmap) can auto-spotlight them. The default is **off**.
**Consequences (testable):**
- Reaction Cam remains disabled for a Participant unless that Participant explicitly enables it in the Player Privacy Panel.
- The Director's Board displays a "Reaction Cam: Enabled" badge on opted-in Participant cards; no badge means off.
- The opt-in flag persists across sessions until the user changes it.
- Combat Cinematics Mode and any other Reaction Cam trigger respect this flag; they skip opted-out Participants silently.
#### FR-25: Opt-in to HP-Reactive Cam Styling
A Participant must explicitly opt in before HP-Reactive Cam Styling (Later roadmap) applies to their feed. The default is **off**.
**Consequences (testable):**
- HP-Reactive Cam Styling remains disabled for a Participant unless that Participant explicitly enables it.
- The GM is not notified of individual styling opt-in statuses; this preference remains private.
#### FR-26: Custom Portrait Fallback
A Participant can set a custom image as their Portrait Fallback (used in FR-8 when the camera is unavailable).
**Consequences (testable):**
- A file picker in the Player Privacy Panel sets the custom portrait.
- Accepted formats are PNG, JPG, WEBP, and static GIF.
- The image falls back to the FoundryVTT user avatar if no custom portrait is set, then to the system placeholder if no avatar exists.
---
## 5. Non-Goals (Explicit)
- **Not an AV transport layer.** This module does not host, relay, or record audio/video streams. FoundryVTT's native WebRTC / AV stack handles all transport.
- **No audio control.** The module manages video visibility only. Muting audio remains native FoundryVTT functionality.
- **No recording or archiving.** No session video capture or replay features in v1.0.
- **FoundryVTT v13 and earlier are not supported.** v14 is the minimum compatibility floor; no backport is planned.
- **No central preset registry.** Community preset sharing is a local JSON export/import workflow only. No cloud or server-side storage.
- **No AI-driven visibility decisions.** All visibility changes are GM-initiated or rule-based (Scene Preset auto-apply). No ML or heuristic automation.
- **No asymmetric per-Viewer visibility (v1.0).** The Visibility Matrix is GM-to-everyone in v1.0; the full `Map<participantId, Map<viewerId, VisibilityState>>` model is architecturally supported but is not exposed in the UI until the Later roadmap.
- **No third-party streaming platform integration.** No OBS, Twitch, or YouTube API in v1.0. Browser Source API is a Later roadmap item.
- **Native WebRTC AV backend only (v1.0).** The module operates exclusively with FoundryVTT's built-in WebRTC stack. Jitsi Meeting Server and other third-party AV backends are not supported in v1.0; they are deferred to the Later roadmap.
---
## 6. MVP Scope
### 6.1 In Scope (v1.0)
- Core Visibility Toggle (FR-1 FR-8): right-click toggle, broadcast, persistence, visual indicators, 8 Participant States, WebRTC track disabling with CSS fallback, Portrait Fallback
- Director's Board (FR-9 FR-14): seating-chart window, bulk actions, Spotlight, keyboard shortcuts
- Scene-Aware Visibility Presets (FR-15 FR-19): save, load, auto-apply, and JSON import/export
- Contextual Notifications (FR-20 FR-22): toast system, verbosity configuration, persistent self-status badge
- Player Privacy Panel (FR-23 FR-26): opt-in controls for future automation effects, custom portrait
- FoundryVTT v14+ compatibility; `module.json` per v14 manifest schema
- English UI strings; i18n-ready string keys for community translation
### 6.2 Out of Scope for MVP
- Combat Cinematics Mode (auto-spotlight active combatant) — deferred to Later; see §10. `[NOTE FOR PM: This is emotionally load-bearing for Marcus-persona GMs. Consider as v1.1 if Day 1 ship goes smoothly.]`
- Reaction Cam (auto-spotlight on damage/dramatic event) — deferred to Later; see §10
- Director's Board Stage Lighting States (Wash / Focus / Blackout presets) — deferred to Later
- Token-Anchored Floating Cams — deferred to Later; requires deep canvas integration
- HP-Reactive Cam Styling — deferred to Later
- Spectator View / Dual Layout System — deferred to Later
- Browser Source API (OBS-ready tile URLs) — deferred to Later
- NPC Presence Tiles — deferred to Later
- Zero-UI Full Automation Mode — deferred to Later
- Pull Visibility Model (opt-in to see feeds) — deferred to Later
- Reaction Clip System (video snippet fallback for no-camera Participants) — deferred to Later
- Full asymmetric per-Viewer visibility in the Director's Board — deferred to Later
- FoundryVTT v13 compatibility backport — will not build
---
## 7. Success Metrics
**Primary**
- **SM-1: Installation count** — 500 installs within 90 days of Foundry Hub listing. Validates FR-1 through FR-8 (broad appeal of the core feature).
- **SM-2: Weekly active worlds** — ≥30% of installing worlds use the module in at least one session per week after the first week. Validates overall module stickiness across all v1.0 features.
**Secondary**
- **SM-3: Core toggle regression-free** — Zero bug reports for FR-1 through FR-4 (basic toggle + persistence) in the first 30 days. Validates Day 1 reliability.
- **SM-4: Open P1 bug count** — No more than 3 open P1 bugs at any point in the first 90 days. Validates overall module quality.
- **SM-5: State-persistence failures** — Zero user-reported Visibility State loss across reconnection (FR-3) after 30 days.
**Counter-metrics (do not optimize)**
- **SM-C1: Feature depth penetration** — Do not optimize for users enabling every feature. The module is successful if most users remain at Level 1 (right-click only) and only power users reach Level 3 (Scene Presets + Director's Board). Depth adoption is a health signal, not the goal. Counterbalances SM-1 and SM-2.
- **SM-C2: Notification frequency** — Do not make toast notifications more prominent, frequent, or verbose. FR-20 notifications exist to remove confusion, not to draw attention. Counterbalances SM-3.
---
## 8. Open Questions
1. **OQ-1:** Does FoundryVTT v14's `game.webrtc` / `AVMaster` API expose a programmatic method for disabling a specific peer's incoming video track (RTCPeerConnection track manipulation), or must the module hook at a lower level? To be resolved by inspecting the v14 AV API during development. FR-7 CSS fallback is the safe default until confirmed.
2. ~~**OQ-2 (Phase blocker):** Is `socketlib` the recommended socket broadcast approach for v14, or does FoundryVTT v14 expose a sufficient native socket API?~~ **RESOLVED:** Native FoundryVTT socket API will be used. `socketlib` dependency will not be added.
3. ~~**OQ-3:** What is the intended behavior when the GM's own feed is set to `hidden` — should the GM see their own feed in their view unchanged, or see the hidden state overlay like other GMs would?~~ **RESOLVED:** The GM always sees all activated Participant feeds. The GM's own feed visibility in their own view is a configurable option (show/hide self-view).
4. ~~**OQ-4:** Should the module operate with Jitsi Meeting Server and other non-native AV backends (beyond native WebRTC), or is native WebRTC the only supported backend for v1.0?~~ **RESOLVED:** Native WebRTC only for v1.0. Non-native backends (Jitsi, etc.) are deferred to the Later roadmap.
5. **OQ-5:** Do FoundryVTT v14 scene activation hooks fire early enough for Scene Preset auto-apply (FR-17) to avoid a visible flash of the wrong camera layout before the preset applies? Not a concern for the first implementation stage — defer to testing.
6. **OQ-6:** Should Scene Presets support partial application — applying only to currently connected Participants and deferring state for offline ones — or should they always apply to all participant slots unconditionally? This cannot be decided yet and will be resolved during FR-15/FR-16 implementation.
---
## 9. Assumptions Index
- **§4.1 / FR-3:** New Participants default to `active` Visibility State on first connection to a world. This is the socially safe default.
- **§4.1 / FR-7:** FoundryVTT v14's WebRTC implementation exposes RTCPeerConnection objects at a level accessible to a module, enabling programmatic track disabling without patching the core AV system.
- **§4.2 / FR-9:** FoundryVTT v14's `ApplicationV2` API is the correct pattern for a resizable floating window with persistent state.
- **§4.3 / FR-15:** 50 presets per world is an adequate upper bound for any campaign use case. If communities surface larger preset libraries, this can increase.
- **§4.3 / FR-17:** The `updateScene` hook (or its v14 equivalent) fires early enough in the scene-transition lifecycle to apply the preset before the AV Tile strip re-renders.
---
## 10. Product Roadmap (Later Features)
The following concepts from the brainstorming session are architecturally consistent with v1.0 but are deferred to keep the initial release focused. They are listed here to prevent scope creep in v1.0 tickets while preserving the broader product vision.
| Concept | Brainstorm ID | Theme | Notes |
|---|---|---|---|
| Combat Cinematics Mode | #4 | Automation | Auto-spotlight active combatant; requires Reaction Cam opt-in (FR-24) already in v1.0 |
| Reaction Cam | #5, #17 | Cinematic | Opt-in per FR-24; triggers from game events |
| Director's Board Stage Lighting States | #7 | Cinematic | Wash / Focus / Blackout vocabulary tier |
| Token-Anchored Floating Cams | #8 | Cinematic | Deep canvas integration; high complexity |
| HP-Reactive Cam Styling | #9 | Cinematic | Opt-in per FR-25 already scaffolded in v1.0 |
| NPC Presence Tiles | #10 | Extended Presence | Static image tiles for NPC voice actors |
| Spectator View | #11 | Streaming | Independent audience layout |
| Zero-UI Full Automation Mode | #12 | Automation | Full configure-once, no-touch operation |
| The Living Table (full seating chart) | #1 | Core Architecture | Full `Map<p, Map<v, State>>` UI exposure |
| Pull Visibility Model | #14 | Core Architecture | Nothing is visible until actively requested |
| Reaction Clip System | #15 | Privacy + Presence | Video snippet fallback for no-camera Participants |
| Dual Layout System + Browser Source API | #18, #19 | Streaming | OBS-ready tile URLs; production stack |
---
## Cross-Cutting NFRs
**Compatibility**
- The module must not conflict with other popular FoundryVTT modules (Monk's Hotbar, Token Action HUD, etc.) by patching shared DOM selectors or overriding core FoundryVTT hooks without proper chaining.
- All hooks must use FoundryVTT's `Hooks.on()` registration pattern, never `Hooks.once()` for persistent behavior.
**Performance**
- No Visibility Matrix operation should block the FoundryVTT main render loop.
- The Director's Board must render and become interactive within 1 second even with 12 Participants.
- Socket message payload for a Visibility Matrix update must be ≤ 4 KB.
**Reliability**
- If the socket broadcast fails because of a network interruption, the GM client retries up to 3 times before surfacing an error notification.
- The module must fail gracefully if `game.webrtc` is unavailable (for example, when AV is disabled); all UI elements are hidden or disabled rather than erroring.
**Privacy**
- The module does not transmit any data outside the FoundryVTT world. No analytics, telemetry, or third-party calls.
- Participant names and portraits are used only within the FoundryVTT session; no external storage is allowed.
**Accessibility**
- All interactive elements in the Director's Board have ARIA labels and are keyboard navigable (FR-14).
- State-indicator icons (FR-4) include tooltip text for screen-reader compatibility.
**Language and Voice**
- Default UI labels use plain language: "Show," "Hide," "Spotlight," "Hidden by GM," "No Camera." Technical or cinematic vocabulary (for example, "Visibility Matrix" or "Wash / Focus / Blackout") is reserved for documentation, tooltips in advanced mode, and developer-facing strings — never as primary interface labels.
- This two-tier vocabulary principle applies to all present and future features. Downstream contributors must follow the plain-language default; advanced or cinematic terms may appear only in optional advanced mode.
**GM Override Guarantee**
- Every automation feature — present (Scene Presets, FR-17/FR-18) and future (Combat Cinematics Mode, Reaction Cam, Zero-UI Full Automation Mode) — must expose an obvious one-click GM override that is accessible without opening configuration UI.
- The Director's Board "Hide All" action (FR-12) serves as the module's emergency path: the GM can silence all cameras in one click at any time, regardless of active automation state.
- This is a non-negotiable cross-cutting rule: no automation may be implemented if it cannot be interrupted or overridden immediately by the GM.
**Delivery Risk Note (v1.0 scope)**
- v1.0 intentionally combines the Day 1 core toggle (FR-1FR-8) with Week 12 enhancements (FR-9FR-26) into a single release. The brainstorming established Day 1 as a shippable standalone product; if delivery constraints arise, the Level 1 core toggle (FR-1FR-8) is the minimum shippable increment, and all higher-level features can shift to v1.1 without breaking the architecture.