# Custom settings

A custom settings section exposes project-wide configuration in the [Settings window](../../manual/settings/index.md). Use one for values a designer sets once for the entire project.

## Settings types

A repository and asset provide the settings section. Add a drawer when you need a custom layout:

| Piece | Is |
| :--- | :--- |
| **Repository** | The data. A serializable class holding your settings. |
| **Asset** | The container. A `ScriptableObject` wrapping the repository. |
| **Drawer** | Optional. A custom Inspector for the repository. |

## The repository

This repository stores two project-wide values and exposes them as read-only properties:

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

[Serializable] [Repository(ID)]
public class MyRepository : TRepository<MyRepository>
{
    public const string ID = "mygame.settings";

    public override string Id => ID;

    [SerializeField] private float m_DefaultVolume = 0.8f;
    [SerializeField] private bool m_SkipIntro;

    public float DefaultVolume => this.m_DefaultVolume;
    public bool SkipIntro => this.m_SkipIntro;
}
```

The `[Repository]` attribute's ID identifies the section and names the asset created in `Resources`. It must be unique, so prefix it with the project or package name.

Override `OnInitialize()` for work that must happen the first time the repository is loaded at runtime.

## The asset

This asset defines how the repository appears in the Settings window:

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

public class MyAsset : TAsset<MyRepository>
{
    public override IIcon Icon => new IconCog(ColorTheme.Type.TextLight);
    public override string Name => "My Game";
    public override int Priority => 20;
}
```

`MyAsset` names and orders the sidebar entry that opens `MyRepository`.

| Member | Controls |
| :--- | :--- |
| `Icon` | The sidebar icon. |
| `Name` | The sidebar label. |
| `Priority` | Sort order in the sidebar. Lower appears higher. |
| `IsFullScreen` | Whether the panel uses the full window width. |

The editor creates the asset on first load. No scene or manual asset placement is required.

## Reading settings at runtime

Resolve the repository through `Settings.Get<T>()` and read its public properties:

```cs
MyRepository settings = Settings.Get<MyRepository>();
float volume = settings.DefaultVolume;
```

The repository is loaded once and cached. In the editor outside Play mode it's re-read each time, so changes in the Inspector take effect immediately.

!!! warning "Settings are read-only at runtime"
    A repository is authored data, like any other asset. Writing to it at runtime works in the editor, silently persists into your project, and does nothing in a build.

    Anything the player changes belongs in a [Global Variable](../../manual/variables/global-variables.md) saved to the **Shared** location — not in settings.

## A custom drawer

Without a custom drawer, Unity draws the repository's fields with its default Inspector.

For a custom layout, write a `PropertyDrawer` for the repository type. Return its `VisualElement` from `CreatePropertyGUI`; the layout implementation is omitted here:

```cs
[CustomPropertyDrawer(typeof(MyRepository))]
public class MyRepositoryDrawer : PropertyDrawer
{
    public override VisualElement CreatePropertyGUI(SerializedProperty property)
    {
        // …
    }
}
```

Unity uses `MyRepositoryDrawer` instead of the default field layout whenever the repository is drawn.

## What belongs here

Use settings for authored project configuration, and keep runtime or per-object values in the systems that own them:

| Settings | Not settings |
| :--- | :--- |
| Project-wide defaults | Per-object configuration |
| Asset references a system needs | Runtime state |
| Feature toggles decided at build time | Player preferences |
| Tuning values shared across scenes | Anything that changes during gameplay |

Use a repository when every scene needs the same value. Per-object values belong on the object instead.

## Version control

Commit the generated asset under `Resources` so the team shares the same project configuration.

Changes to that asset affect the whole project. Personal preferences belong in [Editor settings](../../manual/settings/editor.md), which Unity stores per user.

## Where to go next

- **[Settings window](../../manual/settings/index.md)** — inspect the designer-facing configuration.
- **[Conventions](../conventions.md)** — apply serialization and naming rules to the repository.
- **[Global Variables](../../manual/variables/global-variables.md)** — store player-controlled values that change at runtime.
