Skip to main content

Services, recordings, and sessions

Before we write the integration, let’s give names to the objects we will work with. Reverse has three runtime entry points, and each one exposes services for a particular job.

The runtime entry points

Use the entry point for the server your plugin runs on:
This asks Bukkit for the active recorder provider. It does not create a new recorder. The player and lobby expose the same discovery pattern through ReversePlayer.get() and ReverseLobby.get(). Bukkit’s ServicesManager is used here to access the runtime facade. It does not discover protocol/storage factories. Those are a fixed built-in set selected at startup by adapter and storage.backend; see adapters and storage. An empty Optional means the provider is unavailable, for example because that role is absent or did not finish initialization. Declare the dependency in your plugin descriptor, then discover it during onEnable.

A service performs an operation

The entry point gives us the service that owns the operation:
Here, RecorderService controls capture. Other services handle playback, catalog access, rendering, or UI controls. Borrow these services from Reverse rather than constructing its implementation classes.
You own the integration, not the runtime. Close your own resources and retire your own registrations. Do not close Reverse’s shared storage or availability service from your plugin.

RecordSession: a recording in progress

RecordSession represents live capture. Keep its UUID with your match:
Later, stop that session through the recorder service:
The stop operation returns a stage because saving takes time. Stopping capture and completing a save are different lifecycle points; we will handle both in the first tutorial.

Replay: a saved recording’s metadata

A catalog entry exposes Replay: its ID, name, description, owners, timing, world ID, and terrain identifier. This is enough to draw a list or details screen without loading all events. LoadedReplay adds the immutable event stream needed for playback. Use catalog queries for browsing; load the full replay when you need its timeline.

PlaybackSession: one viewing instance

A PlaybackSession is an active viewing of a saved recording. It has its own viewer list, cursor, pause state, speed, and entity mappings. One recording can be played by several independent sessions. Several viewers in one session share its controls and timeline. Viewer-specific hotbar state does not create a separate playback cursor.

Which UUID should I keep?

The terrain identifier is separate and is a string, not necessarily a UUID. It can refer to captured chunks or a named template.

Owners are not participants

  • Owners decide who may access the finished recording through the catalog.
  • Participants decide which players are selected for capture.
  • Bounds select the spatial area to record.
For example, a moderator can own a recording without being one of its participants. We will keep these choices separate in the next tutorials. Null participant selection captures all in-scope players; an empty set captures none. Nonplayers remain spatially selected. Bounds and participants are immutable session-only capture choices, not extra fields saved in the replay header.

Let’s create a recording

Create your first recording →