Files
h-school/docs/design/16-sight/sight.md
T
Leonid PershinandCursor 02156e4491
ci / server (push) Failing after 3m43s
ci / client (push) Successful in 22s
Register slice 16 sight: inspect images and a denser linked catalog.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 20:46:33 +03:00

233 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Вид и каталог
Договорённость на срез после событий/сцены и одежды, не текущий код.
Сцена и тосты: [`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` |