diff --git a/apps/game/tools/aiart/manifest-b1.json b/apps/game/tools/aiart/manifest-b1.json new file mode 100644 index 0000000..19cb54e --- /dev/null +++ b/apps/game/tools/aiart/manifest-b1.json @@ -0,0 +1,42 @@ +{ + "run": "b1-domain", + "date": "2026-09-06", + "model": "PixelGPT-24×24 (github.com/unstonio/pixelgpt-24x24), 68M декодер, CPU ~22 с/спрайт", + "license": "кода и весов НЕТ (в репо не указана) — в игру нельзя; датасет 20K — CC BY 4.0", + "pipeline": "prompts-b1.txt (seed|имя|промпт|5 ключей палитры) -> gen_pxgpt.py (обусловливание палитрой игры) -> review-b1/*.png (24x24) -> post.mjs (кроп, nearest 16x16, квантизация palette.mjs) -> processed-b1/", + "criterion": ">= 30% годных на доменных интерактивах, где PXG-Tiny отказывала", + "notes": [ + "Отказов нет вообще: модель пробуется рисовать любой конкретный объект (у PXG-Tiny домен давал gate=clarify).", + "Кастомная палитра из 5 цветов игры на запрос работает — стиль совпал на 100%.", + "Главный фактор брака — даунскейл 24→16: колодец/рычаг/прилавок на 24×24 читаются, на 16 разваливаются.", + "Фон часто залит непрозрачным цветом (сундуки) — кроп по альфе не спасает." + ], + "items": [ + { "file": "b1_bell_s1.png", "prompt": "a small bronze bell with a handle", "seed": 227, "match": "good", "note": "колокол читается чётко, бронза" }, + { "file": "b1_bell_s2.png", "prompt": "a small bronze bell with a handle", "seed": 228, "match": "good", "note": "тоже читаемый колокол" }, + { "file": "b1_chest_s1.png", "prompt": "a wooden chest with bronze trim", "seed": 237, "match": "partial", "note": "форма ок, но фон залит жёлтым" }, + { "file": "b1_chest_s2.png", "prompt": "a wooden chest with bronze trim", "seed": 238, "match": "partial", "note": "фон залит; у PXG-Tiny сундук был чище" }, + { "file": "b1_counter_s1.png", "prompt": "a wooden shop counter with goods", "seed": 231, "match": "partial", "note": "на 24×24 прилавок читается, на 16 разваливается" }, + { "file": "b1_counter_s2.png", "prompt": "a wooden shop counter with goods", "seed": 232, "match": "bad", "note": "тёмная каша" }, + { "file": "b1_door_s1.png", "prompt": "an old wooden door with iron hinges", "seed": 233, "match": "good", "note": "дверь с панелями и ручкой" }, + { "file": "b1_door_s2.png", "prompt": "an old wooden door with iron hinges", "seed": 234, "match": "good", "note": "дверь с перекладинами" }, + { "file": "b1_hearth_s1.png", "prompt": "a stone fireplace with burning fire", "seed": 229, "match": "good", "note": "камин с огнём, тёплый F0 уместен" }, + { "file": "b1_hearth_s2.png", "prompt": "a stone fireplace with burning fire", "seed": 230, "match": "partial", "note": "силуэт есть, огонь слабый" }, + { "file": "b1_lever_s1.png", "prompt": "a rusty metal lever on a stone base", "seed": 225, "match": "partial", "note": "на 24×24 рычаг на подставке, на 16 — палка" }, + { "file": "b1_lever_s2.png", "prompt": "a rusty metal lever on a stone base", "seed": 226, "match": "bad", "note": "похоже на лимон" }, + { "file": "b1_mote_s1.png", "prompt": "a glowing wisp of light", "seed": 235, "match": "good", "note": "светящийся ореол с ядром — как моты" }, + { "file": "b1_mote_s2.png", "prompt": "a glowing wisp of light", "seed": 236, "match": "partial", "note": "ядро тёмное, свечение по краю" }, + { "file": "b1_signpost_s1.png", "prompt": "a wooden signpost with a small sign board", "seed": 223, "match": "good", "note": "столб с доской-указателем" }, + { "file": "b1_signpost_s2.png", "prompt": "a wooden signpost with a small sign board", "seed": 224, "match": "good", "note": "столб с двумя досками" }, + { "file": "b1_well_s1.png", "prompt": "a stone well with a wooden roof", "seed": 221, "match": "partial", "note": "на 24×24 good (кладка, проём) — убил даунскейл 24→16" }, + { "file": "b1_well_s2.png", "prompt": "a stone well with a wooden roof", "seed": 222, "match": "bad", "note": "серая клякса" } + ], + "verdict": { + "good": 8, + "partial": 7, + "bad": 3, + "total": 18, + "goodShare": "44%", + "conclusion": "Критерий 30% выполнен; главное — отказов нет, доменные интерактивы модель рисует (PXG-Tiny отказывала). Но: качество неровное, даунскейл 24→16 губит деталь (колодец good на 24×24), фон часто залит, ровно 5 цветов на спрайт, ~22 с/спрайт на CPU. Решающее ограничение — лицензии на код/веса нет, в игру нельзя. Итог: локальные GPT-пиксель-модели домен тянут частично (PXG-Tiny — инвентарь/декор, PixelGPT — простые объекты на 24×24); для критичных интерактивов — RD API (платный) или ручной арт. Дообучение под игру решением не считается (отвергнуто)." + } +} \ No newline at end of file diff --git a/apps/game/tools/aiart/post.mjs b/apps/game/tools/aiart/post.mjs index 9715d56..60086f7 100644 --- a/apps/game/tools/aiart/post.mjs +++ b/apps/game/tools/aiart/post.mjs @@ -1,9 +1,9 @@ /** * Пост-обработка AI-спрайтов «Пепельных лугов» — сценарий над жанронезависимым * @rpg/engine/tools/imaging.mjs (декодер/кроп/квантизация — там). - * Запуск: node apps/game/tools/aiart/post.mjs <каталог с PNG> - * → рядом ../processed/*.png (кроп по альфе, квантизация в палитру) - * → ../processed/_sheet.png (обзорный лист для апрува) + * Запуск: node apps/game/tools/aiart/post.mjs <каталог с PNG> [каталог вывода=processed] + * → <вывод>/*.png (кроп по альфе, квантизация в палитру) + * → <вывод>/_sheet.png (обзорный лист для апрува) * * AI-вывод — только сырьё: в игру попадает после ручного апрува (манифест). */ @@ -15,8 +15,9 @@ import { PALETTE } from '../pixelart/palette.mjs'; const REVIEW = process.argv[2] ?? 'review'; +const OUT_NAME = process.argv[3] ?? 'processed'; const HERE = fileURLToPath(new URL('.', import.meta.url)); -const OUT = join(HERE, 'processed'); +const OUT = join(HERE, OUT_NAME); const SIZE = 16; // целевой размер спрайта (арт-библия) /** Палитра игры как массив [r,g,b] для квантизации. */ diff --git a/apps/game/tools/aiart/processed-b1/_sheet.png b/apps/game/tools/aiart/processed-b1/_sheet.png new file mode 100644 index 0000000..0b93f7e --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/_sheet.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_bell_s1.png b/apps/game/tools/aiart/processed-b1/b1_bell_s1.png new file mode 100644 index 0000000..53994eb --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_bell_s1.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_bell_s2.png b/apps/game/tools/aiart/processed-b1/b1_bell_s2.png new file mode 100644 index 0000000..d10130a --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_bell_s2.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_chest_s1.png b/apps/game/tools/aiart/processed-b1/b1_chest_s1.png new file mode 100644 index 0000000..b91e10c --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_chest_s1.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_chest_s2.png b/apps/game/tools/aiart/processed-b1/b1_chest_s2.png new file mode 100644 index 0000000..dba9c40 --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_chest_s2.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_counter_s1.png b/apps/game/tools/aiart/processed-b1/b1_counter_s1.png new file mode 100644 index 0000000..dee7604 --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_counter_s1.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_counter_s2.png b/apps/game/tools/aiart/processed-b1/b1_counter_s2.png new file mode 100644 index 0000000..2f51d9e --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_counter_s2.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_door_s1.png b/apps/game/tools/aiart/processed-b1/b1_door_s1.png new file mode 100644 index 0000000..3fe9340 --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_door_s1.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_door_s2.png b/apps/game/tools/aiart/processed-b1/b1_door_s2.png new file mode 100644 index 0000000..1befd14 --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_door_s2.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_hearth_s1.png b/apps/game/tools/aiart/processed-b1/b1_hearth_s1.png new file mode 100644 index 0000000..69c3284 --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_hearth_s1.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_hearth_s2.png b/apps/game/tools/aiart/processed-b1/b1_hearth_s2.png new file mode 100644 index 0000000..b9ac7e3 --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_hearth_s2.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_lever_s1.png b/apps/game/tools/aiart/processed-b1/b1_lever_s1.png new file mode 100644 index 0000000..30b49c5 --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_lever_s1.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_lever_s2.png b/apps/game/tools/aiart/processed-b1/b1_lever_s2.png new file mode 100644 index 0000000..b61b9d7 --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_lever_s2.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_mote_s1.png b/apps/game/tools/aiart/processed-b1/b1_mote_s1.png new file mode 100644 index 0000000..9f42c2a --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_mote_s1.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_mote_s2.png b/apps/game/tools/aiart/processed-b1/b1_mote_s2.png new file mode 100644 index 0000000..6250da8 --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_mote_s2.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_signpost_s1.png b/apps/game/tools/aiart/processed-b1/b1_signpost_s1.png new file mode 100644 index 0000000..efb564c --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_signpost_s1.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_signpost_s2.png b/apps/game/tools/aiart/processed-b1/b1_signpost_s2.png new file mode 100644 index 0000000..7de5fbf --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_signpost_s2.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_well_s1.png b/apps/game/tools/aiart/processed-b1/b1_well_s1.png new file mode 100644 index 0000000..8126474 --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_well_s1.png Binary files differ diff --git a/apps/game/tools/aiart/processed-b1/b1_well_s2.png b/apps/game/tools/aiart/processed-b1/b1_well_s2.png new file mode 100644 index 0000000..822baf3 --- /dev/null +++ b/apps/game/tools/aiart/processed-b1/b1_well_s2.png Binary files differ diff --git a/apps/game/tools/aiart/prompts-b1.txt b/apps/game/tools/aiart/prompts-b1.txt new file mode 100644 index 0000000..a984fd7 --- /dev/null +++ b/apps/game/tools/aiart/prompts-b1.txt @@ -0,0 +1,22 @@ +# B1: доменные интерактивы «Пепельных лугов» через PixelGPT-24×24 (5 цветов из палитры). +# Формат: seed|имя|промпт|5 ключей палитры (первый — самый тёмный). +# С 220 по 227 — доменные объекты (вне 38 классов PXG-Tiny, отказ в B0); +# 228-229 — контрольные (PXG-Tiny их уже умела — для сравнения качества). +221|b1_well_s1|a stone well with a wooden roof|P2,P4,P6,P5H,R1 +222|b1_well_s2|a stone well with a wooden roof|P2,P4,P6,P5H,R1 +223|b1_signpost_s1|a wooden signpost with a small sign board|R1,R2,P3,P5,P5H +224|b1_signpost_s2|a wooden signpost with a small sign board|R1,R2,P3,P5,P5H +225|b1_lever_s1|a rusty metal lever on a stone base|R0,R1,R2,B0,P3 +226|b1_lever_s2|a rusty metal lever on a stone base|R0,R1,R2,B0,P3 +227|b1_bell_s1|a small bronze bell with a handle|B0,B1,B2,R1,P2 +228|b1_bell_s2|a small bronze bell with a handle|B0,B1,B2,R1,P2 +229|b1_hearth_s1|a stone fireplace with burning fire|P2,P3,R0,R1,F0 +230|b1_hearth_s2|a stone fireplace with burning fire|P2,P3,R0,R1,F0 +231|b1_counter_s1|a wooden shop counter with goods|R1,R2,P2,P4,B0 +232|b1_counter_s2|a wooden shop counter with goods|R1,R2,P2,P4,B0 +233|b1_door_s1|an old wooden door with iron hinges|R0,R1,R2,P3,B0 +234|b1_door_s2|an old wooden door with iron hinges|R0,R1,R2,P3,B0 +235|b1_mote_s1|a glowing wisp of light|P6,P5H,B1,B2,W2 +236|b1_mote_s2|a glowing wisp of light|P6,P5H,B1,B2,W2 +237|b1_chest_s1|a wooden chest with bronze trim|R1,B0,B1,B2,P3 +238|b1_chest_s2|a wooden chest with bronze trim|R1,B0,B1,B2,P3 \ No newline at end of file diff --git a/apps/game/tools/aiart/review-b1/b1_bell_s1.png b/apps/game/tools/aiart/review-b1/b1_bell_s1.png new file mode 100644 index 0000000..4fc73ae --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_bell_s1.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_bell_s2.png b/apps/game/tools/aiart/review-b1/b1_bell_s2.png new file mode 100644 index 0000000..7d8fd4f --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_bell_s2.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_chest_s1.png b/apps/game/tools/aiart/review-b1/b1_chest_s1.png new file mode 100644 index 0000000..236eedc --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_chest_s1.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_chest_s2.png b/apps/game/tools/aiart/review-b1/b1_chest_s2.png new file mode 100644 index 0000000..cb69c03 --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_chest_s2.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_counter_s1.png b/apps/game/tools/aiart/review-b1/b1_counter_s1.png new file mode 100644 index 0000000..480011f --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_counter_s1.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_counter_s2.png b/apps/game/tools/aiart/review-b1/b1_counter_s2.png new file mode 100644 index 0000000..49e68ff --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_counter_s2.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_door_s1.png b/apps/game/tools/aiart/review-b1/b1_door_s1.png new file mode 100644 index 0000000..01718c0 --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_door_s1.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_door_s2.png b/apps/game/tools/aiart/review-b1/b1_door_s2.png new file mode 100644 index 0000000..5d00fbd --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_door_s2.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_hearth_s1.png b/apps/game/tools/aiart/review-b1/b1_hearth_s1.png new file mode 100644 index 0000000..8ebeeeb --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_hearth_s1.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_hearth_s2.png b/apps/game/tools/aiart/review-b1/b1_hearth_s2.png new file mode 100644 index 0000000..160376b --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_hearth_s2.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_lever_s1.png b/apps/game/tools/aiart/review-b1/b1_lever_s1.png new file mode 100644 index 0000000..c50bd15 --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_lever_s1.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_lever_s2.png b/apps/game/tools/aiart/review-b1/b1_lever_s2.png new file mode 100644 index 0000000..8a34473 --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_lever_s2.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_mote_s1.png b/apps/game/tools/aiart/review-b1/b1_mote_s1.png new file mode 100644 index 0000000..805d925 --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_mote_s1.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_mote_s2.png b/apps/game/tools/aiart/review-b1/b1_mote_s2.png new file mode 100644 index 0000000..3aeb83c --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_mote_s2.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_signpost_s1.png b/apps/game/tools/aiart/review-b1/b1_signpost_s1.png new file mode 100644 index 0000000..1dab36e --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_signpost_s1.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_signpost_s2.png b/apps/game/tools/aiart/review-b1/b1_signpost_s2.png new file mode 100644 index 0000000..75cbaa1 --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_signpost_s2.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_well_s1.png b/apps/game/tools/aiart/review-b1/b1_well_s1.png new file mode 100644 index 0000000..9e5d5d0 --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_well_s1.png Binary files differ diff --git a/apps/game/tools/aiart/review-b1/b1_well_s2.png b/apps/game/tools/aiart/review-b1/b1_well_s2.png new file mode 100644 index 0000000..2244504 --- /dev/null +++ b/apps/game/tools/aiart/review-b1/b1_well_s2.png Binary files differ diff --git a/docs/plan.md b/docs/plan.md index b68e693..162aae6 100644 --- a/docs/plan.md +++ b/docs/plan.md @@ -13,7 +13,7 @@ | # | Задача | Статус | |---|--------|--------| | 1 | Срез «меньше ошибок»: реестры ID, pre-commit, разрезание LocationScene, фикстуры, fail-fast waitFor | ✅ сделано (c379f20, 16b59d8, 39c6349) | -| 2 | AI-генерация текстур и спрайтов (работа B, ниже) | 📋 спланировано, отложено | +| 2 | AI-генерация текстур и спрайтов (работа B, ниже) | B0+B1 ✅ (PoC); B2/B3 отложены — RD API или ручной арт | | 3 | AI-генерация аудио (работа A, ниже) | 📋 спланировано, отложено | | 4 | Акт 2: новые локации/сюжет по `docs/world.md` | очередь после акта 1+AI-ассетов | | 5 | Замена сгенерированных плейсхолдеров арта на AI/ручной арт | в составе работы B | @@ -62,16 +62,17 @@ | Модель | Размер | Железо | Нативная палитра | Лицензия | Комментарий | |--------|--------|--------|------------------|----------|-------------| | **PXG-Tiny** (HF: Tarul/pxg-tiny) | 483K | CPU, NumPy, 1.8 МБ | да (прямые индексы) | MIT + CC0 | 16×16, 38 классов. Идеален по железу, но узкий домен | -| **PixelGPT-24×24** (unstonio) | 68M | CPU, секунды | да, 5 цветов | MIT | 24×24 спрайты; дообучение под свою палитру реально | +| **PixelGPT-24×24** (github.com/unstonio/pixelgpt-24x24) | 68M | CPU, ~22 с | да, 5 цветов/спрайт, кастомная палитра на запрос | **нет (не указана)** | 24×24; отказов нет, домен тянет частично (см. B1). Веса в репо; датасет 20K — CC BY 4.0 | | **Pixel Forge** (cochranblock) | 1.1–17M | CPU (Rust) | да, 7 встроенных палитр | Unlicense | 108 классов объектов; нет персонажей-атласов | | **Retro Diffusion SD1.5** (LostMedia, архив) | ~1B | CPU минуты/картинку | нет (пост-обработка) | Public Domain | классика пиксель-диффузии; для офлайн-пакета | | **Retro Diffusion API (RD Plus/Tile/Animation)** | облако | — | да | платный API | лучший результат для тайлов/анимаций; фолбэк, если локальное не тянет | | **LPC-style (PIXEL-T2I и др.)** | research | GPU | нет | research | перспективное направление для атласов 4 ракурса × walk/slash | -Вывод по классам: тайлы и объекты — **GPT-пиксель-модели локально** (PXG-Tiny / -Pixel Forge / дообученный PixelGPT под нашу палитру); персонажи-атласы — пока -**не решено локально** (кандидаты: дообучение PixelGPT на своих кадрах, либо -платный RD API, либо ручной арт поверх AI-болванок). +Вывод по классам (после B0+B1): инвентарь/декор — **PXG-Tiny локально** (её +классы); простые объекты 24×24 — PixelGPT (но лицензии нет — только PoC); +критичные интерактивы и тайлы сложных поверхностей — **RD API (платный) или +ручной арт**; дообучение под игру не делаем. Персонажи-атласы — **не решено** +(кандидаты: платный RD API или ручной арт поверх AI-болванок). ### Пайплайн интеграции (проект решения) @@ -97,11 +98,17 @@ — вердикты). Pixel Forge отложен (нет Rust-тулчейна). Ограничение: критичные для игры ассеты (колодец, столб, рычаг, колокольчик, моты) вне 38 классов модели — для них дообучение / RD API / ручной арт. -- **B1**: пайплайн post.mjs + манифест + review-каталог; генерация партии - спрайтов объектов для акта 2. -- **B2**: тайлы сложных поверхностей (img-условность от существующих тайлов). -- **B3**: эксперимент с персонажами/атласами (дообучение или RD API) — по - итогам B1–B2 решить, не откладывать ли до ручного арта. +- **B1 (домен, вторая модель)**: PixelGPT-24×24 на доменных интерактивах + (промпты + обусловливание палитрой игры из 5 цветов). + ✅ **Выполнен (2026-09-06)**: 18 спрайтов, 44% годных, **отказов нет** — + доменные объекты (колокол, дверь, камин, столб, моты) модель рисует, где + PXG-Tiny отказывала. Ограничения: даунскейл 24→16 губит деталь (колодец + good на 24×24), фон часто залит, ровно 5 цветов, ~22 с/спрайт CPU, + **лицензии на код/веса нет — в игру нельзя**. Манифест: `manifest-b1.json`. +- **B2**: тайлы сложных поверхностей (img-условность от существующих тайлов) — + локальным моделям недоступно, кандидат RD API; отложено. +- **B3**: персонажи/атласы — RD API (платный) или ручной арт; отложено + до потребности акта 2. --- @@ -150,12 +157,12 @@ ## Открытые решения (принять перед стартом работ) -1. B0: какая из GPT-пиксель-моделей заходит лучше на нашем домене — брать обе - на пробу? (обе крошечные, сравнение дешёвое) -2. Персонажи-атласы: дообучение локально vs платный RD API vs ручной арт — - решить после B1/B2. -3. Python-окружение для моделей: uv-venv вне репо? Веса кэш в ~/.cache — в git - не попадают; в репо — только манифесты и итоговые ассеты. +1. ~~B0: какая из GPT-пиксель-моделей заходит лучше~~ — **закрыто B0+B1**: + PXG-Tiny — инвентарь/декор, PixelGPT-24×24 — домен частично, но лицензии нет. +2. ~~Персонажи-атласы: дообучение локально vs RD API vs ручной арт~~ — + дообучение под игру **отвергнуто**; осталось: платный RD API vs ручной арт. +3. ~~Python-окружение~~ — **закрыто**: venv вне репо (`~/.cache/rpg-ai/venv`, + `venv-pxgpt`), веса в `~/.cache/rpg-ai/`; в git — манифесты и review-PNG. 4. Порог апрува: кто смотрит review-лист (пользователь) и где фиксируется вердикт (пометка в манифесте). @@ -163,5 +170,6 @@ - Облачные API в основном пайплайне (только как опциональный фолбэк для спрайтов). - Модели с некоммерческими весами в основном пайплайне (DreamLite CC BY-NC — - только эксперименты). + только эксперименты); веса без лицензии (PixelGPT) — то же. +- Дообучение моделей под конкретную игру. - TTS-голоса персонажей — вне среза, кандидат на будущее: Kokoro-82M (CPU). \ No newline at end of file