2026-05-13 07:24:36 +02:00

11 KiB
Raw Permalink Blame History

Architecture — HS_DollyCam

System Overview

HS_DollyCam is a multi-script Second Life HUD system. The Controller resides in the ROOT prim of a single-prim HUD; all other scripts are linked children. Communication is exclusively via llMessageLinked with integer channel codes.

Component Diagram

┌─────────────────────────────────────────────────────────────┐
│  HS_CamController.lsl (ROOT)                                │
│  ┌───────────────────────────────────────────────────────┐  │
│  │  Chat parser (/88)  │  Preset manager  │  State mgmt │  │
│  └───────────────────────────────────────────────────────┘  │
│         │         │         │         │         │           │
│    ┌────┘         │         │         │         └────┐     │
│    ▼              ▼         ▼         ▼              ▼     │
│  ┌─────┐  ┌──────────┐  ┌────────┐  ┌────────┐  ┌──────┐  │
│  │ Menu │  │Playlist  │  │Engine  │  │Markers │  │ FOV  │  │
│  │      │  │          │  │Tour    │  │        │  │      │  │
│  └──┬───┘  └────┬─────┘  └───┬────┘  └───┬────┘  └──┬───┘  │
│     │            │            │            │           │      │
│     └            └            └            └           ┘      │
│                    ▼           ▼           ▼                   │
│           ┌─────────────────────────────────┐                 │
│           │  HS_CamEngineCore.lsl           │                 │
│           │  Camera permissions,            │                 │
│           │  llSetCameraParams,            │                 │
│           │  Follow/Lock math              │                 │
│           └──────────────┬──────────────────┘                 │
│                          │                                    │
│                   ┌──────┴──────┐                             │
│                   │  SL Viewer  │                             │
│                   │ (Camera)    │                             │
│                   └─────────────┘                             │
└─────────────────────────────────────────────────────────────┘

Component Details

1. HS_CamController.lsl (ROOT — Main Orchestrator)

Responsibility: Central command router and state coordinator.

Key responsibilities:

  • Chat command parsing on channel 88 (/88 help, /88 save, /88 load, /88 moveto, /88 tour, etc.)
  • Preset management via Linkset Data (P1, P2, … keys)
  • State persistence: Follow/Lock state, Marker visibility, Camera state
  • Routing all high-level commands to specialized helper scripts
  • Demo mode enforcement (DEMO_MAX_SLOTS)

Key constants:

  • CH = 88 — Chat channel
  • CE_CMD_* — Engine command channels (10001060)
  • CE_EVT_* — Engine event channels (20002060)
  • PH_CMD_* — Playlist command channels (61006104)
  • MC_CMD = 5100 — Marker command channel
  • MN_CMD = 5200 — Menu command channel

Notable patterns:

  • loadPreset(idx) — reads Linkset Data, extracts position/focus/FOV into temp globals
  • packPreset(pos, foc, rot, fovRad) — serializes camera state to pipe-delimited string
  • engineMove(pos, foc, durMs) — sends CE_CMD_MOVE to Engine, hides HUD during animated moves
  • phStop(reason) — forwards PH_CMD_STOP to all helpers

2. HS_CamPlaylist.lsl (Notecard-Driven Playlist Engine)

Responsibility: Asynchronous notecard reading and playlist execution.

Key responsibilities:

  • Reads playlist notecards line-by-line
  • Supports moveto, goto, load, wait, tour...endtour, dollyzoom, fov, lock, follow commands
  • Builds CE_CMD_TOUR payloads for tour blocks
  • Uses llGetNotecardLineSync with NAK fallback
  • Compact notecard tours avoid slow multi-line notecard reads

Memory optimization:

  • loadPreset() uses targeted field parsing (not full llParseString2List)
  • Tour blocks store indices first, load position/focus at endtour
  • Token helpers instead of full llParseString2List(line, [" "], [])

3. HS_CamTourCommands.lsl (Secondary Tour Command Helper)

Responsibility: Chat/menu one-shot tour builders.

Key responsibilities:

  • Handles /88 tour ..., /88 dollyzoom ..., menu TOURRUN payloads
  • Builds CE_CMD_TOUR payloads without adding memory pressure to Playlist
  • Targeted preset parsing for position/focus/FOV fields

Design principle: Keep heavy tour parsing out of Playlist; this script absorbs the memory cost.

4. HS_CamEngineTour.lsl (Continuous Tour Runtime)

Responsibility: High-frequency multi-waypoint camera tour playback.

Key responsibilities:

  • Receives CE_CMD_TOUR from Playlist and TourCommands
  • Requests current camera state from Core via CE_CMD_GET_STATE
  • Builds runtime lists: positions, focuses, holds, weights, segment lengths, cumulative lengths, point times
  • Drives camera via CE_INT_SET_CAM to EngineCore
  • Implements Catmull-Rom spline interpolation and trapezoidal motion profiles
  • Throttled camera-frame sending via tourSendCam() at ~30Hz

Memory-critical decisions:

  • Active tour lists stay in script memory (never Linkset Data)
  • Segment caching reduces repeated llList2Vector access
  • CE_CMD_TOUR payload parsed with targeted pipe-field helpers

5. HS_CamEngineCore.lsl (Camera Engine Core)

Responsibility: Low-level camera interface to Second Life viewer.

Key responsibilities:

  • Camera permissions (PERMISSION_CONTROL_CAMERA, PERMISSION_TRACK_CAMERA)
  • Executes llSetCameraParams for all camera movement
  • Follow mode math (World/Local/Yaw coordinate frames)
  • Lock mode math (tracks target position)
  • Configuration dump consumed by Playlist and TourEngine

Hot path: CE_INT_SET_CAM parsing uses direct separator lookup (no llParseString2List).

Tour-related config keys:

  • tour_max_points=20 — Max waypoints per segment
  • tour_cam_min_interval=0.033 — ~30Hz camera update cap
  • tour_pos_epsilon=0.005 — Position change threshold
  • tour_focus_epsilon=0.005 — Focus change threshold

6. HS_CamMenu.lsl (Dialog Menu / UI)

Responsibility: Touch-based dialog menus and UI command dispatch.

Key responsibilities:

  • Dialog menus with page state
  • Menu-driven tour building
  • Nearby target lists (avatars/objects)
  • UI command dispatch via MN_CMD to Controller

Design note: Menu paths are secondary to notecard playlist workflows.

7. HS_CamMarkers.lsl (Visual Marker Helper)

Responsibility: Rez marker pyramids at preset positions.

Key responsibilities:

  • Rezzes HS_CamMarker objects at preset positions
  • Uses MARKER_CH = -880088 region channel
  • Uses llRegionSayTo for marker communication when keys are known
  • Mixed marker list (known to be less memory-efficient, but marker use is rare)

8. HS_CamFov.lsl (FOV Controller)

Responsibility: Field of View adjustments and FOV state synchronization.

Key responsibilities:

  • FOV clamping (RLV_FOV_MIN_DEG=10, RLV_FOV_MAX_DEG=179)
  • FOV state sync across scripts
  • RLVa integration

Data Flow

Preset Save Flow

User: /88 save 3
  → Controller: requests camera state from Core (CE_CMD_GET_STATE)
  ← Core: returns current pos/focus/rot (CE_EVT_STATE)
  → Controller: packs preset, writes to Linkset Data (P3)
  ← Controller: confirms save to user

Smooth Move Flow

User: /88 moveto 5 2500
  → Controller: phStop() (stops any active playlist/tour)
  → Controller: engineMove(<pos5>, <foc5>, 2500)
  ← EngineCore: camera permission (if needed)
  → EngineCore: llSetCameraParams (smooth interpolation)
  ← EngineCore: CE_EVT_MOVE_DONE when complete
  → Controller: hudShow()

Continuous Tour Flow

User: /88 tour 10000 spline 1 3 5 7
  → Controller: phChatTour(msg)
  → TourCommands: builds CE_CMD_TOUR payload
  ← TourCommands: sends CE_CMD_TOUR to TourEngine
  → TourEngine: requests current state from Core
  ← TourEngine: builds runtime lists (positions, focuses, holds, segments)
  → TourEngine: CE_INT_SET_CAM frames @ ~30Hz
  ← EngineCore: llSetCameraParams (continuous drive)
  ← TourEngine: CE_INT_TOUR_BEGIN / CE_INT_TOUR_END

Notecard Playlist Flow

User: /88 play MyTour
  → Controller: phPlay("MyTour", 0)
  → Playlist: reads notecard line-by-line
  ← Playlist: executes moveto/goto/load/wait commands
  ← Playlist: builds tour blocks, sends CE_CMD_TOUR to TourEngine
  ← TourEngine: drives continuous tour
  ← Playlist: chains next command on MOVE_DONE

Linkset Data Keys

Key Format Purpose
P1P999 `px py
HS_CAMS `shown N`
HS_FOLLOW `on uuid`
HS_LOCK `on arg`

Communication Channel Map

Prefix Range Direction Purpose
CE_CMD_ 10001060 Ctrl→Core, Playlist, TourEngine Engine commands
CE_EVT_ 20002060 Core→Ctrl, Playlist Engine events
CE_INT_ 30003003 TourEngine→Core Internal engine ops
PH_CMD_ 61006104 Ctrl→Playlist, TourCommands Playlist commands
MC_CMD 5100 Ctrl→Markers Marker commands
MC_EVT_* 5101 Markers→Ctrl Marker events
MN_CMD 5200 Menu→Ctrl Menu commands
CH 88 User→Ctrl Chat commands
MARKER_CH -880088 Markers→Region Marker region say

Memory Architecture Principles

  1. Hot paths are timer-driven or high-frequency link_messageCE_INT_SET_CAM in EngineCore, tour playback in TourEngine
  2. No llParseString2List in hot paths — Use llSubStringIndex for separator lookup, llGetSubString for field extraction
  3. Runtime data in script memory, not Linkset Data — Tour lists are read every timer tick; Linkset Data reads add latency
  4. Short-lived data patterns — Tour blocks store indices, load position/focus at endtour, build final payload directly
  5. Mixed-type lists are expensive — Avoid in all scripts; use parallel single-type lists instead