# Арт-пайплайн: генерация пиксель-арта из кода

Весь арт первой игры генерируется кодом: `apps/game/tools/pixelart/*.mjs` рисуют спрайты
на собственном Canvas и кодируют PNG без сторонних зависимостей (`node:zlib` +
свой CRC32). Позже генератор можно заменить на рисованный арт — движку всё равно,
откуда текстуры.

## Файлы

| Файл | Что делает |
|---|---|
| `apps/game/tools/pixelart/palette.mjs` | Палитра из 32 цветов (hex + RGBA) |
| `apps/game/tools/pixelart/canvas.mjs` | Canvas: set/get пикселя, `fillDiamond` (изо-ромб), `fromAscii`, seeded rng |
| `apps/game/tools/pixelart/png.mjs` | `encodePng` — сборка PNG вручную |
| `apps/game/tools/pixelart/gen.mjs` | Генерация всех спрайтов игры → `apps/game/assets/` |

## Запуск

```bash
npm run art     # node apps/game/tools/pixelart/gen.mjs — перегенерировать все PNG
```

Выходные файлы кладутся в `apps/game/assets/` и грузятся в игре по ключам
(`tiles/grass`, `chars/hero_down_1`, ...). Список ключей — в `apps/game/src/Game.ts`.

## Палитра и правила

- 32 цвета, тёмная холодная база; **тёплые цвета — только живое** (герой, NPC,
  колокольчики, огонь). Это правило сеттинга «Пепельных лугов» — см. `docs/art-style.md`.
- Размеры: тайл 32×16 (изометрия 2:1), персонаж ~16×24, высокое дерево 32×48.
- Пиксель перо = 1 виртуальный пиксель; никаких сглаженных краёв — контуры ступенчатые.

## ASCII-спрайты

Персонажи задаются ASCII-картами (символ → цвет палитры) — читается и правится
прямо в коде:

```js
const heroDown = fromAscii(`
    ....0000....
    ...011111...
    ...
`, { '0': 'P4', '1': 'F2' });
```

## Процедурные тайлы

Тайлы земли рисуются шумом (seeded rng) + ромбы `fillDiamond` (свет — верхние склоны,
тень — нижние). Дерево: «облачная» крона из перекрывающихся окружностей, ствол,
свисающий кабель — детали сеттинга.

## Атласы

Если спрайтов много (анимации), генератор может собрать атлас: кадры в один PNG +
Spritesheet JSON. Формат Pixi:

```js
const atlas = {
    frames: {
        hero_walk_1: { frame: { x: 0, y: 0, w: 16, h: 24 } },
        hero_walk_2: { frame: { x: 16, y: 0, w: 16, h: 24 } }
    },
    meta: { image: 'hero_sheet.png', size: { w: 32, h: 24 }, scale: 1 }
};
```

Загрузка в игре — `assets.loadAtlas('chars/hero_sheet')`, кадры — `assets.frames(key, 'hero_walk')`.

## Замена генератора на рисованный арт

Движку не важно происхождение текстур. Чтобы перейти на рисованный арт:

1. Рисуете PNG того же размера (или атлас + JSON) в `apps/game/assets/`.
2. Ключи ассетов не меняются — код игры не трогается.
3. Палитру соблюдаете, чтобы арт не выбивался из сеттинга (`docs/art-style.md`).

Aseprite/Piskel: экспорт в PNG с теми же именами файлов, что даёт генератор.