Files
h-school/docs/design/schedule.md
T
2026-08-18 23:51:10 +03:00

148 lines
11 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.
# Расписание
Договорённость на срез после штата, не текущий код.
Штат и предметы: [`staffing.md`](staffing.md). Люди: [`people.md`](people.md).
Типы и карта: [`defs.md`](defs.md). Экран: [`near-term.md`](near-term.md).
Часы из учебного плана раскладываются по дням и кабинетам. Школа впервые начинает **жить по
времени**: в 10:15 у 5Б математика в кабинете 204, и это видно на карте.
## Зачем это раньше ходьбы
Расписание закрывает дыру, которая тянется с первого среза: в панели локации пустуют «Персонажи»
и «Сейчас». Заполнить их можно **без системы перемещения** — если урок стоит в расписании, мы
знаем, кто в кабинете и чем занят. Ни поиска пути, ни шагов по коридору: таблица и часы.
Люди по-прежнему не ходят. Они **находятся** там, где их застало расписание.
## Каркас дня
В `core`, дефом: первый урок в 8:30, до семи уроков, урок 45 минут, перемены по 10 с одной
большой на 20. Одна смена.
Длина недели — **в настройках**, а не в контенте: пять дней по умолчанию. Это школьное правило,
а не свойство мира, и его меняют, чтобы посмотреть, что будет.
Каникулы — дефами: осенние, зимние, весенние и лето, диапазонами дат внутри учебного года.
В каникулы расписание не действует, школа стоит.
## Учебный план
Уже есть: `SubjectDef` знает, в каких параллелях преподаётся предмет и сколько часов в неделю.
Расписание ничего не решает про количество — только про расстановку.
## Кто его строит
**Сервер, сам, детерминированно** — из учебного плана, назначений и карты. Игрок не раскладывает
пасьянс на одиннадцать классов; он влияет тем, кого нанял и что назначил.
Но игрок **может править** готовое: передвинуть урок, поменять кабинет.
Отсюда правило, без которого правки будут пропадать: **исправленное игроком закрепляется.**
Перестроение — а оно случается при каждом найме и назначении — сохраняет закреплённые уроки и
пересобирает только остальное. Иначе первый же наём стёр бы всю ручную работу.
Снять закрепление игрок может явно; тогда урок снова участвует в общей раскладке.
## Правила раскладки
Четыре запрета, нарушать которые нельзя:
1. **Учитель не в двух местах.** Один человек — один урок в слоте.
2. **Класс не в двух местах.** Один класс — один урок в слоте.
3. **Кабинет не занят дважды.** Два класса в одной комнате одновременно невозможны.
4. **Класс влезает в кабинет.** Учеников не больше, чем мест.
Урок идёт **не обязательно в своём кабинете**. У предмета может быть требование к типу помещения:
физкультура — в спортзале, информатика — в компьютерном классе. Без требования урок идёт в
кабинете, закреплённом за классом.
Это и делает карту нужной: один спортзал на одиннадцать классов — узкое место, которое видно в
расписании, а не в отчёте.
## Некому вести — урока нет
Предмет без учителя не ставится вовсе. В расписании класса на этом месте пусто, а в разделе
«Управление» предмет числится непокрытым.
Так наём получает прямое последствие: нанял человека, назначил ему предмет — в расписании
появились уроки. Это единственная обратная связь среза, и она должна быть мгновенной.
То же самое, если часов больше, чем вытягивают нанятые: лишние часы просто не встают.
## Что видит игрок
**В дереве карты** — что происходит в комнате прямо сейчас, скобками рядом с названием:
```
Этаж 2
Кабинет 204 (Математика · 5Б)
Кабинет 205 (Физика · 9А)
Кабинет 206
```
Так классы не сливаются в одинаковые строчки: комната подписана тем, что в ней идёт. Пусто —
значит свободна.
**В панели локации** — «Сейчас» и «Персонажи» наконец не пустуют: урок, класс, учитель.
**В «Управлении»** — расписание класса: сетка «день × урок» на одну параллель.
**В карточке учителя** — его личное расписание: где он и когда. Это же карточка, что и в «Людях»,
так что расписание видно всюду, где человек открывается.
Общей сетки на всю школу нет: одиннадцать классов на шесть дней не читаются с экрана, а нужны
они только тому, кто раскладывает вручную, — а раскладывает сервер.
## Где это живёт
Планировщик — **отдельная библиотека**, как `HSchool.People`: зависит от `HSchool.Content`, не
знает ни Arch, ни ASP.NET, отдаёт простую таблицу. Причина та же, что и с генератором людей: то,
что строится по детерминированным правилам, проверяется только тестами — «этот штат и эта карта
дают вот такую раскладку», — а тест не должен поднимать хост.
Расписание сохраняется вместе с составом: оно дешевле пересчитывается, чем восстанавливается, но
ручные правки восстановить нельзя. Пишется по тем же правилам, что и ростер — при изменении, а не
по таймеру.
## Советы, которые стоит принять сразу
- Не давать игроку раскладывать всё вручную. Автоматика с правками — это управление; пустая сетка
на 66 ячеек — это работа завуча.
- Не пересобирать расписание на каждый тик. Оно меняется от найма и назначения, а не от времени.
- Не хранить «кто где сейчас» отдельным состоянием. Это вычисляется из расписания и часов; вторая
копия немедленно разойдётся с первой.
- Не ставить урок, который некому вести. Дыра в расписании честнее, чем урок без учителя.
- Требование к типу помещения — у предмета, а не у комнаты. Комната не знает, что в ней физкультура.
## Заведомо не сейчас
- Перемещение по карте: люди находятся в комнате, но не идут в неё.
- Оценки, посещаемость, домашние задания, успеваемость.
- Замены заболевшего учителя.
- Вторая смена, деление класса на подгруппы (языки, труд).
- Четверти, триместры, экзамены.
- Кружки, продлёнка, всё вне уроков.
- Предпочтения учителей: «не ставьте мне первым уроком».
## Зафиксировано этим разговором
| Тема | Решение |
| --- | --- |
| Кто строит | Сервер, детерминированно, из плана и назначений |
| Правки игрока | Можно; исправленное закрепляется и переживает перестроение |
| Каркас дня | `core`: 8:30, до 7 уроков, 45 минут, перемены 10 и одна 20; одна смена |
| Длина недели | В настройках, пять дней по умолчанию |
| Каникулы | Дефами, диапазонами дат; в каникулы расписания нет |
| Учебный план | Часы из `SubjectDef`, расписание их только расставляет |
| Запреты | Учитель, класс и кабинет — не более одного урока в слоте; класс влезает в кабинет |
| Место урока | Кабинет класса, если у предмета нет требования к типу помещения |
| Нет учителя | Урок не ставится; предмет числится непокрытым |
| Карта | В дереве рядом с комнатой — что и у кого там сейчас |
| Панель локации | «Сейчас» и «Персонажи» заполняются из расписания |
| Расписание класса | В разделе «Управление», сетка «день × урок» |
| Расписание учителя | В его карточке, там же где навыки и семья |
| Общая сетка школы | Не делаем: её читает только тот, кто раскладывает вручную |
| Где живёт код | Отдельная библиотека рядом с `HSchool.People` |
| Люди и место | Находятся по расписанию; ходьбы нет |