> For the complete documentation index, see [llms.txt](https://docs.marioded.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.marioded.com/api-introduction/improving-recording.md).

# Improving your recording

Extend the first recording example with arena bounds, participant selection, and match ownership.

Our [first integration](/api-introduction/first-recording.md) records a whole world and keeps one active recording. Let's adapt the same start/stop flow for a real arena game.

We will add one concept at a time: capture bounds, participants, and multiple matches. The save-result handling from the first tutorial still applies.

## Give the recording an arena

If several arenas share one Bukkit world, recording the world alone is too broad. Create a bounding box:

```java
RecordingBounds bounds = new RecordingBounds(-64, 0, -64, 64, 255, 64);
```

These are **inclusive block coordinates**: minimum X/Y/Z followed by maximum X/Y/Z. Change them to your arena's actual bounds. For continuous positions, containment ends just before `max + 1` on each axis.

Now pass the bounds when starting:

```java
RecordSession session = recorder.getRecorderService().startRecording(
    world,
    List.of(ownerId),
    new ReplayText("Arena final", "First integration"),
    bounds);
```

Terrain uses full-height chunk columns intersecting the horizontal area. This is not a vertically clipped chunk format.

## Choose the participants

We also want spectators outside our participant set to stay out of player capture. Use the overload that accepts player UUIDs:

```java
RecordSession session = recorder.getRecorderService().startRecording(
    world,
    null,
    List.of(ownerId),
    new ReplayText("Arena final", "First integration"),
    bounds,
    Set.copyOf(participantIds));
```

The new arguments have separate jobs:

| Argument                     | Meaning                                                      |
| ---------------------------- | ------------------------------------------------------------ |
| `null` template              | Capture live terrain rather than reference a named template. |
| `List.of(ownerId)`           | Decide who can access the finished replay.                   |
| `bounds`                     | Select the spatial capture area.                             |
| `Set.copyOf(participantIds)` | Select the players eligible for capture.                     |

Null participants means all in-scope players. An empty set means no players, not “use defaults.” Nonplayer entities are still selected spatially.

## Make participants owners, when that is your policy

Being recorded does not automatically grant catalog access. If every match participant should be an owner, supply their UUIDs as the owner list too:

```java
List<UUID> ownerIds = List.copyOf(participantIds);
```

Alternatively, make a moderator or match host the owner. Keep the two selections conceptually separate even when your application chooses the same UUIDs for both.

## Validate player-supplied text

When names/descriptions come from users, validate them before starting:

```java
ReplayCatalog.validateMetadata(name, description);
ReplayText text = new ReplayText(name, description);
```

Validation throws for invalid input. Handle that in your command/menu layer so the player can correct the text. [Catalog and storage](/api-how-to-guides/catalog-and-storage.md) explains the text bounds and access policy.

## Allow several matches

The first example's `activeSession` field is our own one-match simplification, not a recorder limit. Reverse can record independent sessions in the same world.

Keep each recording ID in its match object. At match end, stop the stored ID:

```java
CompletionStage<StopResult> saving =
    recorder.getRecorderService().stopSession(sessionId);
```

Do not look up the “first recording in this world” to decide which match to stop. Another arena or integration may be recording that same world.

## What if the arena comes from a template?

A nonempty template name skips live terrain capture and references an existing terrain asset:

```java
RecordSession session = recorder.getRecorderService().startRecording(
    world, "arena-template", List.of(ownerId), text);
```

Use either **bounds for live capture** or an **explicit template**, not both. The player machine must be able to resolve the same template. A template's name is not inferred from the Bukkit world's name.

## What we improved

The integration now separates access from capture selection, scopes the arena, and can associate independent recordings with independent matches. The complete bounded/multi-match hook example is available below.

{% content-ref url="/pages/Edz9sNPD1CqInThrMtI0" %}
[Recording a match](/api-how-to-guides/examples/recording-integration.md)
{% endcontent-ref %}

For a complete list of lifecycle outcomes and lower-level capture operations, continue with [Recording integrations](/api-how-to-guides/recording.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.marioded.com/api-introduction/improving-recording.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
