- Updated protocol documentation to include `nativeLanguages` in `nameSets` and added `nativeLanguage` to school creation options. - Enhanced the UI for school creation to allow selection of native languages, improving user experience. - Revised API interfaces to accommodate new native language features, ensuring proper data handling. - Improved localization strings to support new native language functionalities in both English and Russian. - Updated tests to validate the new native language features and ensure robust functionality in staffing scenarios.
148 lines
12 KiB
Markdown
148 lines
12 KiB
Markdown
# Расписание
|
||
|
||
Договорённость на срез после штата, не текущий код.
|
||
Штат и предметы: [`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`, расписание их только расставляет |
|
||
| Запреты | Учитель, класс и кабинет — не более одного урока в слоте; класс влезает в кабинет |
|
||
| Место урока | Кабинет класса, если у предмета нет требования к типу помещения |
|
||
| Нет учителя | Урок не ставится; предмет числится непокрытым |
|
||
| Карта | В дереве рядом с комнатой — что и у кого там сейчас |
|
||
| Панель локации | «Сейчас» и «Персонажи» заполняются из расписания — с срезом 5 из присутствия, см. [`ai.md`](ai.md) |
|
||
| Расписание класса | В разделе «Управление», сетка «день × урок» |
|
||
| Расписание учителя | В его карточке, там же где навыки и семья |
|
||
| Общая сетка школы | Не делаем: её читает только тот, кто раскладывает вручную |
|
||
| Где живёт код | Отдельная библиотека рядом с `HSchool.People` |
|
||
| Люди и место | Находятся по расписанию; ходьбы нет — отменено срезом 5, присутствие стало состоянием ([`ai.md`](ai.md)) |
|