Class StreamBuilder

java.lang.Object
ke.ric.renderer.api.StreamBuilder

public final class StreamBuilder extends Object
Immutable live-camera configuration. Each modifier returns a new builder. Call start() on the server thread after adding at least one frame consumer, palette sink or output.

Defaults are Classic 128×128, 70° vertical FOV, zero roll, a 16-block radius and a target of 20 FPS. Smooth mode can reuse unchanged world evidence for at most 500 ms and two blocks of camera movement within the original centre chunk. fresh() requests new evidence for every frame. FPS is a target: obsolete frames are discarded and work never queues to catch up.

Streams share a fair capture coordinator with four chunks per server tick and bounded conversion work. Each stream has at most one render/conversion in progress. Required chunks must already be loaded. Maps are allocated once and updated, never saved as photographs. After one second without a usable frame, built-in outputs show “No signal” until recovery.

Camera and environment suppliers, frame/error/progress callbacks and Bukkit mutations run on the server thread. Source death/logout, a null camera supplier, owner disable, provider replacement or affected world unload ends or fails the feed. Partial output setup is rolled back, and cleanup removes only owned temporary output.


 RenderStream stream = renderer.stream(drone)
         .toScreen(upperLeftBackingBlock, BlockFace.NORTH, 2, 2)
         .toPlayer(operator)
         .onError(error -> plugin.getLogger().warning(error.getMessage()))
         .start();
 // Later:
 stream.stop();
 
  • Method Details

    • fps

      public StreamBuilder fps(int fps)
      Sets a target frame rate. Slow work skips frames instead of queuing catch-up requests; actual throughput depends on capture, rendering, resolution, conversion and server load.
      Parameters:
      fps - target from 1 to 20 inclusive; default 20
      Returns:
      a new builder with this target
      Throws:
      IllegalArgumentException - if fps is outside 1..20
    • resolution

      public StreamBuilder resolution(int width, int height)
      Sets explicit render dimensions. The immutable original builder is unchanged. Each map or screen preserves image aspect ratio with black letterboxing. This overrides resolution inference from a screen grid.
      Parameters:
      width - positive output width in pixels
      height - positive output height in pixels
      Returns:
      a new builder with this setting
      Throws:
      IllegalArgumentException - for invalid dimensions
    • profile

      public StreamBuilder profile(RenderSettings.Profile profile)
      Selects rendering quality. Check the active provider's advertised profiles before choosing a profile; explicit requested lights and shadows are not silently disabled by quality.
      Parameters:
      profile - supported quality profile; default CLASSIC
      Returns:
      a new builder with this setting
    • settings

      public StreamBuilder settings(RenderSettings settings)
      Replaces rendering settings, including resolution, profile, attachments, memory and timeout. Camera FOV, roll, capture radius and recipe controls remain as configured. Its dimensions count as an explicit resolution and disable screen-grid inference.
      Parameters:
      settings - complete immutable render settings
      Returns:
      a new builder with this setting
    • fov

      public StreamBuilder fov(double degrees)
      Sets vertical field of view, changing the camera framing rather than image brightness. The default is 70°. Older providers explicitly reject unsupported custom FOV.
      Parameters:
      degrees - finite vertical angle strictly between 0 and 180
      Returns:
      a new builder with this setting
      Throws:
      IllegalArgumentException - for an invalid angle
    • radius

      public StreamBuilder radius(double blocks)
      Sets how far loaded-world evidence is captured around the source camera. Larger radii increase capture and render work; required chunks must already be loaded.
      Parameters:
      blocks - finite positive radius in blocks; default 16
      Returns:
      a new builder with this setting
      Throws:
      IllegalArgumentException - for a nonpositive or nonfinite radius
    • fresh

      public StreamBuilder fresh()
      Requests newly captured world evidence for every frame. The resulting camera pose is the pose used for that capture; smooth mode instead reframes recent evidence for a newer pose.
      Returns:
      a new builder with scene reuse disabled
    • reuse

      public StreamBuilder reuse(SceneReusePolicy policy)
      Enables smooth camera reframing with bounded evidence age and displacement. Neither limit is renewed by reuse. The camera must stay in the captured centre chunk and covered build height.
      Parameters:
      policy - immutable reuse bounds; defaults are 500 ms and two blocks
      Returns:
      a new builder with scene reuse enabled
    • reuse

      public StreamBuilder reuse(Duration maxWorldAge, double maxCameraDisplacement)
      Enables smooth camera reframing against unchanged captured world evidence. A fresh capture is needed when its age, displacement or original centre-chunk coverage is exceeded.
      Parameters:
      maxWorldAge - positive duration that fits in nanoseconds, measured from original capture
      maxCameraDisplacement - finite nonnegative distance from the original capture pose, in blocks
      Returns:
      a new builder with these reuse bounds
      Throws:
      IllegalArgumentException - for invalid bounds
    • excluding

      public StreamBuilder excluding(Set<UUID> ids)
      Adds a defensive copy of UUID exclusions before visual capture. Exclusions are cumulative and apply to every layer, including Xray and lighting; the camera entity is already excluded.
      Parameters:
      ids - UUIDs to omit; no null elements
      Returns:
      a new builder with this setting
    • excluding

      public StreamBuilder excluding(org.bukkit.entity.Entity... entities)
      Adds entities to omit before visual capture. References are copied now; UUIDs are read on the server thread when preparing capture. The camera entity is already excluded.
      Parameters:
      entities - entities to omit; no null elements
      Returns:
      a new builder with this setting
    • onFrame

      public StreamBuilder onFrame(Consumer<RenderedFrame> consumer)
      Adds a frame consumer called on the server thread after freshness and lifecycle checks. Frames cannot rewind the feed. Keep callbacks quick; an exception fails and cleans up the stream.
      Parameters:
      consumer - nonnull frame observer; multiple observers run in registration order
      Returns:
      a new builder with this observer
    • onError

      public StreamBuilder onError(Consumer<Throwable> consumer)
      Adds a server-thread error observer. Some errors, such as temporary queue pressure or missing capture evidence, skip frames and may recover; permanent failures terminate the stream. Inspect RenderStream.status() or completion() to distinguish terminal failure.
      Parameters:
      consumer - nonnull error observer
      Returns:
      a new builder with this observer
    • toPlayer

      public StreamBuilder toPlayer(org.bukkit.entity.Player player)
      Adds one temporary handheld map in a free inventory slot without replacing items. The image preserves aspect ratio with black letterboxing. A full inventory fails setup; disconnect removes this output. The map is updated in place and does not enter the saved-photo store.
      Parameters:
      player - recipient of this temporary output
      Returns:
      a new builder with this output
    • toScreen

      public StreamBuilder toScreen(org.bukkit.Location anchor, org.bukkit.block.BlockFace face, int columns, int rows)
      Adds a temporary wall screen made of owned item frames. The anchor is the upper-left backing block as viewed from the requested outward face; columns extend right and rows extend down. The wall and frame positions are validated at start. Partial setup is rolled back, and stop removes only owned output. Existing item frames are rejected.

      Unless resolution was explicitly set, this screen sets render dimensions to columns×128 by rows×128. Multiple screens use the last inferred resolution. Outputs fit the final image to their own grid without distorting its aspect ratio. Live maps are never persisted as photos.

      Parameters:
      anchor - copied location of the upper-left backing block
      face - NORTH, SOUTH, EAST or WEST, pointing outward from the backing wall
      columns - grid width, 1..16 maps
      rows - grid height, 1..16 maps; total at most 256
      Returns:
      a new builder with this screen
      Throws:
      IllegalArgumentException - for an unsupported face or grid size
    • start

      public RenderStream start()
      Starts the configured feed on the server thread and allocates its temporary outputs once. At least one output, palette sink or frame consumer is required. Setup failure rolls back partial output creation. Owner disable also stops this stream automatically.
      Returns:
      the lifecycle handle; stop it when the feed is no longer needed
      Throws:
      IllegalStateException - if called off the server thread or no destination is configured
      RendererException - if the owner/provider is unavailable or setup cannot complete
    • roll

      public StreamBuilder roll(double degrees)
      Rotates the camera around its viewing axis. Camera-relative lights follow the same roll. The default is zero; this convenience method uses degrees, while SceneCamera uses radians.
      Parameters:
      degrees - any finite roll angle, including full turns and inverted views
      Returns:
      a new builder with this setting
      Throws:
      IllegalArgumentException - if degrees is nonfinite
    • lighting

      public StreamBuilder lighting(RenderLighting value)
      Sets request-level world and explicit lighting. Layers inherit this setup unless they supply their own complete lighting value. Exposure and post-render brightness are separate controls.
      Parameters:
      value - immutable lighting setup; default RenderLighting.world()
      Returns:
      a new builder with this setting
    • onProgress

      public StreamBuilder onProgress(Consumer<FrameProgress> value)
      Observes measured stage-local work on the server thread, at most once per tick. Updates are coalesced; stages and render passes can restart at zero. Percentage is basisPoints / 100.0. Keep the callback quick. Throwing fails pending work; a final coalesced notification may arrive after successful completion and cannot revoke it. Lifecycle checks suppress callbacks after cancellation or owner/provider invalidation.
      Parameters:
      value - nonnull progress observer
      Returns:
      a new builder with this setting
    • content

      public StreamBuilder content(SceneContent value)
      Selects which captured block/entity geometry remains available to each render pass. Removed geometry cannot contribute to camera, reflection or shadow rays; sampled environment and light levels remain. Entity layers can instead restrict camera output while retaining scene geometry. Use excluding(...) to omit entities before capture.
      Parameters:
      value - immutable selection; default SceneContent.all()
      Returns:
      a new builder with this setting
    • appearance

      public StreamBuilder appearance(RenderAppearance value)
      Sets rendering appearance, including exposure. Exposure is applied by the renderer; layer brightness is a separate multiplication of already rendered pixels.
      Parameters:
      value - immutable appearance overrides; unspecified fields inherit captured values
      Returns:
      a new builder with this setting
    • recipe

      public StreamBuilder recipe(RenderRecipe value)
      Replaces the ordered render recipe. Every layer derives independently from the same original capture. Entity layers respect scene occlusion unless explicitly configured otherwise.
      Parameters:
      value - nonempty immutable recipe; default one full-scene layer
      Returns:
      a new builder with this setting
    • mapOptions

      public StreamBuilder mapOptions(MapOutputOptions value)
      Sets map-palette conversion options. This affects map output without changing the rendered RGBA image, capture settings or lighting.
      Parameters:
      value - conversion settings; default no dithering
      Returns:
      a new builder with this setting
    • visibleTo

      public StreamBuilder visibleTo(org.bukkit.entity.Player value)
      Applies Bukkit visibility rules for a viewer. Hidden entities are excluded from capture and privacy is checked again before publication. Layers and explicit Xray cannot restore them.
      Parameters:
      value - viewer whose canSee rules apply; does not itself create a player output
      Returns:
      a new builder with this setting
    • environment

      public StreamBuilder environment(RenderEnvironment value)
      Overrides rendered time/weather without changing the live world or captured provenance. Unspecified fields inherit captured facts. Layers can override individual fields again.
      Parameters:
      value - immutable environment settings
      Returns:
      a new builder with this setting
    • excluding

      public StreamBuilder excluding(Collection<? extends org.bukkit.entity.Entity> values)
      Adds entities from a list, set or other collection. References are defensively copied and UUIDs are read on the server thread. Exclusions are cumulative and apply to every recipe layer.
      Parameters:
      values - entity references to omit; no null elements
      Returns:
      a new builder with this setting
    • excludingIds

      public StreamBuilder excludingIds(Collection<UUID> values)
      Adds UUIDs from any collection without retaining the caller's collection. Use this overload when you already have IDs rather than live entity references.
      Parameters:
      values - entity UUIDs to omit; no null elements
      Returns:
      a new builder with this setting
    • excluding

      public StreamBuilder excluding(UUID... values)
      Adds copied UUID exclusions before capture. The source entity is already omitted.
      Parameters:
      values - entity identities to omit; no null elements
      Returns:
      a new builder with combined exclusions
    • environment

      public StreamBuilder environment(Supplier<RenderEnvironment> value)
      Samples rendered environment overrides once per prepared frame on the server thread. Keep the supplier quick. A null value or thrown exception fails the feed; captured provenance remains unchanged. This can change time/weather while reusing existing world evidence.
      Parameters:
      value - nonnull supplier returning a nonnull immutable environment
      Returns:
      a new builder using this supplier
    • chunksPerTick

      public StreamBuilder chunksPerTick(int value)
      Limits this stream's share of the global four-chunk capture budget per server tick. All convenience streams share the fair coordinator; this does not increase its global budget.
      Parameters:
      value - positive requested budget; values above four are capped at four
      Returns:
      a new builder with this capture budget
      Throws:
      IllegalArgumentException - if value is not positive
    • toMapSink

      public StreamBuilder toMapSink(MapSink value)
      Adds a caller-owned destination for an aspect-fitted 128×128 palette. This allocates no maps and performs no photo saving. Sink callbacks run on the server thread; a thrown exception terminates the stream. The sink is closed once during terminal cleanup.
      Parameters:
      value - nonnull palette destination
      Returns:
      a new builder with this sink