Capture

Describing screenshots and recordings.

These types are pure data: they say what to capture and how, and carry no effects. The effects that act on them live in the platform's Capture module, which re-exports everything declared here, so an app names them through Capture and never depends on this package directly.

default : Recording

A 25 FPS half-scale GIF of at most 300 frames, using fixed-step timing and balanced encoder quality.

Sized so a full-screen recording stays well inside the host's in-memory encoding budget and produces a file small enough to embed in a README.

Format : CaptureFormat

Container and codec written for a capture.

Png writes a numbered still per captured frame. Gif and WebM each write a single animated file, encoded incrementally as frames arrive -- so memory stays bounded by one frame and the length of a recording is limited only by max_frames and by disk space.

CaptureFormat in the signature is the module-private nominal this aliases; Capture.Format is the name to write.

Scale : CaptureScale

How far each captured frame is downscaled from the framebuffer.

Scaling happens after rendering, so it shrinks the output file without changing the window size or what the app draws. A ratio that would round an axis to zero is clamped to one pixel.

Timing : CaptureTiming

Whether simulation time follows the wall clock or advances in exact steps.

Reading back the framebuffer stalls the GPU, so a RealTime recording bakes that stutter into the output and differs between runs. FixedStep reports 1/fps as the frame delta regardless of how long the frame actually took, which is smooth and reproducible.

Cursor : CaptureCursor

Whether the host composites a pointer glyph into captured frames.

The operating system cursor is not part of the framebuffer, so a recording never shows a pointer unless something draws one.

Quality : CaptureQuality

How hard the encoder works to choose colours for each frame.

This setting affects Gif and is ignored by Png and WebM.

Best searches the full colour depth. Balanced is the default and trades at most 16/255 channel error for faster encoding on flat-colour frames. Fast uses a coarser palette and may show visible banding.

Recording

Capture.Recording :: # (opaque)

A validated recording request. Its fields cannot be updated directly; use its receiver updates so the invariants are preserved.

is_eq : _

Compare two of these values.

with_path : Recording, Str -> Recording

Return a recording written to a different path.

The path is relative to the app's configured output directory. The host refuses absolute paths and any path containing ...

with_format : Recording, Format -> Recording

Return a recording written in a different format.

with_fps : Recording, I32 -> Recording

Return a recording played back at a different frame rate. A non-positive rate falls back to the 25 FPS default.

with_max_frames : Recording, U64 -> Recording

Return a recording that stops after this many captured frames. 0 records until a Capture.stop command is applied or the app exits.

with_scale : Recording, Scale -> Recording

Return a recording captured at a different scale.

with_every_nth : Recording, U32 -> Recording

Return a recording that keeps only every nth rendered frame. 0 and 1 both keep every frame.

with_timing : Recording, Timing -> Recording

Return a recording using a different simulation timing strategy.

with_cursor : Recording, Cursor -> Recording

Return a recording that does or does not draw a pointer glyph.

with_quality : Recording, Quality -> Recording

Return a recording encoded at a different quality.

path : Recording -> Str

Inspect the output path.

format : Recording -> Format

Inspect the selected format.

fps : Recording -> I32

Inspect the playback frame rate.

max_frames : Recording -> U64

Inspect the frame cap. 0 means the recording is unbounded.

scale : Recording -> Scale

Inspect the capture scale.

timing : Recording -> Timing

Inspect the simulation timing strategy.

cursor : Recording -> Cursor

Inspect whether a pointer glyph is drawn.

quality : Recording -> Quality

Inspect the encoder quality.

Status : [
    Idle,
    Active({ frames : U64, dropped : U64 }),
    Finished({ frames : U64, bytes : U64 }),
    Failed({ frames : U64, reason : FailureReason }),
]

Live recording state, sampled onto every App.Input as input.capture.

Finished remains observable after automatic finalization at the frame cap.

FailureReason : [
    PathInvalid,
    PathEscapesOutputDir,
    AlreadyRecording,
    BudgetExceeded,
    UnsupportedFormat,
    OutOfMemory,
    WriteFailed,
    EncodeFailed,
    Unknown,
]

Why a recording is not running.

PathInvalid, PathEscapesOutputDir, AlreadyRecording, and BudgetExceeded reject a start request before anything is written. The remaining reasons may stop an active recording.