> ## Documentation Index
> Fetch the complete documentation index at: https://docs.marioded.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Services, recordings, and sessions

> Get to know the services and data objects before creating your first recording.

# 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:

```java theme={null}
ReverseRecorder recorder = ReverseRecorder.get().orElseThrow();
```

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](https://docs.marioded.com/api/adapters.md) and [storage](https://docs.marioded.com/api/catalog-and-storage.md).

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:

```java theme={null}
RecorderService recording = recorder.getRecorderService();
RecordSession session = recording.startRecording(world);
```

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.

> [!NOTE]
>
> **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:

```java theme={null}
UUID sessionId = session.getUniqueId();
```

Later, stop that session through the recorder service:

```java theme={null}
recording.stopSession(sessionId);
```

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?

| Value | Meaning | Use it for |
| - | - | - |
| Recording session ID | The live recording and the replay it will produce | Stop the exact match recording; store its resulting replay reference. |
| Replay ID | A saved recording | Catalog queries, loading, playback, and lobby selection. |
| Playback session ID | One active viewing instance | Seek, pause, resume, set speed, leave, or stop that session. |
| Viewer ID | A player's UUID | Find their playback session and manage viewer-specific layout state. |
| Bukkit world ID | The source world | List recordings with `getSessionsForWorld(worldId)` or broadcast world events, not stop a particular recording. |

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 →](https://docs.marioded.com/api/first-recording.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.