# Product Requirements Document — HS_DollyCam ## 1. Product Overview HS_DollyCam is a cinematic camera dolly HUD for Second Life. It enables users to save camera presets, execute smooth moves between them, play automated playlists from notecards, and run continuous multi-waypoint tours with spline interpolation. ## 2. Functional Requirements ### 2.1 Preset Management | ID | Requirement | Priority | |----|-------------|----------| | PR-01 | User can save the current camera position, focus, and FOV as a numbered preset (P1, P2, …) stored in Linkset Data | Must | | PR-02 | User can load a preset instantly (cut) or move to it smoothly with a configurable duration | Must | | PR-03 | User can delete a preset by index | Should | | PR-04 | User can list all saved presets with position/focus/FOV details | Should | | PR-05 | Preset format: `px|py|pz|fx|fy|fz|rx|ry|rz|rs|fovRad` (11 pipe-delimited fields) | Must | | PR-06 | In DEMO_MODE, saving is limited to `DEMO_MAX_SLOTS` (default 5) presets | Should | ### 2.2 Camera Movement | ID | Requirement | Priority | |----|-------------|----------| | PR-10 | `moveto [ms]` — smooth move to preset with duration | Must | | PR-11 | `load ` — instant cut to preset (zero-duration) | Must | | PR-12 | `cam on` / `cam off` — request/release camera control permission | Must | | PR-13 | HUD auto-hides during moves > 0ms to prevent flicker | Should | | PR-14 | Mutual exclusion: only one movement mode active at a time (move, tour, lock, follow) | Must | ### 2.3 Playlist Playback | ID | Requirement | Priority | |----|-------------|----------| | PR-20 | `play [gap_ms]` — reads inventory notecard line-by-line, executes commands | Must | | PR-21 | Supports commands: `moveto`, `goto`, `load`, `wait`, `tour ... endtour`, `dollyzoom`, `fov`, `lock`, `follow` | Must | | PR-22 | Uses `llGetNotecardLineSync` when simulator has notecard cached, falls back to `llGetNotecardLine` on `NAK` | Must | | PR-23 | Tour blocks (`tour [mode] endtour`) build a single continuous payload | Must | | PR-24 | Compact notecard tours (`tour [mode] `) skip multi-line reads for performance | Should | | PR-25 | Playlist chains moves on `MOVE_DONE` unless a `wait` line appears directly after a `moveto` (early cut) | Must | ### 2.4 Continuous Tour Engine | ID | Requirement | Priority | |----|-------------|----------| | PR-30 | `tour [mode] ...` — one-liner continuous tour across presets | Must | | PR-31 | Supports `linear` and `spline` (Catmull-Rom) interpolation modes | Must | | PR-32 | Implements trapezoidal motion profiles with configurable hold times per waypoint | Must | | PR-33 | Supports waypoint-specific weights and FOV ramps between waypoints | Should | | PR-34 | Throttles camera frame output to ~30Hz (`tour_cam_min_interval`) to prevent simulator saturation | Must | | PR-35 | Uses segment caching to avoid repeated `llList2Vector` lookups during timer playback | Must | | PR-36 | Supports `startfirst` mode flag to begin tour from first preset without current-camera-state roundtrip | Should | ### 2.5 Lock / Follow Modes | ID | Requirement | Priority | |----|-------------|----------| | PR-40 | `lock on [|uuid]` — locks camera to a target position or object | Should | | PR-41 | `follow on [uuid] [yaw|local|world] [transition_ms]` — follows a target with configurable coordinate frame | Should | | PR-42 | Lock and Follow are mutually exclusive (enabling one disables the other) | Must | | PR-43 | Follow/Lock state persists in Linkset Data across script resets | Should | ### 2.6 FOV Control | ID | Requirement | Priority | |----|-------------|----------| | PR-50 | `fov ` — sets viewer FOV via RLVa (auto-detects degrees if value > 3.2) | Should | | PR-51 | `fovdeg ` — sets viewer FOV explicitly in degrees (10–179) | Should | | PR-52 | FOV clamped to `RLV_FOV_MIN_DEG` (10°) and `RLV_FOV_MAX_DEG` (179°) | Must | | PR-53 | FOV changes require RLVa-enabled viewer; no-op if RLVa is disabled | Must | ### 2.7 Visual Markers | ID | Requirement | Priority | |----|-------------|----------| | PR-60 | `show cams [N]` — rezzes N marker pyramids at preset positions (max 30) | Should | | PR-61 | `hide cams` — removes all marker pyramids | Should | | PR-62 | Clicking a marker pyramid loads the corresponding preset and moves to it | Should | | PR-63 | Marker state (shown/hidden, count) persists in Linkset Data | Should | ### 2.8 Dialog Menu | ID | Requirement | Priority | |----|-------------|----------| | PR-70 | Touch menu provides buttons for Save, MoveTo, Load, Play, Tour, Follow, Lock workflows | Should | | PR-71 | Menu maintains page state and short UI lists (nearby avatars/objects, selected tour indices) | Should | | PR-72 | Menu paths are secondary to notecard playlist workflows | Should | ## 3. Non-Functional Requirements | ID | Requirement | |----|-------------| | NFR-01 | **Memory**: All scripts must operate within severe LSL memory constraints. Avoid `llParseString2List` in hot paths. Avoid mixed-type lists. | | NFR-02 | **Performance**: Tour engine timer hot path must maintain ≤30Hz output without simulator message saturation. | | NFR-03 | **Reliability**: Tour playback runtime lists must remain in script memory (not Linkset Data) to avoid per-tick read latency. | | NFR-04 | **Safety**: Camera permission denial must be handled gracefully with user-visible feedback. | | NFR-05 | **Single-prim**: Controller resides in ROOT prim; all data structures must fit within a single script's memory budget. | | NFR-06 | **Owner-only**: All commands must be restricted to the object owner (check `llGetOwnerKey`). | ## 4. Communication Protocol All inter-script communication uses `llMessageLinked` with the following channel ranges: | Range | Purpose | |-------|---------| | 1000–1099 | Engine commands (CE_CMD_*) | | 2000–2099 | Engine events (CE_EVT_*) | | 3000–3099 | Engine-to-core internal (CE_INT_*) | | 5000–5299 | Helper script channels (MC_CMD, MN_CMD) | | 5100–5199 | Marker script (MC_CMD, MC_EVT_*) | | 6100–6199 | Playlist commands (PH_CMD_*) | | 88 | Chat channel (CH) | | -880088 | Marker region channel (MARKER_CH) | ## 5. Acceptance Criteria - All preset save/load/delete/list operations work correctly via `/88` chat commands - Notecard playlist playback executes commands in sequence with proper wait/tour handling - Continuous tours play smoothly across waypoints with spline interpolation at ~30Hz - Lock/Follow modes maintain camera tracking on targets - FOV control works in RLVa-enabled viewers within clamped range - Visual markers rezz at preset positions and respond to clicks - HUD detaches cleanly: releases camera, hides markers, resets follow/lock state - No script exceeds memory budget under typical usage (12 presets, 20-waypoint tour)