32 KiB
Одежда, вещи и климат
Договорённость на следующий срез, не текущий код.
Люди: people.md. Типы и карта: defs.md. Жизнь школы: ai.md.
Экран: near-term.md. Проекты: projects.md.
У человека появляется то, что на нём надето и что он несёт. Школа получает климат и правила одежды. Игрок это смотрит и выбирает правила; надевает не он — система сама приводит гардероб к уместности, сезону и погоде.
Срез отвечает на вопросы «во что одеты», «что в сумке», «какая на улице погода» и «что человек делал сегодня». Магазинов, стирки, краж и выдачи со склада нет.
Что меняется в уже принятом
| Было | Стало | Почему |
|---|---|---|
| Create выбирает набор имён | Create выбирает страну; набор имён вложен в неё | Климат, имена и вкус к одежде — одна культура, а не три пикера |
ThingDef — мебель на карте |
Тот же вид def, поля отличают размещаемое / носимое / переносимое | Стул и футболка — предметы, но живут в разных местах |
| Карточка — один свиток | Вкладки: обзор, одежда, ноша, сейчас + история | Гардероб в узкую колонку списком навыков не влезает |
| «Управление» — деньги и штат | Плюс вкладка «Правила» | Дресс-код — единственное действие игрока в этом срезе |
| Часы несут дату и паузу | Плюс температура и осадки | Погода должна быть видна, не спрятана в карточке |
| Одна раздевалка на 12 шкафчиков | Две (м / ж); шкафчик принадлежит ученику | Переодевание на физкультуру и личное хранение — разные вещи |
Старые школы без страны поднимаются: нынешний набор имён отображается на ванильную страну, климат — первый пресет этой страны. Файл не переписывается молча в новый вид, пока школа не сохранится сама.
Страна
Новый вид def — CountryDef. Это то, что игрок выбирает при создании школы.
В стране лежит всё, что раньше было «набором имён», плюс ссылки на климатические пресеты:
{
"defName": "Russia",
"climatePresets": ["TemperateContinental", "ContinentalCold"],
"names": {
"patronymicRule": "Slavic",
"nativeLanguages": ["Russian", "Belarusian", "Ukrainian"],
"relatedLanguageChance": 0.35,
// maleGiven, femaleGiven, surnames — как у нынешнего NameSetDef
},
}
Набор имён перестаёт быть выбираемым видом. Он не удаляется как форма данных: это вложенный
объект страны. Мод, который хочет другую страну, кладёт свой CountryDef целиком, а не «набор
имён плюс климат сбоку».
Родной язык по-прежнему выбирается из names.nativeLanguages, если их больше одного. Это не
третий пикер культуры — это язык внутри уже выбранной страны. Не указан — бросает сид школы,
как сейчас.
Климатический пресет школа получает случайный из списка страны, от того же сида, и записывает у себя. Повтор create с тем же сидом даёт ту же погоду. Сменить пресет у живой школы нельзя: это часть рождения, как набор имён раньше.
В core одна страна — Russia: нынешний славянский набор вложен в неё, пресеты — умеренно-
континентальные. Другие страны приходят модами.
Форма создания говорит «Страна», не «Набор имён». GET /api/catalog отдаёт countries вместо
nameSets. POST /api/schools принимает countryId; неизвестная страна — 400 unknown-country.
Старое поле nameSetId не принимается.
Климат и погода
Погода — не картинка и не текст. На школе живёт состояние: уличная температура и осадки
(нет / дождь / снег). Его видно у часов, и от него одеваются. Дождь и снег ещё добавляют минуты
к запасу на дорогу (BehaviorDef.commuteRainMinutes / commuteSnowMinutes): план дня получает
уже число, симуляция считает его с улицы. Ходьбу по коридору это не режет.
Числа живут в ClimatePresetDef, не в коде. Страна только ссылается на id. Мод меняет зиму,
не трогая имена.
Пресет описывает:
- ход температуры по году (месячные нормы);
- как температура гуляет внутри дня и от нормы (разброс);
- когда и какие осадки — с поправкой на температуру: ниже нуля тот же бросок даёт снег, выше — дождь.
Погода пересчитывается не каждый тик, а когда это меняет одежду или надпись у часов: сдвиг на несколько десятых градуса, смена осадков. Детерминизм: пресет + сид школы + календарная дата и час. Тот же сид, тот же день — та же улица.
В здании теплее, чем на улице, даже без сотрудника: стены держат. Но комфорт — работа техника. Без него зимой в кабинетах прохладно, летом душно; с ним держится жилая полоса. Двор, крыльцо и переход между корпусами — улица.
Пропуск пустого времени погоду не «перепрыгивает молча»: к утру рабочего дня состояние считается из даты, как годовой набор уже считается через каникулы.
Тепло как нужда
Новая нужда — тепло (Warmth). Шкала как у остальных: 0–1, полоска на карточке.
Она падает, когда одежда не соответствует температуре места, где человек сейчас: на морозе без куртки, в жару в шубе. В комфортной полосе почти не падает. Дома (вне школы) восстанавливается за кадром, как сон.
Две черты, несовместимые друг с другом:
- теплолюбивый — комфортная полоса сдвинута вверх, на жару реагирует спокойнее, на холод — раньше;
- холодолюбивый — наоборот.
Сдвиг — поле на TraitDef (смещение комфортной температуры), не список фамилий в коде. Мод
добавляет «мерзлявый» тем же полем.
Голодный учится хуже уже сейчас. Замёрзший — тоже: та же NeedFactor, что у голода. Нужда
видна, двигает переодевание и режет рост навыка на уроке. Оценок как журнала нет.
Один ThingDef, три роли
Мебель, одежда и портфель — один вид. Различают поля, а не отдельные классы. Стул без слоёв по-прежнему ставится на карту; футболка со слоями на карту не ставится.
| Поле | Зачем |
|---|---|
layers |
Какие слои занимает. Пусто — не одежда |
portable |
Можно нести в сумке / шкафчике / дома |
mass |
Килограммы; ноша складывается |
insulation |
Насколько греет (и преет в жару) |
formality |
Формальность, 0–100 |
age |
Допустимый возраст |
sex |
male / female / нет поля = любой |
colors |
Какие ColorDef допустимы на этом def |
skirtLength |
Длина низа; для «короткой» формы |
pe |
Форма для физкультуры |
subject |
Только у дефа учебника: какой предмет |
Учебник — один ThingDef, экземпляр несёт id предмета. Не двенадцать дефов «учебник математики».
Цвет — поле экземпляра, не отдельный def вещи. «Синяя футболка» и «красная футболка» — один
TShirt с разным color.
ColorDef — свой вид: id, теги уместности (neutral, bright, school). Правила школы
фильтруют теги, а не имена цветов. Мод добавляет «бордовый» файлом, не пересборкой.
Новые слои — пересборка: слои как роли, код их знает. Подписи — в локалях.
Слои
Код знает десять, в core все используются:
| Слой | Что надевают |
|---|---|
Underwear |
трусы |
UpperUnderwear |
бюстгальтер (поверх трусов, под верх) |
Socks |
носки |
Bottom |
юбка, штаны, джинсы, брюки |
Top |
футболка, рубашка |
OverTop |
свитер, жилет |
Outer |
куртка, пальто, шуба |
Shoes |
обувь |
Head |
шапка, кепка |
Accessory |
ремень, шарф, значок |
Платье — один предмет на несколько слоёв: layers: ["Bottom", "Top"]. Пиджак, если его можно
снять отдельно от брюк, — отдельная вещь на OverTop или Outer, не «костюм-монолит».
На одном слое — не больше одной вещи. Надеть свитер поверх рубашки можно: это разные слои. Надеть две футболки нельзя.
Ванильный набор
Не витрина моды, а достаточный гардероб, чтобы генератор и правила было чем кормить:
- бельё: абстрактный
Underwear, от него трусы / боксеры / трусики и бюстгальтеры (UpperUnderwear); - носки нескольких цветов;
- низы: юбка (женская), штаны, джинсы, брюки — длины обычная и короткая;
- верх: футболка, рубашка;
- поверх: свитер;
- верхняя: куртка, пальто, шуба;
- обувь: повседневная и зимняя;
- голова: шапка;
- аксессуары: ремень, шарф;
- платье (два слоя);
- форма физкультуры (верх + низ,
pe: true); - ноша: портфель, учебник (один def), телефон, бутылка.
Цвета палитры: белый, чёрный, серый, синий, голубой, красный, зелёный, бежевый. Красный и
зелёный — bright; белый, чёрный, серый, синий — school и neutral.
Где лежит вещь
У экземпляра одно место из четырёх:
| Место | Что это |
|---|---|
| Надето | занимает слои |
| Сумка | с собой, давит на ношу |
| Шкафчик | в школе, не несёт |
| Дом | не локация, а состояние «не в школе» |
Домашнего узла на карте нет и не будет. «Дом» — событие и подпись текущего дела, как «вне школы» уже есть у присутствия.
Шкафчик — слот на карте, привязанный к ученику. Число шкафчиков в раздевалке = число слотов. Раздача: ученики этого пола, старшие параллели раньше, при равенстве — стабильный id. Не хватило — не досталось: запас только в сумке и дома. Сотрудники шкафчик ученика не получают.
Сменить одежду в школе можно и без шкафчика: снятое уходит в сумку. Шкафчик — чтобы не таскать форму для физкультуры весь день.
Две раздевалки на ванильной карте — два узла, мужская и женская, у спортзала. Def разный, чтобы ИИ шёл в свою. В редакторе шкафчики по-прежнему число в слоте: поставили 40 — сорок учеников этого пола получат место.
Генератор одевает
Люди больше не рождаются голыми. Генератор, тем же семейным сидом, собирает гардероб:
- повседневное и уместное полу, возрасту и дефолтным правилам школы;
- сезонную верхнюю одежду;
- форму для физкультуры ученикам, у кого в сетке есть этот предмет;
- учебники по одному на каждый предмет параллели (не все книги каталога);
- портфель, телефон и бутылку — с шансом и возрастом (первокласснику телефон не обязателен).
Родители одеты: на них есть планы появиться в школе, и раздетой карточки быть не должно. Соискатели — тоже полные люди, значит тоже одеты.
Цвет бросается из допустимых у def с учётом правил школы. Красную рубашку в школу с политикой «без яркого» генератор не выдаст на тело; в домашнем запасе яркое может лежать.
Детерминизм тот же: страна + пресет + сид + карта + язык = те же люди в той же одежде. Золотой отпечаток ростера обновляется в той фазе, которая начинает одевать.
Ноша
Новый навык Hauling («Переноска»), always, как сила. Предел массы:
предел = f(Strength, Endurance, Hauling) — точная формула в BehaviorDef или соседнем
дефе правил, не константа в коде.
На карточке — два числа: несёшь / можешь. Перегруз не замедляет ходьбу в этом срезе. Вещи сверх предела генератор не выдаёт в сумку: лишнее остаётся дома или в шкафчике.
В сумке в учебный день: портфель, учебники сегодняшних уроков, телефон, бутылка, то, чему не хватило шкафчика. Остальные учебники — в шкафчике или дома. Иначе одиннадцатиклассник с двенадцатью учебниками всегда перегружен, и шкала лжёт.
Износ
У экземпляра одежды прочность 0–1. Пока вещь на теле в школе, она чуть падает со временем. Ходьбу отдельно не считаем. Сумка и шкафчик не изнашиваются.
На карточке — полоска и подпись по порогам из данных (целая, поношенная, порванная,
висит лохмотьями). Пороги — def, не if в UI.
Из дома в одежде ниже порога не выходят. Утром вне школы срабатывает событие: ветхая вещь заменяется свежей того же def и цвета (или ближайшего уместного). Это видно в истории («получил новую рубашку»), не как поход по узлам карты.
Пропуск ночи это событие обязан применить: иначе после «пропустить» школа выходит в лохмотьях.
Уместность
Не запрет «юбку надеть нельзя», а оценка. Надеть можно; система сама так не оденет, а если ситуация сменилась — переоденет.
Оси, все из данных на вещи, цвете и правилах школы:
- пол и возраст;
- сезон и текущая погода (утепление vs улица);
- урок: на физкультуре нужна
pe-форма; - формальность вещи vs дресс-код;
- цвет vs цветовая политика;
- длина низа vs «короткая» форма.
«Короткая» форма — про длину юбки (и летний короткий рукав), не про «можно без формы». Малышам короткое неуместно: даже если школа выбрала «короткую», младшие параллели ходят в обычной. Порог возраста — поле на правиле, не магическая семёрка в коде.
Цветовая политика отдельно от строгости. Строгая форма всё ещё может быть «без яркого» или «белый верх, чёрный низ». У учителей свой комплект правил: ученику белая рубашка, директору — не обязательно.
Смена правил в «Управлении» вступает в силу со следующего рабочего дня. Сегодняшняя одежда не вспыхивает в раздевалках посреди урока. На карточке правил видно: «с завтра».
Переодевание
Дома — мгновенно, событием, в момент ухода/прихода.
В школе — действие: дойти до своей раздевалки и сменить. Снятое — в шкафчик, если он есть, иначе в сумку. Надетое — из шкафчика или сумки.
Типичные поводы, все через уже существующий выбор цели:
- утром пришёл не по погоде (вчера было тепло, ночью ударил мороз) — переодеть верх;
- сейчас физкультура — форма
pe, после урока — обратно; - с завтра действует новый дресс-код — утром уже в нём (домашнее мгновенное + проверка при входе).
Действие занимает раздевалку как комнату, не чужой шкафчик. Вместимость переодевания — сколько человек одновременно могут здесь действовать; это не путать с числом личных шкафчиков.
Техник
Новая должность и комната: техник (Technician) в теплоузле / кабинете техника. Комната
открывает должность, как медкабинет — медсестру. Игрок нанимает из пула.
Пока техник не нанят, здание держит тепло по-плохому: зимой зябко, летом душно. Нанятый сдвигает
внутреннюю температуру в комфортную полосу. Числа — в дефе правил климата, не в if (month).
Ванильная карта получает эту комнату в основном корпусе. Без неё должность не рождается, и нанять некого.
Что видит игрок
Часы
Рядом с датой: температура улицы и осадки. Клиент не считает погоду из месяца — только рисует кадр. Кадр часов растёт, версия протокола поднимается.
Карточка человека — вкладки
Не отдельный экран и не вкладка оболочки. То же окно подробностей справа, внутри него вкладки:
- Обзор — то, что есть сейчас: тело, навыки, черты, нужды (включая тепло), семья, расписание.
- Одежда — слои, надетое, цвет, прочность с полоской и подписью, уместность к текущей ситуации (коротко: «к уроку», «холодно», «не по форме»).
- Ноша — сумка, масса несёшь/можешь, шкафчик если есть, домашнее не тащить сюда списком из пятидесяти строк: дом — кратко «ещё N вещей дома».
- Сейчас — текущее дело на территории школы (
ест,идёт,учится (математика),переодевается). Вне школы — одна подпись «дома», без фальшивого расписания домашней жизни. Ниже — история за сегодня: сортировка, поиск, пейджинг.
Игрок с карточки ничего не надевает и не забирает. Чистый просмотр.
История — HTTP, как список людей: GET .../people/{id}/log, страница, фильтр. Не сокет и не
общая лента школы. Хранится на работнике за текущие сутки (граница — шесть утра), к новому дню
обнуляется. Пропуск ночи не оставляет вчерашний лог.
Управление — «Правила»
Вкладка рядом с нынешним штатом, не новый верхний режим. Четыре комбобокса:
| Кого | Форма | Цвет |
|---|---|---|
| Ученики | обычная / короткая / строгая | свободно / без яркого / белый верх чёрный низ |
| Сотрудники | обычная / короткая / строгая | свободно / без яркого / белый верх чёрный низ |
«Применить» меняет завтрашнее правило. Сегодняшний день доигрывается как был.
Поток данных
Инвентарь лежит на человеке в people.json. Он меняется чаще состава (переодевание, износ),
но реже нужд: писать файл на каждом тике нельзя, писать при смене состава — мало. Шов тот же, что
у найма: запись, когда гардероб изменился содержательно (утро, переодевание, выдача новой вещи),
не каждый кадр.
Карточка по-прежнему через мейлбокс: нужды и текущее действие живые, одежда едет тем же ответом. Список людей одежду не несёт.
История — отдельный GET, чтобы карточку не раздувать сотней строк.
Погода — в кадре часов. Открытая школа, 20 Гц, потеря старого кадра допустима: как с датой.
Где живёт код
Нового проекта нет.
| Что | Куда |
|---|---|
CountryDef, ClimatePresetDef, ColorDef, поля ThingDef, слои |
HSchool.Content |
| Генерация гардероба, раздача шкафчиков, учебники параллели | HSchool.People |
| Погода от пресета и даты, износ, утренняя замена | HSchool.Simulation |
| Действие «переодеться», цель «одеться по погоде / к физкультуре» | HSchool.Ai |
| Кадр часов, карточка, лог, правила, create | HSchool.Server + клиент |
| Раскладка часов | HSchool.Protocol + protocol.ts + docs/protocol.md |
Советы, которые стоит принять сразу
- Не заводить
ApparelDef. Поля наThingDefдешевле, чем два загрузчика и вечный вопрос «а рюкзак — это что». - Не делать цвет отдельным def вещи. Экземпляр + палитра.
- Не ставить домашний узел на карту. Тридцать тысяч «комнат» семей не окупить.
- Не раздавать шкафчик каждому на ванильной карте. Нехватка — правило, не баг.
- Не вешать перегруз на ходьбу, пока не измерен. Число на карточке сначала.
- Не возвращать общую ленту событий школы. История — у человека, за сегодня.
Заведомо не сейчас
- Магазины, деньги за одежду, стирка, кража, выдача со склада игроком.
- Игрок одевает человека с карточки.
- Болезни от промокания, прогул «не в форме» как оценка. Штраф к уроку от холода — фаза 51.
- Смена страны или климатического пресета у живой школы.
- Почасовая анимация погоды, ветер, грязь, зонты как система.
- Шкафчики сотрудников, раздевалки в каждом корпусе сверх двух ванильных.
- История старше суток и школьная лента на весь экран.
- Портреты и спрайты одежды. Слои — текст и цвет, не картинка.
Зафиксировано этим разговором
| Тема | Решение |
|---|---|
| Вид def | Один ThingDef; одежда и ноша — поля |
| Цвет | Поле экземпляра; ColorDef с тегами уместности |
| Костюм / платье | Один предмет на несколько слоёв; снимаемый пиджак — отдельная вещь |
| Слои | Бельё, носки, низ, верх, поверх, верхняя, обувь, голова, аксессуар |
| Уместность | Пол, возраст, сезон/погода, урок (физкультура), формальность, дресс-код, цвет |
| Запрет vs оценка | Оценка; система сама не наденет неуместное |
| Короткая форма | Длина юбки и летний рукав; малышам неуместно — ходят в обычной |
| Цвет vs строгость | Два независимых правила; своё у учеников и у сотрудников |
| Ноша | Навык Hauling + сила + выносливость; на карточке число, ходьбу не трогает |
| Учебники | Один def, экземпляр на предмет параллели; в сумке — сегодняшние |
| Прочее в сумке | Портфель, телефон, бутылка |
| Генератор | Одевает всех, включая родителей и соискателей |
| Переодевание дома | Мгновенно, событием |
| Переодевание в школе | Действие в своей раздевалке |
| Дом | Не узел карты; текущее дело «дома» |
| Шкафчик | Слот карты, один ученик; старшие раньше; не хватило — не досталось |
| Раздевалки | Два узла, м/ж; шкафчики добавляются числом в редакторе |
| Износ | Падает на теле в школе; полоска + подписи; из дома в ветхом не выходят |
| Замена одежды | Утром дома событием |
| Страна | CountryDef: вложенные имена + ссылки на пресеты климата |
| Create | Пикер страны вместо набора имён; язык — если у страны их несколько |
| Климат | Пресет выбирается сидом из списка страны, на живой школе не меняется |
| Погода | Температура и осадки; у часов; одежда; минуты на дорогу |
| В здании | Теплее улицы всегда; комфорт — если нанят техник |
| Техник | Комната + должность; холод летом и тепло зимой |
| Нужда | Warmth; черты теплолюбивый / холодолюбивый |
| Правила | Вкладка в «Управлении»; четыре комбобокса; с завтра |
| Карточка | Вкладки обзор / одежда / ноша / сейчас+история; чистый просмотр |
| История | Только этот человек, только сегодня, HTTP, поиск и пейджинг |
| Инвентарь в сейве | На человеке в people.json, писать при содержательной смене |
| Игрок надевает | Нет |
| Погода влияет на ИИ | Да: переодеться. Ходьбу не штрафует. Урок — через нужду тепла |