Remove off-queue.md and add new design documentation files including README.md, defs.md, near-term.md, projects.md, runtime.md, people.md, staffing.md, and schedule.md to outline the structure and agreements for the game's design phases.

This commit is contained in:
Leonid Pershin
2026-08-20 12:26:13 +03:00
parent 12cc36b4dd
commit a37a5eb82d
101 changed files with 1015 additions and 921 deletions
+148
View File
@@ -0,0 +1,148 @@
# Расписание
Договорённость на срез после штата, не текущий код.
Штат и предметы: [`staffing.md`](../03-staffing/staffing.md). Люди: [`people.md`](../02-people/people.md).
Типы и карта: [`defs.md`](../01-shell/defs.md). Экран: [`near-term.md`](../01-shell/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; длинные — те, в которые обедают |
| Обеденные смены | Список в каркасе дня: какая параллель ест после какого урока |
| Длина недели | В настройках, пять дней по умолчанию |
| Каникулы | Дефами, диапазонами дат; в каникулы расписания нет |
| Учебный план | Часы из `SubjectDef`, расписание их только расставляет |
| Запреты | Учитель, класс и кабинет — не более одного урока в слоте; класс влезает в кабинет |
| Место урока | Кабинет класса, если у предмета нет требования к типу помещения |
| Нет учителя | Урок не ставится; предмет числится непокрытым |
| Карта | В дереве рядом с комнатой — что и у кого там сейчас |
| Панель локации | «Сейчас» и «Персонажи» заполняются из расписания — с срезом 5 из присутствия, см. [`ai.md`](../05-ai/ai.md) |
| Расписание класса | В разделе «Управление», сетка «день × урок» |
| Расписание учителя | В его карточке, там же где навыки и семья |
| Общая сетка школы | Не делаем: её читает только тот, кто раскладывает вручную |
| Где живёт код | Отдельная библиотека рядом с `HSchool.People` |
| Люди и место | Находятся по расписанию; ходьбы нет — отменено срезом 5, присутствие стало состоянием ([`ai.md`](../05-ai/ai.md)) |