Merge branch 'phase/48-lesson-teacher-present'

This commit is contained in:
Leonid Pershin
2026-08-20 08:42:38 +03:00
16 changed files with 595 additions and 5 deletions
+43
View File
@@ -0,0 +1,43 @@
# Фаза 48. Учитель в кабинете
## Зависимости
- [Фаза 21](21-decisions.md)
- [Фаза 18](18-presence-walking.md)
## Зачем
Ученик в кабинете больше не качает навык в пустоту. Нет учителя на месте — нет роста.
## Задачи
- [x] `LessonLearningSystem` растёт навык, только если назначенный учитель стоит в
`lesson.RoomId`: на кампусе, путь пуст, остаток минут 0
- [x] Нет человека с `TeacherId` в мире — как отсутствующий
- [x] Действие учителя урок не отменяет
- [x] Формула `LessonLearning.Gain` не меняется
- [x] Лог ученика `lesson-no-teacher` один раз на предмет в сутки, не каждый тик; `thingDef`
предмет; подпись из каталога
- [x] `docs/protocol.md` — новый `type` у HTTP лога, без бампа сокета
- [x] Фикстуры, где учитель был строкой `t1` вне ростера, нанимают живого человека — иначе
существующий тест роста навыка зелёный впустую
## Тесты, без которых фаза не закрыта
- [x] Ученик и учитель стоят в кабинете → навык за урок вырос
- [x] Ученик в кабинете, учитель в другом узле → навык не вырос
- [x] Учитель идёт по коридору в этот кабинет → пока идёт, роста нет
- [x] Нет человека с id учителя → роста нет
- [x] За урок без учителя в логе ученика одна строка `lesson-no-teacher`, не по числу тиков
- [x] Голодный по-прежнему учится хуже сытого, когда учитель на месте
## Критерий готовности
- Учитель ушёл в туалет посреди математики — класс в кабинете есть, навык за эти минуты не
ползёт
- `dotnet test` проходит
## Стоп
Не масштабировать рост навыком учителя. Не трогать тепло, учебник и дорогу. Не бампить
протокол. Не писать лог учителю.
+34
View File
@@ -0,0 +1,34 @@
# Фаза 50. Навык учителя на уроке
## Зависимости
- [Фаза 48](48-lesson-teacher-present.md)
- [Фаза 12](12-hiring-budget.md)
## Зачем
Соискатель с математикой 78 перестаёт отличаться от 41 только зарплатой.
## Задачи
- [ ] `LessonLearning.TeacherFactor` — та же кривая, что `NeedFactor`: навык 0 → 0.25, 100 → 1
- [ ] Навык учителя — среднее его значений по `SubjectDef.skills`; нет ключа — `Range.Min`
- [ ] `Gain` умножает на этот фактор; учитель в кабинете по-прежнему обязателен (фаза 48)
- [ ] Числа кривой в коде рядом с нуждой, не новый экран и не сейв
- [ ] Лог не пишем: рост тише — это и есть сигнал
## Тесты, без которых фаза не закрыта
- [ ] Учитель с навыком 20 даёт меньший прирост, чем с 80, при том же ученике и голоде
- [ ] Предмет с несколькими скиллами берёт среднее, а не первый попавшийся в словаре
- [ ] Нет ключа навыка у учителя — подставляется минимум шкалы, рост не падает в ноль
- [ ] Учителя нет в кабинете — по-прежнему нулевой рост, фактор не спасает
## Критерий готовности
- Два учителя математики в тестовой школе: слабый класс растёт заметно медленнее
- `dotnet test` проходит
## Стоп
Не вводить оценки. Не менять формулу зарплаты. Не трогать тепло и учебник.
+37
View File
@@ -0,0 +1,37 @@
# Фаза 51. Тепло на уроке
## Зависимости
- [Фаза 48](48-lesson-teacher-present.md)
- [Фаза 32](32-weather-warmth.md)
## Зачем
Замёрзший сидит на уроке так же, как голодный: полоска уже есть, рост её должен чувствовать.
## Задачи
- [ ] `Gain` умножает `NeedFactor(голод) × NeedFactor(тепло)`
- [ ] Нет нужды `Warmth` в каталоге — множитель тепла 1, голод как сейчас
- [ ] Лог `lesson-cold` один раз на предмет в сутки, если на уроке, который иначе учил,
тепло ниже `BehaviorDef.needThreshold`; `thingDef` — предмет
- [ ] `docs/protocol.md` — тип лога
- [ ] В [`inventory.md`](../design/inventory.md) убрать «тепло урок не штрафует»: стало рядом
с голодом
## Тесты, без которых фаза не закрыта
- [ ] Тепло 0.1 и голод 1 → меньший прирост, чем оба по 1
- [ ] Тепло 1 и голод 0.1 → как нынешний голодный, тепло не «вылечивает»
- [ ] Нет `Warmth` в каталоге — голодный тест фазы 21 по-прежнему зелёный
- [ ] За урок на холоде одна строка лога, не по числу тиков
- [ ] Учителя нет в кабинете — лога холода нет (урок не учил)
## Критерий готовности
- Январь без техника: полоска тепла падает, навык за тот же урок растёт медленнее, чем в мае
- `dotnet test` проходит
## Стоп
Не болеть от промокания. Не штрафовать ходьбу. Не трогать учебник.
+38
View File
@@ -0,0 +1,38 @@
# Фаза 52. Учебник на уроке
## Зависимости
- [Фаза 48](48-lesson-teacher-present.md)
- [Фаза 35](35-appropriateness.md)
## Зачем
Утренний `RepackBag` уже кладёт учебники сегодняшних предметов в сумку. Урок начинает это
проверять.
## Задачи
- [ ] Рост урока полный, только если в **сумке** есть экземпляр с `subject` этого предмета
- [ ] Шкафчик и дом не считаются: ученик в кабинете
- [ ] Нет учебника — множитель `BehaviorDef.lessonNoTextbookFactor`, ваниль 0.5
- [ ] Валидатор: число 0–1
- [ ] Лог `lesson-no-textbook` один раз на предмет в сутки; `thingDef` — предмет
- [ ] `docs/protocol.md` — тип лога
## Тесты, без которых фаза не закрыта
- [ ] Учебник математики в сумке → полный рост (при учителе на месте)
- [ ] Тот же учебник в шкафчике или дома → рост как с коэффициентом 0.5
- [ ] Учебник другого предмета в сумке не закрывает этот урок
- [ ] Одна строка лога за сутки на предмет, не по числу тиков
- [ ] Пак без поля — 0.5, каталог не падает
## Критерий готовности
- Слабая переноска, учебник остался дома — на уроке растут хуже одноклассника с книгой
- `dotnet test` проходит
## Стоп
Не заставлять идти за учебником отдельной целью. Не замедлять ходьбу перегрузом. Не тратить
деньги на замену.
+38
View File
@@ -0,0 +1,38 @@
# Фаза 53. Погода на дороге
## Зависимости
- [Фаза 18](18-presence-walking.md)
- [Фаза 32](32-weather-warmth.md)
## Зачем
В январе опаздывают чаще, чем в мае. Черта уже двигает запас на дорогу; осадки — тоже.
## Задачи
- [ ] `BehaviorDef.commuteRainMinutes` и `commuteSnowMinutes`; ваниль 3 и 6
- [ ] Валидатор: не отрицательные
- [ ] `DayPlans.Build` принимает уже посчитанные лишние минуты; `HSchool.Ai` не знает осадков
- [ ] Симуляция при сборке плана дня подставляет минуты из текущей улицы
- [ ] Лог на каждого не пишем — опоздание видно местом
- [ ] В [`inventory.md`](../design/inventory.md) поправка: погода влияет на дорогу, не только
на переодевание
## Тесты, без которых фаза не закрыта
- [ ] Снег → `AppearAt` раньше на `commuteSnowMinutes` относительно ясного того же дня
(тот же человек, сид, дата без осадков)
- [ ] Дождь → на `commuteRainMinutes`
- [ ] Ясно → минуты как сейчас, только черты и бросок
- [ ] Пак без полей — 0 лишних минут, каталог не падает
- [ ] Тот же сид и снег → тот же `AppearAt`
## Критерий готовности
- Снежным утром класс наполняется позже, чем ясным; ленивый по-прежнему ближе к звонку
- `dotnet test` проходит
## Стоп
Не мочить одежду. Не пропускать день из-за мороза. Не бампить кадр часов.
+15
View File
@@ -222,3 +222,18 @@
| [47. Пак romance](47-romance-pack.md) | ⬜ | Ориентация, симпатия, пара 18+, патч тем |
46 стоит на 37 и 42; 47 — на 42 и 23. `example` не трогать.
## Вне очереди
Дизайн: [`../design/off-queue.md`](../design/off-queue.md).
Склейка уже живых систем, не новый кусок игры. Номера не спорят со срезом 10. После каждой
фазы школа целая. 50–52 стоят на 48; 53 — на 18 и 32, можно параллельно с 48.
| Фаза | Статус | Зачем |
| --- | --- | --- |
| [48. Учитель в кабинете](48-lesson-teacher-present.md) | ✅ | Нет учителя на месте — нет роста навыка |
| [50. Навык учителя](50-teacher-skill-gain.md) | ⬜ | Соискатель 78 учит лучше, чем 41 |
| [51. Тепло на уроке](51-warmth-lesson.md) | ⬜ | Замёрзший учится хуже, как голодный |
| [52. Учебник на уроке](52-textbook-lesson.md) | ⬜ | Нет в сумке — половинный рост |
| [53. Погода на дороге](53-weather-commute.md) | ⬜ | Снег и дождь добавляют минуты к приходу |