# Project Topology

The main bulk of a project lives within a Yjs Document. The structure of the document can be seen in our Typescript type here: <https://github.com/Vija02/TheOpenPresenter/blob/main/packages/base-plugin/src/types.ts>

Here's how a project document might look like:

{% code overflow="wrap" %}

```json
{
  "meta": {
    "id": "project_01j96y7vz1f5c9pphfx0nkqg6h",
    "name": "Test Project",
    "createdAt": "2024-10-02T15:40:36.706Z"
  },
  "data": {
    "scene_01j9c3wn6mfcpafk2ee8jwcw5t": {
      "name": "Audio Recorder",
      "order": 1,
      "type": "scene",
      "children": {
        "plugin_01j9c3wn6mfcpafk2eecfj37s5": {
          "plugin": "audio-recorder",
          "order": 1,
          "pluginData": {
            "recordings": [],
            "activeStreams": []
          }
        }
      }
    },
    "scene_01j9740ysfemzsdyvqn2pyhb5m": {
      "name": "Radio",
      "order": 2,
      "type": "scene",
      "children": {
        "plugin_01j9740ysge6wv45h29rqkddtt": {
          "plugin": "radio",
          "order": 1,
          "pluginData": {
            "url": ""
          }
        }
      }
    }
  },
  "renderer": {
    "1": {
      "currentScene": "scene_01jbf18xagf24a30sf1wvf19wh",
      "overlay": null,
      "children": {
        "scene_01j9740ysfemzsdyvqn2pyhb5m": {
          "plugin_01j9740ysge6wv45h29rqkddtt": {
            "volume": 0.05,
            "isPlaying": false
          }
        },
        "scene_01j9c3wn6mfcpafk2ee8jwcw5t": {
          "plugin_01j9c3wn6mfcpafk2eecfj37s5": {}
        }
      }
    }
  }
}
```

{% endcode %}

{% hint style="warning" %}
Some parts of this document might still change. Particularly around `meta` and  `renderer`
{% endhint %}

## ID

All ID inside our document should be a [TypeID](https://github.com/jetify-com/typeid-js). Notice that they are also prefixed with strings like *scene*, *plugin* and *project*.

## Meta

The **meta** object stores any meta information about the project. It is quite basic at the moment but we may add more things in the future.

## Data

The majority of information is stored in the **data** object. A project can contain many scenes.

#### Scene

A scene controls what is shown in a single view. It contains one or more **plugins.**

#### Plugin

Each plugin is responsible for a specific functionality. Eg: Video playing. You can include multiple plugin inside a single scene.&#x20;

For example, you may have a plugin to show a moving background. And then use another plugin to show text on top of it.

Crucially, each plugin can store its own data in the document. This data will be used by the Renderer to render the right things.

## Renderer

#### Multiple Views

A project have many views at any single time. This is useful to show different views to multiple screens. For example, to be used as a confidence monitor.

This is the first level under renderer.

#### Active scene

Each view will show the scene that is set in the **currentScene** property.

Meanwhile, the **overlay** property is used to override/overlay the view with something else like a black screen.

#### Children

The children property maps the **scenes** and **plugins** that exists in **data**. Correspondingly, each plugin is responsible for the data that is stored inside those properties.

{% hint style="info" %}
While we have the concept of **views** and **active scenes**, a plugin does not have to strictly obey them. For example, an song player plugin probably wants to keep playing across scenes. However, we encourage to keep crossovers to the minimum.
{% endhint %}

## Custom state in data vs renderer

So there are 2 location where plugin can store their state. When should you store state in **data** vs **renderer**?

If your data will be the same across views, they should be stored in **data**.

If your data will be different across views, they should be stored in **renderer**.

**For example:**

A lyrics plugin may store its songs in the **data** property. However, it may choose to store the display information in the **renderer** property. This allows users to show different lyrics of the same song in screens within the same plugin.


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.theopenpresenter.com/introduction/project-topology.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
