Class StreamBuilder
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 Summary
Modifier and TypeMethodDescriptionappearance(RenderAppearance value) Sets rendering appearance, including exposure.chunksPerTick(int value) Limits this stream's share of the global four-chunk capture budget per server tick.content(SceneContent value) Selects which captured block/entity geometry remains available to each render pass.environment(Supplier<RenderEnvironment> value) Samples rendered environment overrides once per prepared frame on the server thread.environment(RenderEnvironment value) Overrides rendered time/weather without changing the live world or captured provenance.excluding(Collection<? extends org.bukkit.entity.Entity> values) Adds entities from a list, set or other collection.Adds a defensive copy of UUID exclusions before visual capture.Adds copied UUID exclusions before capture.excluding(org.bukkit.entity.Entity... entities) Adds entities to omit before visual capture.excludingIds(Collection<UUID> values) Adds UUIDs from any collection without retaining the caller's collection.fov(double degrees) Sets vertical field of view, changing the camera framing rather than image brightness.fps(int fps) Sets a target frame rate.fresh()Requests newly captured world evidence for every frame.lighting(RenderLighting value) Sets request-level world and explicit lighting.mapOptions(MapOutputOptions value) Sets map-palette conversion options.Adds a server-thread error observer.onFrame(Consumer<RenderedFrame> consumer) Adds a frame consumer called on the server thread after freshness and lifecycle checks.onProgress(Consumer<FrameProgress> value) Observes measured stage-local work on the server thread, at most once per tick.profile(RenderSettings.Profile profile) Selects rendering quality.radius(double blocks) Sets how far loaded-world evidence is captured around the source camera.recipe(RenderRecipe value) Replaces the ordered render recipe.resolution(int width, int height) Sets explicit render dimensions.Enables smooth camera reframing against unchanged captured world evidence.reuse(SceneReusePolicy policy) Enables smooth camera reframing with bounded evidence age and displacement.roll(double degrees) Rotates the camera around its viewing axis.settings(RenderSettings settings) Replaces rendering settings, including resolution, profile, attachments, memory and timeout.start()Starts the configured feed on the server thread and allocates its temporary outputs once.Adds a caller-owned destination for an aspect-fitted 128×128 palette.toPlayer(org.bukkit.entity.Player player) Adds one temporary handheld map in a free inventory slot without replacing items.toScreen(org.bukkit.Location anchor, org.bukkit.block.BlockFace face, int columns, int rows) Adds a temporary wall screen made of owned item frames.visibleTo(org.bukkit.entity.Player value) Applies Bukkit visibility rules for a viewer.
-
Method Details
-
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
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 pixelsheight- positive output height in pixels- Returns:
- a new builder with this setting
- Throws:
IllegalArgumentException- for invalid dimensions
-
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
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
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
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
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
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
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 capturemaxCameraDisplacement- finite nonnegative distance from the original capture pose, in blocks- Returns:
- a new builder with these reuse bounds
- Throws:
IllegalArgumentException- for invalid bounds
-
excluding
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
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
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
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
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 blockface- NORTH, SOUTH, EAST or WEST, pointing outward from the backing wallcolumns- grid width, 1..16 mapsrows- 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
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 configuredRendererException- if the owner/provider is unavailable or setup cannot complete
-
roll
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
-