> 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-how-to-guides/recipes.md).

# Integration recipes

Follow practical patterns for matches, Watch buttons, private recordings, and custom controls.

Start with the outcome you want. Each recipe links to the detailed guide and, where available, a complete example you can adapt.

| I want to…                           | Main services                  |
| ------------------------------------ | ------------------------------ |
| Record a game and publish its replay | Recorder + save result         |
| Add a local Watch command            | Catalog + player               |
| Watch through a proxy lobby          | Lobby dispatch                 |
| Capture one arena in a shared world  | Recorder bounds + participants |
| Customize replay controls            | Layout service                 |
| Replay a game milestone              | Recordable codec + renderer    |

## Record a match and offer a Watch link afterward

1. On the gameplay machine, depend on `reverse-recorder` and discover `ReverseRecorder`.
2. At match initialization, choose owners, participants, bounds, and text separately.
3. Start capture on the main thread and store the returned session ID with the match ID.
4. Stop that session on completion or cancellation.
5. On successful nondegraded save, store the replay ID in your match database.
6. On a lobby machine, pass that ID to `DispatchService.watch` when an authorized player chooses Watch.

Do not transfer a live `RecordSession` Java object across machines or store a Bukkit world UUID as the replay ID. The replay UUID is the portable reference.

See [recording](/api-how-to-guides/recording.md), [dispatch](/api-how-to-guides/availability.md), and the [complete recording example](/api-how-to-guides/examples/recording-integration.md).

## Open a replay from your own command

On a local player server, discover `ReversePlayer`, build an actor from authenticated player identity and your intended admin policy, check `catalog.find`, then call `play`. Schedule delayed connection checks on the main thread. Reject the request if the player disconnected or your integration is disabling.

If several requests can overlap, add request identity tracking as well: “still online” alone does not prove an old completion belongs to the player's latest request. The supplied example shows the minimum connection/lifecycle checks, not a full replacement for your command system's concurrency policy.

See the [complete playback example](/api-how-to-guides/examples/playback-integration.md).

## Record an arena without the rest of the shared world

Use a nonnull `RecordingBounds` plus a participant UUID set through the canonical recorder start method. Owners should be whoever may view the replay, which can differ from participants. Keep template null; bounds and templates cannot be combined.

This selects event/entity admission and horizontally intersecting terrain columns, not a new physical Bukkit world and not a vertically clipped chunk serialization format.

## Make a replay owner-private

Keep `open-access: false` on viewing/catalog servers, pass the intended owner list at recording start, and do not construct an administrator actor for ordinary players. A minigame can make every participant an owner, or only the match's moderator, according to its product policy.

The recorder command always adds its initiator as an owner. If an automated recording needs a different owner policy, use the API instead of issuing player commands through a fake actor.

## Add a round-restart control to the hotbar

Register a namespaced layout action that calls `seekTo(session, roundStartTick)`. Either bind it from YAML or install a `LayoutItem` in a free slot. Remember that seeking changes the shared session for all viewers, and choose explicitly whether it should resume playback.

See the [complete UI extension example](/api-how-to-guides/examples/ui-extensions.md). For actual round boundaries, persist that game concept through a coordinated custom event/application index instead of guessing from wall-clock duration.

## Announce a game milestone during replay

Share an immutable payload and codec between recorder/player integrations. Register the same coordinated codec ID on both before emitting/loading, insert the event into the correct recording session, and register a player renderer that targets `context.getViewers()`.

The [milestone example](/api-how-to-guides/examples/milestone.md) is transient: it is an announcement during playback, not durable state reconstructed for every seek. Use [stateful integration rules](/advanced-integrations/recordables.md) for persistent changes.

## Send a notification only when persistence really finishes

Use `stopSession(...).whenComplete(...)` or `RecordingSavedEvent`, not `RecordingStopEvent`. Handle a null replay ID and degraded terrain separately. Schedule Bukkit messages on the main thread and avoid blocking it waiting for save completion.

See the [complete notification example](/api-how-to-guides/examples/replay-notifications.md).

## Support optional Reverse installations

Use `softdepend`, keep role-specific API references behind an optional adapter, and register that adapter only when the dependency is present and enabled. Re-check provider discovery rather than assuming a plugin's jar existing means its runtime initialized successfully.

Do not package a second copy of the API to make missing-runtime class references appear to work. Optional integrations need a classloading boundary, not duplicate contracts.


---

# 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-how-to-guides/recipes.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.
