- 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.
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
llGetNotecardLineSyncwhen the simulator has the notecard cached, with fallback tollGetNotecardLineonNAK. - 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.lslviaCE_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
startfirstmode flag soHS_CamEngineTour.lslstarts 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-builtTOURRUNpayloads. - Builds
CE_CMD_TOURpayloads for secondary workflows without adding memory pressure toHS_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_TOURpayloads 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_CAMtoHS_CamEngineCore.lsl. - Supports spline/linear movement, easing profiles, FOV ramps, and keep-frame mode.
- Uses throttled camera-frame sending via
tourSendCam()to reduce repeatedCE_INT_SET_CAMmessages. - Uses segment caching during timer playback to reduce repeated
llList2Vectoraccess. - Parses large
CE_CMD_TOURpayloads 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_CAMis parsed withoutllParseString2Listbecause it is part of the active tour hot path.- Applies
llSetCameraParamsfor active camera movement. - Holds engine configuration and emits config dumps consumed by Playlist and TourEngine.
Tour-related config keys include:
tour_max_pointstour_cam_min_intervaltour_pos_epsilontour_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_CamMarkerobjects at preset positions. - Uses
MARKER_CH = -880088. - Uses
llRegionSayTofor 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_TOURpayloads - parsing normal notecard playlist lines
Use targeted helpers such as:
lineToken()inHS_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_TOURpayload 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
llMessageLinkedcalls
Tour playback currently reduces load with:
tour_cam_min_intervaltour_pos_epsilontour_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
rgscans for unwantedllParseString2Listreintroductions in hot paths - optional
lslintif 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_CAMhot path. - Large
CE_CMD_TOURstartup 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.