Creating Lessons
Creating Lessons
A Lesson is the actual demand the solver schedules — "this Subject, taught by these Teacher(s), to these Class Group(s), this many times a week, for this many periods each time." Every field below lives on this one form.
The required fields
- Subject — a single subject, from the Subjects list.
- Teacher(s) — one or more teachers. Selecting more than one means co-teaching: all of them are required to be present simultaneously for every instance of this lesson, not "any one of them" and not the workload split between them.
- Class Group(s) — one or more groups, from the Classes hierarchy. See the "combined vs. individual" section below before selecting more than one — it changes the meaning of the lesson, not just its convenience.
- Duration (slots) — how many consecutive Periods each instance occupies (2 for a double period, etc.). The solver guarantees a multi-period instance stays on one day and never spans a day boundary.
- Count / Week — how many times this lesson repeats per week.
Combined session vs. one lesson per class
Selecting more than one Class Group does not create a separate lesson for each class by default. It creates one shared lesson that all of the selected groups attend together at the same time, in the same room, with the same teacher(s) — a combined/joint session (an assembly, a joint activity). All of those groups become simultaneously busy for every instance.
If what you actually want is each class getting its own separate lessons of the same subject (the far more common case — "10A has Math five times a week, and so does 10B, independently"), check "Create individual lesson for each class?", which appears once you've selected more than one group. This creates one independent Lesson record per selected group instead of one shared one — each gets scheduled on its own, not forced into the same room/slot as the others.
This checkbox only appears when creating a new lesson with multiple groups selected, and it's disabled while editing an existing lesson (an existing lesson is always one specific combined-or-individual record; splitting happens at creation time).
Bunching: SPREAD / CONSECUTIVE / NONE
Controls how the solver prefers a lesson's repeated instances (when Count > 1) to fall across
the week — this is a soft preference, not a hard rule:
- SPREAD (default) — prefer at most one instance per day, spread across different days (typical for a subject like Math running 5x/week, once per weekday).
- CONSECUTIVE — prefer instances to land on the same day, back-to-back with no gaps (for a
subject that's better taught in a block, e.g. two Art lessons in a row once a week, when
Durationalone doesn't cover the whole block because you want repeats bunched rather than one longer single instance). - NONE — no spread or bunching preference either way.
Block: forcing lessons to start together
A free-form label. Any lessons sharing the same non-empty Block value are forced to start at exactly the same Period — a genuine hard constraint, not a preference. Rooms, teachers, and durations can all differ between them; only the start time is forced to match. This is how you model parallel electives (e.g. French and German running at the same time in different rooms, so students can choose either without a timetable clash).
Repeated instances are paired up by position — a block's 1st instance lines up with every other
member's 1st instance, the 2nd with the 2nd, and so on. If members of the same block have
different Count values, only the shorter one's worth of instances get paired, and this mismatch
is flagged as a warning on every generation (see Warnings in When generation
fails) rather than going unnoticed.
Locked vs. Preferred time slots
These look similar (both are a multi-select of Periods) but mean very different things:
| Locked Time Slots | Preferred Time Slots | |
|---|---|---|
| Strength | Hard — always honored | Soft — honored when possible |
| Effect if unsatisfiable | Generation fails (INFEASIBLE) | Silently unsatisfied; no effect on feasibility |
| How many you can pick | Capped at Count | Unlimited — any number of candidates |
| Typical use | "This exact lesson always happens at this exact time" (e.g. a fixed assembly) | "Try to put this here if it fits, but don't force it" |
The form also runs a lightweight client-side warning (not a hard block) if the Locked Time Slots you're picking overlap with another lesson that already has an overlapping lock on a shared Class Group — worth reading before saving, but it's only a heads-up, not enforcement; the real enforcement happens when you generate.
Required Room Tags
Optional. A lesson with one or more required tags can only be placed in a room that has all of them (not just one) — see Adding Rooms for how tags work.
Activity Tags — classification only
A free-form multi-select, independent of Subject, for grouping/labeling lessons however you like (e.g. "Practical", "Exam", "Fieldtrip"). This is metadata only — no constraint currently reads it. Selecting an Activity Tag doesn't change how the solver schedules anything; it's there for future use (FET-style per-tag constraints) and for your own organization. This is called out explicitly here because two earlier settings in this project's history (a room-stability toggle and one of the bunching modes) looked like they did something but silently didn't for a while — Activity Tags are not one of those; they're intentionally inert today.
Deleting
Deleting a Lesson is immediate — there's no confirmation-of-dependents check, but a Lesson has nothing else depending on it (nothing else references a Lesson by ID), so this is safe.
Deleting something a Lesson points at behaves differently depending on what it is:
- Subject — protected. A Lesson's link to its Subject is a real database reference, so deleting a Subject that's still used by any Lesson is blocked. (The error shown for this one isn't as polished as elsewhere in the app — it may look like a raw database error rather than a friendly message — but the deletion is genuinely prevented either way.)
- Teacher or Class Group — not protected. A Lesson stores these as plain ID lists, not a database-level reference, so deleting a Teacher or Class Group that's still assigned to a Lesson succeeds and leaves that Lesson pointing at an ID that no longer exists. Generation ignores the missing teacher or class (the lesson is scheduled without them) and says so in a warning, and the Lesson's edit form shows it as (deleted). Double-check the Lessons list before removing a Teacher or Class Group you suspect is still in use.
- Room — not applicable. A Lesson never references a specific Room at all (only Required Room Tags); the actual room is chosen by the solver at generation time, so deleting a Room has no direct effect on any Lesson.