# Enemy Spritesheets Reference

This document describes how to use every enemy spritesheet in `gviewer`. All sheets live under **`static/enemies/`** and are served at **`/enemies/<filename>`**.

## General Conventions

- **Row index**: 0-based. Row 0 is the top row.
- **Frame index**: 0-based within each row. Frames are read left to right.
- **Animation playback**: For each animation, loop frames `0` through `frames - 1` on that row. Use the given `frameWidth` and `frameHeight` to crop each frame from the sheet.
- **Slicing a frame**: From the full image, the frame at column `col` and row `row` is:
  - **Source X**: `col * frameWidth`
  - **Source Y**: `row * frameHeight`
  - **Width**: `frameWidth`
  - **Height**: `frameHeight`
- All sheets use a **black background**; treat black as transparent if needed.

---

## Bug — `bug.png`

| Property | Value |
|----------|--------|
| **Frame size** | 96 × 96 px |
| **Sheet size** | 1152 × 480 px (12 columns × 5 rows) |
| **Columns** | 12 |
| **Rows** | 5 |

### Animations

| Row (0-based) | Animation name | Frames | Description |
|---------------|----------------|--------|-------------|
| 0 | Idle | 8 | Standing / idle loop |
| 1 | Movement | 8 | Walking / moving |
| 2 | Hit | 8 | Reacting to being hit |
| 3 | Attack | 8 | Attack animation |
| 4 | Death | 12 | Death; uses full row width |

---

## Cyclops — `cyclops.png`

| Property | Value |
|----------|--------|
| **Frame size** | 96 × 96 px |
| **Sheet size** | 1728 × 480 px (18 columns × 5 rows) |
| **Columns** | 18 |
| **Rows** | 5 |

### Animations

| Row (0-based) | Animation name | Frames | Description |
|---------------|----------------|--------|-------------|
| 0 | Idle | 8 | Idle / floating |
| 1 | Movement | 8 | Moving |
| 2 | Hit | 8 | Hit reaction |
| 3 | Attack | 8 | Attack (e.g. beam) |
| 4 | Death | 18 | Death; full row |

---

## Egghead — `Egghead.png`

| Property | Value |
|----------|--------|
| **Frame size** | 72 × 68 px |
| **Sheet size** | 1440 × 340 px (20 columns × 5 rows) |
| **Columns** | 20 |
| **Rows** | 5 |

### Animations

| Row (0-based) | Animation name | Frames | Description |
|---------------|----------------|--------|-------------|
| 0 | Idle | 7 | Idle |
| 1 | Moving | 8 | Movement |
| 2 | Attack | 14 | Attack |
| 3 | Hit | 8 | Hit reaction |
| 4 | Death | 20 | Death; full row width |

---

## Eye — `eye.png`

| Property | Value |
|----------|--------|
| **Frame size** | 96 × 96 px |
| **Sheet size** | 1536 × 480 px (16 columns × 5 rows) |
| **Columns** | 16 |
| **Rows** | 5 |

### Animations

| Row (0-based) | Animation name | Frames | Description |
|---------------|----------------|--------|-------------|
| 0 | Idle | 8 | Idle |
| 1 | Moving | 8 | Moving |
| 2 | Hit | 8 | Hit reaction |
| 3 | Attack | 8 | Attack |
| 4 | Death | 16 | Death; full row |

---

## Float Guy — `FloatGuy.png`

| Property | Value |
|----------|--------|
| **Frame size** | 134 × 134 px |
| **Sheet size** | 2546 × 670 px (19 columns × 5 rows) |
| **Columns** | 19 |
| **Rows** | 5 |

### Animations

| Row (0-based) | Animation name | Frames | Description |
|---------------|----------------|--------|-------------|
| 0 | Idle | 8 | Idle / hovering |
| 1 | Moving | 8 | Moving |
| 2 | Attack | 9 | Attack |
| 3 | Hit | 8 | Hit reaction |
| 4 | Death | 19 | Death; full row |

---

## Licky — `licky.png`

| Property | Value |
|----------|--------|
| **Frame size** | 126 × 77 px |
| **Sheet size** | 2268 × 385 px (18 columns × 5 rows) |
| **Columns** | 18 |
| **Rows** | 5 |

### Animations

| Row (0-based) | Animation name | Frames | Description |
|---------------|----------------|--------|-------------|
| 0 | Idle | 4 | Idle |
| 1 | Moving | 4 | Moving |
| 2 | Hit | 8 | Hit reaction |
| 3 | Attack | 10 | Attack (e.g. tongue) |
| 4 | Death | 18 | Death; full row |

---

## Purpdog — `purpdog.png`

| Property | Value |
|----------|--------|
| **Frame size** | 116 × 74 px |
| **Sheet size** | 1740 × 370 px (15 columns × 5 rows) |
| **Columns** | 15 |
| **Rows** | 5 |

### Animations

| Row (0-based) | Animation name | Frames | Description |
|---------------|----------------|--------|-------------|
| 0 | Idle | 4 | Idle |
| 1 | Moving | 4 | Moving |
| 2 | Attack | 9 | Attack |
| 3 | Hit | 7 | Hit reaction |
| 4 | Death | 15 | Death; full row |

---

## Rex — `rex.png`

| Property | Value |
|----------|--------|
| **Frame size** | 96 × 96 px |
| **Sheet size** | 1536 × 480 px (16 columns × 5 rows) |
| **Columns** | 16 |
| **Rows** | 5 |

### Animations

| Row (0-based) | Animation name | Frames | Description |
|---------------|----------------|--------|-------------|
| 0 | Idle | 8 | Idle |
| 1 | Moving | 8 | Moving |
| 2 | Hit | 8 | Hit reaction |
| 3 | Attack | 8 | Attack |
| 4 | Death | 16 | Death; full row |

---

## Slime — `slime.png`

| Property | Value |
|----------|--------|
| **Frame size** | 96 × 96 px |
| **Sheet size** | 1440 × 480 px (15 columns × 5 rows) |
| **Columns** | 15 |
| **Rows** | 5 |

### Animations

| Row (0-based) | Animation name | Frames | Description |
|---------------|----------------|--------|-------------|
| 0 | Idle | 8 | Idle |
| 1 | Moving | 8 | Moving |
| 2 | Hit | 8 | Hit reaction |
| 3 | Attack | 8 | Attack |
| 4 | Death | 15 | Death; full row |

---

## Multieye — `multieye.png`

| Property | Value |
|----------|--------|
| **Frame size** | 96 × 96 px |
| **Sheet size** | 1728 × 480 px (18 columns × 5 rows) |
| **Columns** | 18 |
| **Rows** | 5 |

### Animations

| Row (0-based) | Animation name | Frames | Description |
|---------------|----------------|--------|-------------|
| 0 | Idle | 8 | Idle / floating |
| 1 | Moving | 8 | Moving |
| 2 | Hit | 8 | Hit reaction |
| 3 | Attack | 8 | Attack (e.g. projectile) |
| 4 | Death | 18 | Death; full row |

---

## Quick reference: frame dimensions only

| Enemy    | Filename     | frameWidth | frameHeight | Rows | Max frames/row |
|----------|--------------|------------|-------------|------|-----------------|
| Bug      | bug.png      | 96         | 96          | 5    | 12              |
| Cyclops  | cyclops.png  | 96         | 96          | 5    | 18              |
| Egghead  | Egghead.png  | 72         | 68          | 5    | 20              |
| Eye      | eye.png      | 96         | 96          | 5    | 16              |
| Float Guy| FloatGuy.png | 134        | 134         | 5    | 19              |
| Licky    | licky.png    | 126        | 77          | 5    | 18              |
| Purpdog  | purpdog.png  | 116        | 74          | 5    | 15              |
| Rex      | rex.png      | 96         | 96          | 5    | 16              |
| Slime    | slime.png    | 96         | 96          | 5    | 15              |
| Multieye | multieye.png | 96         | 96          | 5    | 18              |

---

## Using this in code

The live config is in **`src/routes/enemies/+page.svelte`** in the `ENEMIES` array. Each entry can have an `animation` object:

```ts
animation: {
  frameWidth: number,
  frameHeight: number,
  animations: [
    { name: string, row: number, frames: number },
    // ...
  ]
}
```

To play an animation: use `row` as the 0-based row index, and loop from frame index `0` to `frames - 1` on that row, with each frame being `frameWidth` × `frameHeight` pixels. The app uses `$lib/components/AnimatedSprite.svelte` for playback; pass `rowIndex`, `frameCount`, `frameWidth`, and `frameHeight` from the animation config.
