# Publishing

Publishing uploads one Visual Script class and uses its attributes to create or update a Registry listing. Start the upload from the script's context menu in Unity.

!!! info "Sign in before uploading"
    Publishing requires a free account and a Unity Access Token on the current machine. Complete the [Unity Access Token](access-token.md) setup first; otherwise, the upload dialog offers to open the sign-in window.

## 1. Write the node

A publishable package contains **one class in one C# file**. The class must use one of these extension points:

| Base | Publishes as |
| :--- | :--- |
| `Instruction` | An Instruction |
| `Condition` | A Condition |
| `Trigger` | A Trigger |
| `IType` implementation | A Signal |

[Extending](../scripting-api/extending/index.md) covers each extension point. For publishing, the class attributes define the listing:

```cs
using System;
using UnityEngine;
using VisualScript.Icons;
using VisualScript.Runtime;

[Title("Log Text")]
[Description("Prints text in the Console")]
[Category("Debug/Log Text")]

[Parameter("Text", "The text to print")]
[Keywords("Print", "Console", "Debug")]

[Version(1, 0, 0)]
[Image(typeof(IconSpeech), ColorTheme.Type.TextLight)]

[Serializable]
public class InstructionAcmeLogText : Instruction
{
    [SerializeField] private GetString m_Text = new GetString();

    protected override string GetTitle(GameObject source) => $"Log {this.m_Text}";

    protected override Awaitable Run(Args args)
    {
        Debug.Log(this.m_Text.Get(args));
        return Done;
    }
}
```

`InstructionAcmeLogText` publishes as an Instruction. Its `[Title]`, `[Description]`, `[Parameter]`, and related attributes provide the metadata that the Registry displays and searches.

## 2. Upload it

1. Select the `.cs` file in Unity's **Project window**.
2. Right-click and choose `Visual Script` &rarr; `Upload to Registry`.

A progress bar appears. When the upload completes, the dialog reports *New package has been successfully created* or *Package has been successfully updated* and provides a button that opens the listing.

!!! info "A successful upload moves the file"
    After a successful upload, Unity moves the script into `Assets/Visual Script/<kind>` and renames it after the package identifier. The Registry uses this location and name to track the package and compare its local and published versions.

## What gets sent

The upload includes the script and the metadata declared by its attributes:

| Attribute | Becomes |
| :--- | :--- |
| `[Title]` | The package name. |
| `[Description]` | The summary shown in search results. |
| `[Category]` | Where it sits in the dropdown after installation. |
| `[Parameter]` | The documented parameters. |
| `[Keywords]` | Search terms. |
| `[Note]` | Caveats shown on the listing. |
| `[Dependency]` | What the node requires, with a link. |
| `[Version]` | The published version. |
| `[Documentation]` | The listing's **Docs** button. |
| `[MadeWithAI]` | The AI flag shown on the listing. |
| `[Get]` / `[Set]` | Whether a Signal reads, writes, or both. |

The upload doesn't include other files, scenes, or project settings.

A package with only `[Title]` can publish, but its search result contains little information. Add the attributes that explain its behavior, parameters, and requirements.

!!! tip "Write for the person searching"
    Registry search matches `[Description]` and `[Keywords]`. Describe the task in the terms a developer would search for: *Rotates an object toward another over time* is more specific than *Custom rotation helper*.

## What can't be uploaded

If the upload is rejected, the dialog identifies the reason:

| Situation | Why |
| :--- | :--- |
| *This script is not supported for Visual Script* | The class doesn't subclass `Instruction`, `Condition`, `Trigger`, or implement `IType`. |
| *Package in this folder are protected and cannot be uploaded* | The file lives under `Packages/`. If you own the code, move a copy into `Assets/` before uploading. |
| *You are not authenticated* | You're signed out on this machine. See [Unity Access Token](access-token.md). |

Modules don't use this upload flow. The Visual Script team publishes and maintains them as packages.

## Before you press upload

!!! warning "Published means public"
    Open the file and check for content that shouldn't be published:

    * Hard-coded paths from your machine.
    * References to types that only exist in your project.
    * API keys, private endpoints, or credentials.
    * Leftover debug logging.
    * A class name that could collide with another package's.

    Prefix the class name with a short vendor tag, such as `InstructionAcmeSpawnWave`, because class names must be unique within a project.

Before sharing the listing, install the published node in an empty project that contains only Visual Script and the node's declared dependencies. Confirm that it compiles and performs the documented behavior.

## After publishing

- **Open the listing** and verify its description, parameters, and dependencies.
- **Add it to a [list](lists.md)** when it belongs with related packages.
- **Share the link** from the documentation, devlog, or tutorial that uses the package.
- **Ship improvements** by incrementing `[Version]` and uploading again. See [Updating](updating.md).

## Where to go next

- **[Updating](updating.md)** — version and maintain the published package.
- **[Lists](lists.md)** — bundle related nodes, including integrations with other Asset Store tools.
- **[Conventions](../scripting-api/conventions.md)** — inspect the complete attribute reference.
