> For the complete documentation index, see [llms.txt](https://viridian-games.gitbook.io/pixel-palette/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://viridian-games.gitbook.io/pixel-palette/core-components/animation-system/animation-system-technical-details.md).

# Animation System Technical Details

Every frame is a full snapshot of the entire layer stack at a point in time. **AnimationFrame** stores a deep copy of every layer's `RawPixels`, plus per-layer `Visible` and `Opacity` arrays.

#### Frame Data

```
AnimationFrame
  ├─ List<Color32[]> layerPixels   ← deep copy of every layer's pixels
  ├─ List<bool>       layerVisible  ← visibility per layer
  ├─ List<float>      layerOpacity  ← opacity per layer (0–1)
  └─ string           name          ← display name ("Frame 1", etc.)
```

`Clone()` deep-copies all pixel arrays so frames are completely independent — editing one frame never affects another.

#### Frame Operations

<table><thead><tr><th width="238.6666259765625">Method</th><th>What it does</th></tr></thead><tbody><tr><td><code>SwitchToFrame(i)</code></td><td>Saves current frame state, restores target frame's layers onto the canvas</td></tr><tr><td><code>AddFrame()</code></td><td>Clones the current frame, inserts after it, switches to the new frame</td></tr><tr><td><code>DuplicateFrame(i)</code></td><td>Clones frame at index, inserts copy after it (doesn't switch)</td></tr><tr><td><code>DeleteFrame(i)</code></td><td>Removes the frame (minimum 1 kept). Adjusts <code>currentFrameIndex</code></td></tr><tr><td><code>MoveFrame(from, to)</code></td><td>Reorders frames. <code>currentFrameIndex</code> follows the moved frame</td></tr><tr><td><code>SaveCurrentFrame()</code></td><td>Copies live layer data into the current frame's storage</td></tr></tbody></table>

#### Frame Switching Flow

```
SwitchToFrame(2):
  1. SaveCurrentFrame()    → overwrite frame[oldIndex] with current layer data
  2. RestoreLayersFromFrame(frame[2]) → copy frame[2]'s pixel arrays into live layers
  3. Upload all layer textures to GPU via SetPixels32 + Apply
  4. QueueCompositeRefresh of the full canvas
  5. Fire OnFrameChanged(2)
```

`SaveCurrentFrame` must be called before any direct layer editing or frame switch to preserve changes.

#### Layer Count Sync

When layers are added/removed after frames exist, `SyncFrameCount()` pads each frame with new layer data (copied from the live layer manager). This keeps all frames matching the current layer count.

#### Playback

`Update()` runs when `isPlaying`:

```
playTimer += Time.deltaTime
if playTimer >= 1/fps:
  playTimer -= 1/fps
  next = (currentFrameIndex + 1) % FrameCount
  SaveCurrentFrame()
  RestoreLayersFromFrame(next)
  OnFrameChanged(next)
```

Cycles through frames at the configured FPS (default 12, min 1). Wraps around when reaching the last frame.

#### Onion Skinning

During `RefreshComposite`, after layer blending and before GPU upload:

```
ApplyOnionSkin(dirtyRect, pixels):
  onionIndex = currentFrameIndex + onionOffset   (default -1 = previous frame)
  if onionIndex is valid and different from current:
    GetFrameComposite(onionIndex)                ← composite of that frame
    for each pixel in dirty rect:
      blend into composited pixels at 30% opacity
```

This shows the previous/next frame as a faded ghost overlay. Toggle on/off via `OnionSkinEnabled`.

#### Frame Compositing (for Export/Thumbnails)

`GetFrameComposite(frameIndex)` alpha-blends all layers of a saved frame into a single `Color32[]` — independent of the live canvas state. Used for:

* Frame thumbnails in the UI (`GenerateFrameTexture`)
* Spritesheet export


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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://viridian-games.gitbook.io/pixel-palette/core-components/animation-system/animation-system-technical-details.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.
