HSDollyCam/AGENTS.md
mita 31443b091f Add user manual for HS DollyCam and FOV extension; introduce project context for AI agents
- Created HS DollyCam HUD user manual (v1.3.0) detailing features, setup, commands, and troubleshooting.
- Added FOV extension manual outlining FOV commands, usage in playlists, and dollyzoom functionality.
- Introduced project context file for AI agents, specifying technology stack, critical implementation rules, and existing patterns.
2026-05-07 06:10:45 +02:00

9.9 KiB

HS_DollyCam Project Information

This repository contains LSL (Linden Scripting Language) scripts for HS_DollyCam, a professional camera control system for Second Life.

The project is highly memory-sensitive. LSL script memory is limited, and large lists, mixed-type lists, and repeated string splitting can create avoidable memory pressure. Prefer targeted parsing and short-lived data where practical.

Core Components

The system is split across specialized scripts that communicate mostly via llMessageLinked.

1. HS_CamController.lsl (Main Controller)

The central command and state coordinator.

  • Handles chat commands and menu commands.
  • Coordinates playlist, menu, marker, FOV, and engine scripts.
  • Saves presets into Linkset Data.
  • Handles marker click events and forwards camera movement requests.
  • Maintains FOLLOW and LOCK state in Linkset Data.

Important note: movement math and continuous tour playback are not owned entirely by the Controller anymore. Controller dispatches movement/tour commands to helper scripts and engine scripts.

2. HS_CamPlaylist.lsl (Playlist Manager)

Primary script for notecard-driven workflows.

  • Reads playlist notecards line by line.
  • Uses llGetNotecardLineSync when the simulator has the notecard cached, with fallback to llGetNotecardLine on NAK.
  • Handles moveto, goto, load, wait, tour ... endtour, dollyzoom, fov, lock, follow, and marker show/hide commands.
  • Builds tour payloads and sends them to HS_CamEngineTour.lsl via CE_CMD_TOUR.
  • For notecard tour blocks, the builder stores preset indices, holds, and weights, then loads position/focus only at endtour.
  • Also supports compact notecard tours (tour <ms> [mode] <idx...>) to avoid slow multi-line notecard reads when no holds/weights are needed.
  • Compact notecard tours add an internal startfirst mode flag so HS_CamEngineTour.lsl starts from the first preset without a current-camera-state roundtrip.
  • loadPreset() intentionally uses targeted field parsing instead of splitting the full preset string into a list.
  • Standard notecard command parsing uses token helpers rather than full llParseString2List(line, [" "], []).

The user's primary workflow is Notecard Tours, so optimize this file carefully and prioritize notecard-tour memory use over chat/menu one-liner convenience.

3. HS_CamTourCommands.lsl (Secondary Tour Command Helper)

Dedicated helper for chat/menu one-shot tour builders.

  • Handles /88 tour ..., /88 dollyzoom ..., and menu-built TOURRUN payloads.
  • Builds CE_CMD_TOUR payloads for secondary workflows without adding memory pressure to HS_CamPlaylist.lsl.
  • Uses targeted preset parsing for position/focus/FOV fields.
  • Keep notecard playlist logic in HS_CamPlaylist.lsl; keep chat/menu convenience parsing here.

4. HS_CamEngineTour.lsl (Continuous Tour Runtime)

Dedicated runtime for continuous multi-waypoint camera tours.

  • Receives CE_CMD_TOUR payloads from Playlist and TourCommands paths.
  • Requests current camera state from Core via CE_CMD_GET_STATE.
  • Builds runtime lists for active tour playback: position, focus, holds, segment lengths, cumulative lengths, point times, and optional weights.
  • Drives the camera by sending CE_INT_SET_CAM to HS_CamEngineCore.lsl.
  • Supports spline/linear movement, easing profiles, FOV ramps, and keep-frame mode.
  • Uses throttled camera-frame sending via tourSendCam() to reduce repeated CE_INT_SET_CAM messages.
  • Uses segment caching during timer playback to reduce repeated llList2Vector access.
  • Parses large CE_CMD_TOUR payloads using targeted pipe-field helpers rather than splitting the whole payload list.

Do not move active tour runtime lists into Linkset Data. They are read every timer tick; Linkset Data would reduce script memory but likely hurt runtime performance due to repeated string reads and conversions.

5. HS_CamEngineCore.lsl (Camera Engine Core)

Low-level camera engine.

  • Handles camera permissions, base camera params, MoveTo, Follow, Lock, config, and state queries.
  • Receives internal tour camera frames with CE_INT_SET_CAM.
  • CE_INT_SET_CAM is parsed without llParseString2List because it is part of the active tour hot path.
  • Applies llSetCameraParams for active camera movement.
  • Holds engine configuration and emits config dumps consumed by Playlist and TourEngine.

Tour-related config keys include:

  • tour_max_points
  • tour_cam_min_interval
  • tour_pos_epsilon
  • tour_focus_epsilon

6. HS_CamMenu.lsl (Menu/UI)

Handles dialog menus, page state, menu-driven tour building, nearby target lists, and UI command dispatch.

  • Sends menu commands with MN_CMD.
  • Keeps short UI lists such as nearby avatars/objects and selected tour indices.
  • Menu paths are secondary compared with notecard tours.

7. HS_CamMarkers.lsl (Marker Helper)

Marker support is a comparatively rare workflow.

  • Rezzes HS_CamMarker objects at preset positions.
  • Uses MARKER_CH = -880088.
  • Uses llRegionSayTo for marker setup/cleanup when marker keys are known.
  • Keeps a mixed marker list internally. This is known to be less memory-efficient, but marker usage is rare and should not be prioritized unless marker workflows become important.

8. HS_CamFov.lsl

Handles Field of View adjustments and FOV-related state synchronization.

Communication Protocol

Primary communication uses llMessageLinked.

Important constants:

  • MC_CMD = 5100: Marker helper command channel, e.g. SHOW|N, HIDE.
  • MC_EVT_CLICK = 5101: Marker click event from Markers to Controller.
  • MN_CMD = 7000: Menu command channel.
  • PH_CMD_PLAY = 6100: Controller/Menu to Playlist play command.
  • PH_CMD_STOP = 6101: Stop playlist command.
  • PH_CMD_CHAT_TOUR = 6102: Chat one-liner tour forwarded to TourCommands.
  • PH_CMD_TOURRUN = 6103: Menu-built tour forwarded to TourCommands.
  • PH_CMD_CHAT_DZ = 6104: Chat DollyZoom forwarded to TourCommands.
  • CE_CMD_MOVE = 1010: Engine move command.
  • CE_CMD_TOUR = 1011: Continuous tour command handled by TourEngine.
  • CE_CMD_STOP = 1012: Stop engine movement.
  • CE_CMD_LOCK = 1020: Lock command.
  • CE_CMD_FOLLOW = 1030: Follow command.
  • CE_CMD_FOV = 1040: FOV command.
  • CE_CMD_GET_STATE = 1060: Request current camera state.
  • CE_INT_SET_CAM = 3000: TourEngine to Core camera frame, payload <pos>|<focus>.
  • CE_INT_TOUR_BEGIN = 3001: TourEngine begins external drive.
  • CE_INT_TOUR_END = 3002: TourEngine ends external drive.
  • CE_INT_TOUR_STOP = 3003: Stop external tour drive.
  • MARKER_CH = -880088: Region channel for marker communication.

Preset Storage

Presets are stored in Linkset Data using keys like P1, P2, etc.

Preset format:

px|py|pz|fx|fy|fz|rx|ry|rz|rs|fovRad

Many consumers only need the first six fields:

  • position: fields 0..2
  • focus: fields 3..5
  • optional FOV: field 10

When reading presets in memory-sensitive code, avoid full llParseString2List(data, ["|"], []) if only these fields are needed.

Performance And Memory Guidelines

Prefer targeted parsing in hot paths

Avoid full llParseString2List when:

  • parsing CE_INT_SET_CAM
  • parsing preset data
  • parsing large CE_CMD_TOUR payloads
  • parsing normal notecard playlist lines

Use targeted helpers such as:

  • lineToken() in HS_CamPlaylist.lsl
  • pipe-field helpers in HS_CamEngineTour.lsl
  • direct separator lookup for two-field payloads in HS_CamEngineCore.lsl

Keep active runtime data in script memory

Active tour playback reads position/focus/segment lists every timer tick. Keep those lists in HS_CamEngineTour.lsl; do not replace them with Linkset Data reads.

Linkset Data is appropriate for persistent presets and shared state, not per-frame runtime data.

Minimize mixed-type and large temporary lists

Avoid mixed-type list builders for large payloads where a direct string build is clear and safe.

For notecard tour blocks:

  • Store preset indices while parsing.
  • Load preset position/focus at endtour.
  • Build the final CE_CMD_TOUR payload directly.

Be careful with timer hot paths

Timer-driven code should avoid:

  • full string splitting
  • repeated Linkset Data reads
  • repeated object detail calls unless needed
  • unnecessary llMessageLinked calls

Tour playback currently reduces load with:

  • tour_cam_min_interval
  • tour_pos_epsilon
  • tour_focus_epsilon
  • segment caching in TourEngine

Use llRegionSayTo when target keys are known

For marker communication, prefer llRegionSayTo over llRegionSay when the marker key is known. This reduces unnecessary listener wakeups in the region.

Configuration

Engine configuration lives in HS_CamEngine.properties.

Useful current keys:

move_step=0.025
follow_step=0.05
default_move_ms=3000
default_focus_dist=10.0
move_pos_lag=0.5
move_focus_lag=0.5
follow_pos_lag=0.5
follow_focus_lag=0.5
pos_threshold=0.02
focus_threshold=0.02
tour_cam_min_interval=0.033
tour_pos_epsilon=0.005
tour_focus_epsilon=0.005
follow_predict=0.10
tour_max_points=20

tour_cam_min_interval=0.033 caps internal tour camera updates around 30 Hz while still allowing path computation at move_step.

Validation Notes

There is no official local Second Life LSL compiler in this repository. The authoritative compile check is still in-world via the Second Life Viewer or Firestorm.

Local checks that are useful before in-world compile:

  • brace-balance checks
  • conflict marker search
  • targeted rg scans for unwanted llParseString2List reintroductions in hot paths
  • optional lslint if installed, with the understanding that it is not the official Linden compiler

Current Optimization Priorities

Highest priority:

  • Notecard tour memory behavior.
  • TourEngine timer hot path.
  • Core CE_INT_SET_CAM hot path.
  • Large CE_CMD_TOUR startup parsing.

Lower priority:

  • Marker memory layout, because marker use is rare.
  • Chat one-liner tour convenience paths.
  • Menu-only tour building paths, unless they become a primary workflow.