> For the complete documentation index, see [llms.txt](https://wise-shepherd-games.gitbook.io/theia-ecs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wise-shepherd-games.gitbook.io/theia-ecs/world-level-state/resources.md).

# Resources

Immutable managed reference-type store

Resources are **an immutable,&#x20;*****enum-keyed*****&#x20;store for managed reference-type data**. They are the **bridge between the blittable component world and the managed asset world**.

Components must be strictly blittable, so **they cannot hold managed references directly**. A component that needs to reference a sprite sheet, an audio clip, or any other managed asset cannot store it inline. Resources solve this: **the managed data lives on the world**, keyed by a dense `enum`, and the component holds only a small `enum` field. **The lookup is O(1) via bare array indexing**.

#### Enum Key Constraints

**The key type must be an** `int`**-backed** `enum` **with dense values starting at zero**. The framework enforces this once per closed generic at static construction time:

```csharp
public enum DwarfSpriteKind : int
{
    Idle    = 0,
    Walk    = 1,
    Mine    = 2,
    Combat  = 3,
}
```

#### Creating a Resource Store

Resource stores are created on the world via `CreateResource<TKey, TData>`. Every `enum` value must be registered exactly once; the call throws before committing any state if validation fails. `CreateResource` returns `this` for fluent chaining:

```csharp
world
    .CreateResource<DwarfSpriteKind, Texture2D>(
        new ResourcesEntries<DwarfSpriteKind, Texture2D>() { Key = DwarfSpriteKind.Idle,   Data = [idle1, idle2] },
        new ResourcesEntries<DwarfSpriteKind, Texture2D>() { Key = DwarfSpriteKind.Walk,   Data = [walk1, walk2] },
        new ResourcesEntries<DwarfSpriteKind, Texture2D>() { Key = DwarfSpriteKind.Mine,   Data = [mine1, mine2] },
        new ResourcesEntries<DwarfSpriteKind, Texture2D>() { Key = DwarfSpriteKind.Combat, Data = [combat1, combat2] }
    )
    .CreateResource<SoundKind, AudioClip>(
        new ResourcesEntries<SoundKind, AudioClip>() { Key = SoundKind.AxeSwing, Data = [axeSwingClip] },
        new ResourcesEntries<SoundKind, AudioClip>() { Key = SoundKind.FootStep, Data = [footStepClip] }
    );
```

**Resources are immutable after creation**. There are no public setters on a `Resources<TKey, TData>` instance; lookups are the only operation available after world setup.

#### Accessing Resources

Retrieve the store via `world.GetResource<TKey, TData>()`, then look up by key:

```csharp
Resources<DwarfSpriteKind, Texture2D> sprites =
    world.GetResource<DwarfSpriteKind, Texture2D>();

/* Returns a ReadOnlySpan<Texture2D> for the key */
ReadOnlySpan<Texture2D> idleFrames = sprites.Get(DwarfSpriteKind.Idle);

/* Returns a ref readonly to a specific element */
ref readonly Texture2D firstFrame = ref sprites.Get(DwarfSpriteKind.Idle, 0);
```

A component holds the key; the system or callback looks up the asset at runtime:

```csharp
public struct Dwarf
{
    public DwarfSpriteKind CurrentAnimation;
}

public ref struct RenderForEach : IForEach<Dwarf>
{
    public ReadOnlySpan<Texture2D> IdleFrames;
    public ReadOnlySpan<Texture2D> WalkFrames;
    public ReadOnlySpan<Texture2D> MineFrames;
    public ReadOnlySpan<Texture2D> CombatFrames;

    public void Execute(ref Dwarf dwarf)
    {
        ReadOnlySpan<Texture2D> frames = dwarf.CurrentAnimation switch
        {
            DwarfSpriteKind.Idle   => IdleFrames,
            DwarfSpriteKind.Walk   => WalkFrames,
            DwarfSpriteKind.Mine   => MineFrames,
            DwarfSpriteKind.Combat => CombatFrames,
            _                      => IdleFrames,
        };

        /* Render current animation frame */
    }
}

/* ... */

Resources<DwarfSpriteKind, Texture2D> sprites =
    world.GetResource<DwarfSpriteKind, Texture2D>();

RenderForEach forEach = new RenderForEach()
{
    IdleFrames   = sprites.Get(DwarfSpriteKind.Idle),
    WalkFrames   = sprites.Get(DwarfSpriteKind.Walk),
    MineFrames   = sprites.Get(DwarfSpriteKind.Mine),
    CombatFrames = sprites.Get(DwarfSpriteKind.Combat),
};

dwarfQuery.ForEach(ref forEach);
```

#### Thread Safety

Reads via `Get` **are safe to perform concurrently from multiple threads**. Writes happen only inside `CreateResource`, which is expected to run during world setup before any system reads from the store.

#### Serialization

**Resource stores are not serialized**. They hold managed reference-type data that **is expected to be reloaded at startup**.
