Skip to main content

Plugins

Plugins

Starting with version 0.8.0, the first draft of creating custom plugins were introduced. They are meant as a way for developers to add extra functionality to PianoRhythm. Each plugin is instantiated in its own iframe sandbox with access to a limited API to the client's internal PianoRhythm.

As of 5/1/2023, this plugin architecture is still in a initial draft state so it's still experimental.

caution

Plugins are currently not synced and uploaded to your account in the cloud. They are only stored locally on the client. You can actually find the raw objects in the IndexedDB: plugin-management -> plugins.

Creating Plugins

To get started with creating your first plugin, you'll see it under the Plugins menu in the settings modal.

0.7.5This screenshot was taken in version: 0.7.5

Once you click on the Create New Plugin button, a modal will pop up with different tabs to edit code, html, and the css of the plugin. The code section displays a typescript code editor while the other tabs are in similar fashion.

0.7.5This screenshot was taken in version: 0.7.5

Every plugin must have a Main class. As noted in the screenshot, in the constructor of the class is an object model that is injected. It represents an API with certain access to the PianoRhythm client. With it, you'll have certain methods like sending note data to the audio engine, fetching data like the current users and/or rooms, and more.

For example, if you wanted to trigger a note on event, you can do:

main
class Main {
/** The core plugin app. */
#app: IPianoRhythmPluginApp;

constructor(app: IPianoRhythmPluginApp) {
this.#app = app;
}

onStart() {
console.log("Plugin Started");

//Signature: noteOn(channel: number, key: number, velocity: number): void
this.#app.noteOn(0, 60, 127);
}
...

Any chat messages emitted by your plugin will be tagged with PLUGIN to let other users be able to differentiate you and your plugin.

0.7.5This screenshot was taken in version: 0.7.5

info

Plugins that emit chat messages or notes will be disabled in public lobbies in the near feature.

Editor

The editor is pretty basic so don't expect any fancy tooling like proper intellisense. There's a basic autocompletion for the API that is injected but that's about it. However, there are some autogenerated type docs for the API and associated types: IPianoRhythmPluginAPI

Autocompletion

The autocompletion for the API is currently tied to the variable name app. Changing the variable name will inactivate the autocompletion.

0.7.5This screenshot was taken in version: 0.7.5

HTML Tab

The html section allows you to create and describe the structure of your plugin.

CSS Tab

The css section allows you to describe the presentation of your plugin. Because of the nature of the iframe and css, manipulating the position and dimensions of your plugin could be tricky. I still need to research to find a better format. In the mean time, there are methods you can run with the api to edit the position and dimensions of your plugin:

main
  ...
onStart() {
console.log("Plugin Started");

//signature: setContainerPosition(x: string | number, y: string | number): void { }
this.#app.setContainerPosition(400, 400);

//signature: setContainerDimensions(width: string | number, height: string | number): void { }
this.#app.setContainerDimensions(100, 100);
}
...

Meta Tab

As of now, plugins are only processed locally on your client. In the future, there'll be a plugin store where you can share and publish your plugin for other users to use. It'll go through a verification process and must be approved before it others can download it. The Meta tab will allow you to add more meta description about your plugin.

Lifecycles

There are also certain life cycle and other hooks implemented. The primary ones being onStart and onStop. Those two methods are called when the plugin is initialized and stopped, respectively.

The other hooks such as onChatMessageAddedEvent are automatically called within the app. Hopefully the name of the methods are self explanatory. If not, then experiment with the code to see what happens!

Compilation

When you are ready to test your plugin, just click on the compilation button. If they are no syntax issues or missing requirements, then it should succesfully compile. Then from there, you can press execute to load and run the plugin into PianoRhythm.

If any runtime errors occur, then you can check the console logs in the browser's dev tools (ctrl + shift + i). Otherwise, you'll see a list of your plugins that were loaded succesfully:

0.7.5This screenshot was taken in version: 0.7.5

Post Load

For loaded plugins, you can simply click on the UI element to trigger a menu that will allow you to edit, unload, or remove the plugin.

The edit button will retrigger the modal for the code editors.
The unload button will stop the plugin and put it into an inactive state. Once unloaded, you can reload it and it'll be put in an active state.
The remove button will stop the plugin and remove it from the list.

0.7.5This screenshot was taken in version: 0.7.5

Types

You can find the associated types here: