# 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`](/unity/api/imlpredictor.md#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`](/unity/api/mlfeature.md) 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 %}


---

# 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.natml.ai/unity/authoring/distribute.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.
