Register slice 16 sight: inspect images and a denser linked catalog.
ci / server (push) Failing after 3m43s
ci / client (push) Successful in 22s

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-21 20:46:33 +03:00
co-authored by Cursor
parent bcc3f1333c
commit 02156e4491
8 changed files with 461 additions and 0 deletions
+232
View File
@@ -0,0 +1,232 @@
# Вид и каталог
Договорённость на срез после событий/сцены и одежды, не текущий код.
Сцена и тосты: [`events.md`](../11-events/events.md). Портреты: [`portrait-models.md`](../off-queue/portrait-models.md),
[`portrait-prompt-craft.md`](../off-queue/portrait-prompt-craft.md). Вещи и правила: [`inventory.md`](../07-inventory/inventory.md).
Экран: [`near-term.md`](../01-shell/near-term.md). Сессия (гость): [`session.md`](../08-session/session.md).
Протокол: [`protocol.md`](../../protocol.md).
Игрок **смотрит** именованную сущность — и может попросить картинку. Каталог `core` перестаёт
быть «достаточным минимумом»: одежда, комнаты и правила связаны так, чтобы и генератор людей,
и генератор кадра видели одно и то же. Кадр локации больше не запрещён: это не портрет человека
без тела, а отдельный субъект.
Срез отвечает на вопросы «что можно нарисовать», «почему в промпте худи, а не только рубашка»
и «какие ещё две ручки дресс-кода отбирают вещи». LLM, ControlNet и бумажной куклы нет.
## Что увидит игрок
На карточке человека кнопка портрета как сейчас. На панели выбранного узла карты — «создать
картинку» кабинета, двора, коридора, если у места или его fill есть что сказать генератору.
В списке одежды, ноши и предметов локации — то же у вещи с непустым `prompt`. Гость смотрящей
школы жмёт те же кнопки, что хозяин: как `POST .../portrait`, не как pausing-notice.
В «Правилах» две новые оси на роль (ученики / сотрудники): аксессуары и обувь. Как форма и
цвет — с завтрашнего рабочего утра.
Новая школа и новый набор одевают шире: худи, пиджак, кеды рядом со старой рубашкой. Живых
людей молча не переодеваем.
## На какие вопросы отвечает
- Какой HTTP-субъект кадра, если это не человек: узел карты и тип вещи.
- Как kind `scene` / `thing` стыкуется с уже собранным портретом, не ломая инварианты 1, 3, 4.
- Какие дефы ванили получают прозу и fill, чтобы кабинет не рисовался пустым стулом.
- Как две новые политики одежды фильтруют тот же `Appropriateness`, без нового вида поведения.
## Чего нет
- LLM-текста, ControlNet, позы в UI, автогенерации всем узлам утром.
- Спрайтов-слоёв и бумажной куклы: по-прежнему PNG по запросу, слои на карточке — текст и цвет.
- Картинок у часов, журнала, комбобоксов, тоста без сущности.
- Группового портрета класса с лицами конкретных учеников.
- Магазинов, одевания с карточки, новых стран, отдельного пака variety.
- Черт «любит худи» и экшена `Inspect`.
- Лифта живых `portraitSettings` и живого гардероба.
## Что меняется в уже принятом
| Было | Стало | Почему |
| --- | --- | --- |
| Kind `scene` запрещён ([`events.md`](../11-events/events.md)) | Узел карты — отдельный субъект кадра | «Просматриваемое» уже есть на панели локации |
| Картинка только у человека и notice с `personId` | Плюс узел и вещь с непустым вкладом | Иначе кабинет и куртка только текстом |
| Одежда в промпте из локали карточки | Слой одежды берёт английский `prompt` с ThingDef | RU UI не должен кормить Krea русским существительным |
| Ванильный гардероб — минимум для генератора | Закрытый расширенный список + цвета | Иначе новые правила не из чего выбирать |
| Стул и большинство комнат молчат в кадре | Ключевые Room/Thing говорят; `Chair` по-прежнему пустой | Бюджет сцены; не каждый fill |
| Правила: форма × цвет (и речь сбоку) | Плюс аксессуары и обувь | Две оси, которые уже есть слоями |
| «Портреты одежды не этот срез» ([`inventory.md`](../07-inventory/inventory.md)) | PNG вещи по кнопке, не спрайт на слое | Просмотр, не кукла |
| Гость генерирует портрет человека, не notice | Гость генерирует и локацию, и вещь | Смотреть чужую школу иначе слепое |
Протокол: новые HTTP маршруты узла и вещи. Версию сокета **не** бампим. Сейв: PNG рядом с
портретами; у правил одежды два новых поля с подъёмом `free`. Живые `portraitSettings` не
переписываем: нет kind `scene`/`thing` — fallback из опций.
## Этап A — каталог
Школа целая без арта кабинета: люди разнообразнее, портрет человека уже видит худи и доску.
### Гардероб
Закрытый список **новых** `ThingDef` в `core` (слои как в срезе 7, не новые роли):
| Def | Слой | Зачем |
| --- | --- | --- |
| `Hoodie` | OverTop | Неформальный верх |
| `Cardigan` | OverTop | Теплее свитера, спокойнее худи |
| `Vest` | OverTop | Жилет, формальность выше |
| `Blazer` | OverTop | Пиджак; снимается отдельно от брюк |
| `Polo` | Top | Между футболкой и рубашкой |
| `Blouse` | Top | Женский верх, формальность |
| `Turtleneck` | Top | Водолазка |
| `Tights` | Socks | Колготки, `sex: female` |
| `Leggings` | Bottom | Неформальный низ, женский |
| `Sweatpants` | Bottom | Спортивные штаны не-PE |
| `Sneakers` | Shoes | Кеды, низкая формальность |
| `SchoolShoes` | Shoes | Школьные туфли, тег school |
| `Cap` | Head | Кепка, не шапка от мороза |
| `Headband` | Head | Ободок |
| `Raincoat` | Outer | Плащ; не шуба |
| `PeTrackPants` | Bottom | PE-низ полной длины рядом с шортами |
Новые `ColorDef`: `Navy` (`neutral`, `school`), `Brown` (`neutral`), `Burgundy` (`neutral`),
`Pink` (`bright`), `Yellow` (`bright`). Существующие вещи **могут** получить Navy/Brown в
`colors`, где это уместно (брюки, пиджак), без смены палитры на радугу.
На **каждой** носимой вещи, включая уже существующие `TShirt` / `Shirt` / …, заполняется
английский блок `prompt` (тот же вид, что у доски). Пустой — вещь в портрете человека
по-прежнему собирается из подписи; цель ванили — непустой блок, чтобы locale карточки не
текла в Swarm. Длина фрагмента как у сцены: ≤ 120 символов, иначе ошибка загрузки.
Генератор одежды включает новые def в те же броски слоёв (`optionalApparelChance` и выбор
низа/верха/обуви). Детерминизм: тот же сид + карта + страна → тот же ростер; состав одежды
на **новой** школе может отличаться от старого золотого отпечатка — фикстуру обновляет эта
фаза. Живой `people.json` не дополняем худи задним числом; новый набор (create / yearly
intake) — да.
### Комнаты, fill, правила
Непустой `prompt` у ванильных мест, которые игрок реально открывает: `Classroom` (уже есть),
`Library`, `ComputerLab`, `GymHall`, `Cafeteria`, `MedicalOffice`, `PrincipalsOffice`,
`TeachersRoom`, `SecretaryOffice`, `UtilityRoom`, меняльные, `SchoolYard`, `EntranceHall`,
`Corridor`. `Restroom` — короткая проза умывальной, не кабинки крупным планом. `Stairwell`,
этажи и корпуса без текста **молчат** (кнопки не будет).
Новые fill-вещи (слоты на def комнаты и/или дефолтной карте, не свободная геометрия):
| Def | Куда |
| --- | --- |
| `PottedPlant` | класс, библиотека, кабинет директора |
| `WallPoster` | класс |
| `NoticeBoard` | холл |
| `GymMat` | зал |
`Chair`, `StudentDesk`, шкафчик без прозы — молчат, как сейчас. Связность: fill с текстом
попадает в сборщик сцены человека (фаза 66 уже спрашивает fill) и позже в кадр узла.
Две оси на `DressRulePair`, те же роли ученики/сотрудники, вступление **с завтра**:
| Ось | Значения | Смысл |
| --- | --- | --- |
| Аксессуары | `free` / `none` | `none` — слой `Accessory` в школе неуместен (ремень, шарф). Шапка от холода не аксессуар |
| Обувь | `free` / `uniform` | `uniform` — обувь с тегом цвета `school` и формальностью не ниже обычной; кеды не в школу (PE — свой режим) |
Дефолт обеих — `free`, чтобы живая школа без полей вела себя как сегодня. Неизвестный код —
`400`, как у формы/цвета. Речь не трогаем. Новых `ApparelIssue` достаточно, чтобы утренний
dresser снял/заменил; ходьбу и магазины не открываем.
После этапа портрет человека уже богаче; клик по кабинету ещё может не рисовать.
## Этап B — кадр с панели
Школа целая: кнопка на том, что уже открыто глазом.
### Субъект
Три субъекта, не четвёртый kind портрета человека в том же URL:
| Субъект | Ключ | PNG | Сборка промпта |
| --- | --- | --- | --- |
| Человек | как сейчас | `saves/{id}.portraits/` | внешность + одежда + сцена узла |
| Узел карты | id узла | `saves/{id}.images/node.{safeId}.png` | место + fill + погода, если улица; **без** лиц карточки |
| Вещь | `defName` + цвет, если есть | `saves/{id}.images/thing.{def}.{color\|none}.png` | блок вещи + цвет + износ, если смотрим надетое; без человека |
HTTP (имена уточнит фаза, смысл нет):
- `GET`/`POST` `.../nodes/{nodeId}/image` и `.../image/prompt`
- `GET`/`POST` `.../things/{defName}/image?color=` и `.../image/prompt`
Неизвестный узел / def — `404`. Пустой вклад (нет ни одного фрагмента) — `400` `cannot-generate`,
Swarm не зовём. Swarm как у портрета: `503` / `502` / `504`. Гость — `201`, не `403`.
В шаблоне `swarmui.json` у пресетов появляются shot kind `scene` и `thing` (проза кадра без
человека). Живая копия без них **не лифтится**: сборщик подставляет fallback из
`SimulationOptions` (строки по умолчанию, не константы в билдере).
Кадр локации не портретирует присутствующих поимённо. Если в узле кто-то есть, допустим **один**
общий фрагмент из опций («pupils at desks») — не список имён и не их одежда.
Вещь на карте — тип fill, без нового instance id в сейве. Вещь на человеке в промпт кладёт
цвет и полосу износа; ключ кэша PNG — def+цвет, не personId (перегенерация обновляет файл).
### Кнопка
Панель локации, строка одежды/ноши, строка предмета в локации: кнопка только если GET prompt
(или эквивалентная проверка вклада) не пустой. «Показать промпт» — тот же текст, что уйдёт в
Swarm. Открытие панели не генерирует. Строки через `t(...)`.
Notice `generateImage` не меняем: по-прежнему человек и хозяин.
После этапа клик по кабинету или белой футболке даёт PNG.
## Где живёт код
Нового проекта нет.
| Что | Куда |
| --- | --- |
| Новые Thing/Color, `prompt` на одежде и комнатах, слоты fill | `HSchool.Content` + JSONC `core` |
| Генератор гардероба, золотой ростер | `HSchool.People` |
| Уместность аксессуаров и обуви | `HSchool.Content.Appropriateness` + dresser в Simulation / People |
| HTTP картинки узла и вещи, PNG, fallback shot | `HSchool.Server` (сервис портретов / работник спрашивает карту) |
| Маршруты | `docs/protocol.md` (+ клиент `api.ts`); сокет не трогаем |
| Кнопки на панели и карточке | `src/HSchool.Client/src/ui` |
| Kind `scene`/`thing` в шаблоне | `swarmui.json` |
Инвариант 4: Simulation по-прежнему не знает Swarm. Сборщик кадра узла — тот же работник, что
спрашивает комнату для портрета.
## Советы, которые стоит принять сразу
- Не вешать картинку локации на кадр присутствия 2 Гц: PNG по HTTP, как портрет.
- Не давать вещи instance id «чтобы кэш был уникальнее». Def+цвет дешевле смены `people.json`.
- Не лифтить живой гардероб «всем по худи». Разнообразие — create и набор.
- Не рисовать корпус без `prompt`: этаж в дереве остаётся навигацией.
- Не складывать `scene` в `PortraitKind` человека: иначе `kind=scene` на `/people/.../portrait`.
- Гость жжёт GPU на картинке кабинета — это уже так на лице; очередь Swarm общая.
## Заведомо не сейчас
- LLM, ControlNet, редактор позы, автоген утра.
- Бумажная кукла, иконки слоёв, арт на каждом ряду дерева сразу (только выбранный узел).
- Журнал оценок как картинка, погода у часов как PNG.
- Групповое фото класса, лица с карточек на кадре кабинета.
- Магазин, стирка, игрок одевает, новые `CountryDef`.
- Черты вкуса к одежде, `Inspect` как действие ИИ.
- Лифт `portraitSettings`, возврат SDXL.
## Зафиксировано этим разговором
| Тема | Решение |
| --- | --- |
| Форма | Один срез 16, не два и не side-work |
| Просматриваемое | Человек, узел карты, надетое/несомое, fill локации |
| Kind `scene` | Да, без человека в сборке |
| Каталог | Закрытый список в `core`, не пак |
| Связность | `prompt`, fill, теги, правила — без новых глаголов ИИ |
| Правила | Аксессуары `free`/`none`, обувь `free`/`uniform`, с завтра |
| Гость | Как портрет человека, не как notice |
| Живые школы | Без лифта лиц и гардероба; правила без полей → `free` |
| Кэш вещи | def + цвет, не экземпляр |
| Стоп | После A школа в разнообразии; после B — кнопка на панели |
| Протокол | HTTP в коммите 87; сокет не +1 |
| Ваниль/пак | `core` |