> For the complete documentation index, see [llms.txt](https://docs.allout.game/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.allout.game/core-engine-concepts/assets-and-resources.md).

# Textures

Files under `res` are addressed relative to that folder:

```go
icon := get_asset(Texture_Asset, "ui/icon.png");
```

`get_asset` returns null when the path is missing. Keep paths case-correct and check optional assets before using them.

## Texture information

```go
Texture_Asset :: class : Asset {
    get_width           :: method() -> s64;
    get_height          :: method() -> s64;
    get_world_size      :: method() -> v2;
    get_aspect          :: method() -> float;
    get_pivot           :: method() -> v2;
    get_pixels_per_unit :: method() -> float;
    get_uvs             :: method() -> (v2, v2);
}
```

`get_world_size()` returns the source texture dimensions divided by its pixels-per-unit setting. It does not include renderer or attachment scale.

Use `Sprite_Renderer.set_texture` for a world sprite, or pass the texture to `UI.quad` for immediate-mode UI.

## Texture settings

Select a texture in the Assets pane to edit its asset settings, then click **Apply**.

* **Pixels Per Unit** controls its world size.
* **Filter** uses linear sampling by default. Use nearest sampling for pixel art.
* **Wrap Repeat** allows the texture to tile. Also enable **Wrap** on the `Sprite_Renderer`, then adjust its scale and UV offset.
* **Pivot** changes the texture origin.
* **Crop** trims source pixels during preprocessing.

### Nine-slicing

Nine-slicing preserves the corners and borders of a texture while stretching its center. Set **Slice** in left, bottom, right, top order. **Slice Scale** changes the rendered border thickness.

For a `Sprite_Renderer`, set its **Nine Slice** values in the component. For immediate-mode UI, pass the same values through `Quad_Params`:

```go
nine_slice := Texture_Nine_Slice_Data.{
    slice = {25, 40, 25, 25},
    slice_scale = 1
};

UI.quad(rect, panel_texture, params={
    nine_slice = nine_slice
});
```

## Mip assets

Mip assets are smaller versions loaded early and retained under memory pressure.

**Auto Generate Mips** under **Edit → Game Config** includes textures and Spine rigs referenced by the project. Keep it enabled for most games. Explicitly enable **Should Mip** on an asset that is loaded only through a computed path and cannot be found by the reference scan.

When automatic generation is disabled, **Manual Mip Quality** selects a `1/8`, `1/16`, or `1/32` source-size divisor. New projects default to `1/32`.

## Dynamic canvases

`Dynamic_Canvas` is a scene-owned RGBA texture that CSL can modify:

```go
Dynamic_Canvas :: class {
    create    :: proc(width: s64, height: s64, pixels_per_unit: float = 100) -> Dynamic_Canvas;
    destroy   :: method();
    fill      :: method(color: v4);
    set_pixel :: method(x: s64, y: s64, color: v4);
    get_pixel :: method(x: s64, y: s64) -> v4;
    stamp     :: method(from: v2, to: v2, radius: float, color: v4, softness: float = 0.5, opacity: float = 1);

    width: s64 #read_only;
    height: s64 #read_only;
    pixels_per_unit: float #read_only;
}
```

Create the canvas once, assign it to a sprite, and destroy it when its owner ends:

```go
Paint_Surface :: class : Component {
    canvas: Dynamic_Canvas;

    ao_start :: method() {
        canvas = Dynamic_Canvas.create(256, 256);
        canvas.fill({1, 1, 1, 1});
        entity.get_component(Sprite_Renderer).set_canvas(canvas);
    }

    ao_end :: method() {
        canvas.destroy();
    }
}
```

Canvas pixels are synchronized scene state, not client-only state. Update them through the normal shared gameplay path. A canvas is limited to 512×512 pixels; one scene can hold up to 16 canvases and 4 MiB of canvas pixels.
