# Distributing Predictors

Predictors are designed to be shared. Whether you choose to open-source your predictor or sell it, here are some general guidelines:

## Packaging Predictors

We highly recommend packaging a predictor with the following layout:

```javascript
model-name/             // Package name should be lowercase and dasherized
│
├─ Runtime/
│  ├─ MLPackage.asmdef  // Assembly definition for your package scripts
│  ├─ Predictor.cs      // Model predictor
│  ├─ ...
│     
├─ Sample/ 
│  ├─ example.unity     // Example scene demonstrating model
│  ├─ ...
│
│
├─ README.md            // Readme explaining how the predictor is used
├─ LICENSE.md           // License if applicable
```

{% hint style="info" %}
Your package assembly definition should reference `NatML.ML` for access to NatML classes and interfaces.
{% endhint %}

{% hint style="success" %}
You can use [NatML Hub](https://hub.natsuite.io/predictor/create) to generate a template predictor package that already has this layout, saving you time.
{% endhint %}

## Publishing on NatML

All public predictors on [NatML Hub](https://hub.natsuite.io) must pass a review process to ensure that they meet developer experience and performance standards. Below are the criteria used in the review process:

### Developer Experience

The foundational principle in designing the developer experience is to **reduce cognitive load**. The developer should not have to learn many--or ideally, any--new concepts in order to use your predictor.

{% hint style="warning" %}
Try to keep the number of public methods in your predictor at a minimum. **Ideally, there should only be one public method**: `Predict`.
{% endhint %}

The `README` should be the entrypoint for developers. Keeping in line with the considerations above, the `README` should very quickly discuss how the predictor is used, [with code snippets](https://www.markdownguide.org/extended-syntax/#fenced-code-blocks).

{% hint style="success" %}
Most developers will simply not read the `README`, so keeping it short and sweet would increase their chances of actually reading it.
{% endhint %}

### API Design

NatML predictors have a typical usage pattern:

1. Create the predictor.
2. Call [`Predict`](https://docs.natml.ai/unity/api/imlpredictor#making-predictions) with one or more features.
3. Use the output(s) directly, or call a post-processing method on the output(s).

{% hint style="danger" %}
Predictors **must not** deviate from this usage pattern. Specifically, the predictor must not have any public methods for feature pre- or post-processing.
{% endhint %}

{% hint style="warning" %}
Predictors should be thread-safe, and should support background processing. As a result, the `Predict` method should not use any Unity APIs which [cannot be used from background threads](https://stackoverflow.com/a/41333540/13395268). This includes familiar classes like `Texture2D`, `RenderTexture`, `ComputeShader`, and `Job`.
{% endhint %}

{% hint style="info" %}
If your predictor requires pre-processing on the main thread, you should instead create a `CustomFeature` class which derives from [`MLFeature`](https://docs.natml.ai/unity/api/mlfeature) and implements `IMLEdgeFeature` or `IMLCloudFeature`.
{% endhint %}

If your predictor requires further post-processing before the outputs can be used, then your predictor should return an instance of an inner class. This inner class should expose a method to perform the required post-processing. This is a common pattern for computer vision predictors that output an image:

```javascript
// Predictor outputs an inner class
Predictor.Output output = predictor.Predict(...);
// Then developer performs post-processing on the output
RenderTexture result = ...;
output.PostProcessIntoRenderTexture(result);
```

{% hint style="success" %}
One advantage of this pattern is that the developer can run your post-processing code on the main thread, giving you full access to Unity API's.
{% endhint %}

Finally, all public methods **must** be annotated with [XML documentation](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/xmldoc/). This is critical for developers to know how to use different methods in your classes.

{% hint style="info" %}
Most code editors have intellisense which automatically display the XML docs to the developer. This significantly increases developer productivity.
{% endhint %}

### Performance

Predictors should be written for maximum performance and minimal overhead. Predictors, along with any pre- or post-processors, **must not** use any performance-degrading API's that might have significant adverse effects on the entire app.

{% hint style="danger" %}
Predictor packages that use GPU readbacks (`Texture2D.ReadPixels`,  `ComputeBuffer.GetData`) or Disk IO will be **immediately rejected.**
{% endhint %}
