Soft constraints reference

Soft constraints reference

Every constraint below lives on the Constraints page as a threshold, a toggle, or just an always-on rule, and every one of them can be individually strengthened or weakened via the "Constraint Weights" tab — see Constraint weighting for how that dial works. None of these can ever make generation fail; see Hard vs. soft constraints if that distinction isn't clear yet.

The "Base cost" column is how many objective points one violation costs at the default 100% weight — useful context for deciding which constraints are worth raising or lowering relative to each other, since the solver is always trying to minimize the total across all of them at once.

IDNameBase costAlways on?
S1Max Consecutive Periods50Yes
S2Max Daily Load100Yes
S3Subject Spread10Only lessons with bunching = SPREAD
S4Room Stability20Toggle (enableRoomStability, default on)
S5Student Gap Minimization5Toggle (enableStudentGaps, default on)
S6Consecutive Bunching15 + 10Only lessons with bunching = CONSECUTIVE
S7Preferred Start Times8Only lessons with Preferred Time Slots set
S8Max Days Per Week15Opt-in (maxDaysPerWeek, off by default)
S9Min Days Per Week15Opt-in (minDaysPerWeek, off by default)
S10Max Span Per Day5Opt-in (maxSpanPerDay, off by default)
S11Teacher Gap Threshold10Yes, but only above maxGapsPerDay
S12Cross-Building Travel(set per building pair)Opt-in — only when a Building distance is configured

S1 — Max Consecutive Periods

Penalizes: a teacher being active for more than "Max Consecutive Periods" (General Limits tab, default 2) periods in a row without a break, checked as a sliding window across each day.

Raise the weight when teacher burnout from long unbroken stretches is a bigger concern than almost anything else you're weighing it against — this already has the second-highest base cost of any soft constraint, so raising it further should be reserved for schools that have had real problems with this. Lower it if you'd rather let the solver bunch a teacher's periods together in exchange for a better result on something else (e.g. more Preferred Start Times honored).

S2 — Max Daily Load

Penalizes: a teacher being scheduled for more than "Max Daily Load" (General Limits tab, default 5) periods in a single day. This has the highest base cost of any soft constraint by a wide margin — the solver treats overloading a teacher's whole day as roughly twice as bad as a long consecutive stretch (S1) and five times as bad as a room change (S4). Only lower this if a school genuinely doesn't mind uneven daily loads more than other constraints.

S3 — Subject Spread

Penalizes: a class group getting more than one instance of the same subject on the same day, but only for lessons whose Bunching is set to SPREAD (Creating Lessons). A lesson set to CONSECUTIVE or NONE never triggers this — see S6 below for the CONSECUTIVE counterpart.

Raise it if double-booked-subject days (e.g. Math showing up twice on the same Monday) are specifically what you're trying to eliminate; lower it if your school is fine with occasional repeats as long as the week's total count comes out right.

S4 — Room Stability

Penalizes: a teacher switching rooms between two periods they're active in back-to-back, on the same day. Gated entirely by the "Room Stability" switch on the Teacher Welfare tab — when that switch is off, this constraint contributes nothing regardless of its weight, since the solver never even builds the underlying tracking variables for it.

Raise it for schools where walking between rooms between periods is a real time cost (large campuses, specialist labs far from general classrooms); lower it if room assignment is mostly cosmetic for your school and you'd rather the solver optimize other things freely.

S5 — Student Gap Minimization

Penalizes: a class group having a single free period sandwiched between two lessons on the same day (a "1-0-1" pattern — busy, free, busy). Gated by the "Student Gap Minimization" switch on the Student Constraints tab. Known limitation: this only detects exactly one free period in the middle — a 2+ period gap in a student's day isn't currently penalized by this constraint at all, and there's no configurable threshold the way S11 has for teachers (every detected gap is penalized, unconditionally).

S6 — Consecutive Bunching

Penalizes: a lesson set to Bunching: CONSECUTIVE (Creating Lessons) whose repeated instances (Count > 1) don't land on a single day back-to-back with no gaps. This is actually two penalties working together under one weight: one for using more than one day for the repeats (base cost 15), and one for each gap between instances on their shared day (base cost 10 per gap) — raising or lowering the S6 weight scales both together.

Raise it when a subject genuinely needs to run as a tight block (e.g. a double-Art session that isn't modeled as a single Duration: 2 lesson because you specifically want two separate back-to-back instances); lower it if you'd rather let the solver spread things out when doing so helps elsewhere.

S7 — Preferred Start Times

Penalizes: a lesson instance that doesn't start in one of its Preferred Time Slots (Creating Lessons) — but only for lessons that have any preferred slots set at all; a lesson with none configured never contributes to this constraint. Distinct from Locked Time Slots, which are hard (see the hard constraints reference's H6 entry) — a missed preference never makes generation fail, it just costs 8 points per instance that misses.

S8 / S9 — Max / Min Days Per Week

Penalizes: a teacher or a class-group leaf being active on more than "Max Days Per Week" (S8) or fewer than "Min Days Per Week" (S9) distinct days — both configured on the General Limits tab, both off by default (leave the field blank to disable), and both apply identically whether the resource is a teacher or a class group. Use S8 to discourage a teacher's or class's week from sprawling across every day when it doesn't need to; use S9 to discourage the opposite — cramming what should be a spread-out subject into too few days.

S10 — Max Span Per Day

Penalizes: a teacher's or class-group leaf's first-to-last active period on a given day stretching wider than "Max Span Per Day" (General Limits tab, off by default) periods — this counts even across a period where the resource is not actually busy, so a schedule with lessons at Period 1 and Period 7 and nothing in between still counts as a 7-period span, not "2 lessons."

S11 — Teacher Gap Threshold

Penalizes: a teacher having more single-slot "sandwich" gaps in a day than "Max Gaps Per Day" (Teacher Welfare tab, default 1) allows — unlike S5, this one has a real configurable threshold, so the first gap (or however many "Max Gaps Per Day" permits) is free, and only the excess is penalized. This is the teacher-side counterpart to S5, but with a threshold S5 doesn't have.

S12 — Cross-Building Travel

Penalizes: a teacher's or a class-group leaf's two back-to-back periods landing in rooms from two different Buildings that have a travel penalty configured between them on the Buildings page's distance matrix. Same-building consecutive periods are always free, as is any pair of buildings with no penalty entered (blank or 0).

Unlike every other soft constraint, S12 has no fixed base cost — the "Base cost" for a given violation is whatever number the admin typed into that building pair's cell in the distance matrix (e.g. 40 for two buildings on opposite ends of campus, 5 for two buildings a short walk apart), and the S12 weight slider on the Constraints page scales that per-pair number the same way it scales a fixed base cost for the others. Entirely opt-in: with no Buildings created, or no distance-matrix cell filled in, this constraint contributes nothing and costs nothing to evaluate — existing schools that never touch Buildings see no change in behavior at all.

Raise the weight when cross-campus movement between periods is a real, meaningfully different cost across your buildings (e.g. a five-minute walk to a detached Science block); lower it if building layout is a minor inconvenience you'd rather not have the solver trade off against other priorities.