Back to Guides
Scheduling Guide

Hockey League Scheduling, the Way HAHL Actually Does It

Not theory. The constraint list, the rotation problem we hit for years, and the auto-scheduler we are putting in front of HAHL's 2025 fall season at Huntsville Ice Sports Center.

14 min readLast updated: November 2025

The Havoc Amateur Hockey League — HAHL — plays out of Huntsville Ice Sports Center inside the Benton H. Wilcoxon Municipal Ice Complex at 3185 Leeman Ferry Rd SW. I started playing beer league in Huntsville in 2010, having never skated before, in the only adult league in town at the time. After several seasons of dissatisfaction with how that league was being run, a group of us founded HAHL in 2016 as a breakaway, and I have run the Bronze division's schedule every season since. The league has continued to grow — today HAHL runs four divisions (Bronze, Steel, Silver, and Iron), with the Huntsville Havoc SPHL team as title sponsor.

For most of those years the schedule was built manually — a spreadsheet, a round-robin matrix, and an evening at a kitchen table. It worked, the way most manual schedules work: just well enough that nobody noticed the specific way it kept failing. That specific failure is what this guide is about, and it is not the failure most articles on hockey scheduling describe.

The Real Problem with Manual Scheduling

The story you usually read is that manual schedules give some teams too much prime ice and other teams too little. That happens, but it is not the failure that drove HAHL to change anything. The failure that did was simpler and more annoying: teams kept playing each other two weeks in a row.

Here is how it happens. You build a clean round-robin matrix on paper — every team paired against every other team, evenly distributed. Then you lay that matrix onto the actual ice slots the rink has given you. Slots and matchups never line up cleanly, so you rotate. You move week 3 slot 2 to week 4. You shuffle a Friday game to the following Sunday. Each shuffle is sensible in isolation. None of them check whether the team-pair you just moved already played the same opponent the week before.

Across an HAHL Bronze season, we would routinely end up with two or three pairs of consecutive identical matchups by the time the schedule was published. Captains noticed. Players noticed more. The fix during the season was to swap individual games, which itself created new consecutive-pair problems further down the schedule. The whole structure has the property of a leaky balloon — push in here, bulges out there.

The actual constraint that matters: No team should play the same opponent in consecutive weeks. Almost every other "fairness" rule people talk about is easier to satisfy than this one, because it is the only rule that requires the scheduler to remember what came before.

Round-Robin Formats — and What HAHL Uses

Single round-robin

Every team plays every other team once. For an eight-team division that produces seven games per team — a short season for a paying league. Single round-robin is the right call only when you are running a clinic, a learn-to-play offshoot, or a short summer league where players are happy paying for fewer games.

Double round-robin (the HAHL Bronze format)

Every pair meets twice. Eight teams gives you 14 games per team — a full fall or winter season at HAHL's typical pace. Double round-robin is the default for any league with six to twelve teams per division because the math lands in the sweet spot: long enough to feel like a season, short enough that the rink is still leasable.

Triple round-robin

Three meetings per pair. We considered it pre-split when HAHL was still a single division of six teams — that would have been 15 games each. Triple round-robin works for small leagues, but it makes the consecutive-opponent problem worse because there are simply more meetings of the same pair to space out.

Cross-division play

With four divisions in HAHL today, cross-division games would be uneven in standings (the skill gap between, say, Bronze and Silver is significant), so we keep regular-season play within division. A handful of crossover or exhibition games mid-season — labeled as such and not counted in standings — give players something different to look forward to without distorting any division's playoff race.

The Constraints HAHL Actually Applies

Every league has a constraint list, even if it is not written down. Writing it down is the first step toward any automated scheduling that will not fight you. The HAHL Bronze list, in roughly the order that matters:

  1. No consecutive same-opponent matchups. Hard constraint. This is the one manual scheduling kept breaking.
  2. Holiday and city-event blackouts. The Wilcoxon Complex is a city-operated building. When the city closes it — major holidays, large events — every adult league moves around it together. We pull those dates before assigning anything.
  3. Shared-goalie pairings. Some Bronze players also play Silver. Two teams that share a goalie cannot be on the ice at the same time, ever. That is a hard pair-of-teams constraint at the slot level.
  4. Even distribution of slot times. Huntsville Ice Sports Center has different slot times across the week, and not all slots are equally desirable. Late Sunday ice and the first Friday slot of the night are the obvious extremes. No team should land on the unpopular slots disproportionately, and no team should hoard the popular ones either.
  5. Bye-week balance. If the schedule produces byes, distribute them evenly. A team that gets two byes in the first four weeks is going to feel the back half of the season very differently than a team that gets none.
  6. Captain reschedule rules, decided up front. Captains can request swaps inside a defined window (we use three weeks before the game). After the window closes, only the board can move games. This is not really a scheduling constraint, but it is a governance constraint that determines how often the schedule has to be re-validated.

What's Changing for HAHL's Fall 2025 Season

Heading into Fall 2025, we are transitioning HAHL onto RocketHockey. The public site (havocahl.com) still routes to our existing HockeyShift setup while the cutover is in flight, but the schedule generator we are using to build the Bronze season is now RocketHockey's constraint solver. The most consequential change was not features or interface — it was that the schedule generator treats "no consecutive same-opponent" as a hard constraint up front, alongside the goalie-sharing and blackout rules. The generator backtracks on its own placement decisions to keep all constraints satisfied. If it cannot find a fit, it tells me which constraint pair is irreconcilable, and I either relax one or add an ice slot.

The behavioral difference for me as the Bronze scheduler is that I no longer build the matrix then rotate. I declare the constraints, let the generator place games, and then read the output. The first Bronze schedule produced by the new generator had zero consecutive identical matchups across the season — not "fewer than before," zero. That was the single biggest qualitative improvement, and it took roughly the same total time end to end, just spent in different places: more time defining constraints up front, less time chasing rotation problems after.

None of that is a sales pitch for one particular tool. The same approach works in any scheduler that lets you declare consecutive-pair as a hard constraint. The tools that do not let you declare it that way — the ones that treat it as a preference, or expect you to enforce it visually — produce manual-quality output even when they call themselves automated.

Step-by-Step: How a Season Gets Built

These are the steps the HAHL Bronze season runs through, in order. Each one is broken down further inside RocketHockey, but the sequence is the same regardless of tool.

1

Catalog every constraint before you touch the calendar

List the things the schedule has to respect: team count and divisions, every available ice slot (with day and time), holiday and rink blackout dates, shared-goalie pairings between teams, and any board-imposed limits like maximum prime-time ice per team across the season.

2

Pick the format that matches your team count

For HAHL Bronze with eight teams, a double round-robin produces 14 games — a full season without padding. Six teams may need a triple round-robin to avoid an undersized season; twelve or more, single round-robin plus cross-division play.

3

Make "no consecutive same opponent" a hard constraint

This is the rule that manual schedulers always violate by accident. Tell the generator that no two teams can play each other in consecutive weeks. If your tool will not accept this as a hard constraint, switch tools — because if you set it as a soft preference, the rotation step will break it.

4

Generate, then read it like a player

Before you ship, scan as if you are on each team. Does any team play three Sundays in a row? Does Bronze 4 get Friday ice twice as often as Bronze 1? The generator handles the rules you gave it. Player-experience review is the part still on you.

5

Publish with explicit captain expectations

When you send the schedule, send the rules at the same time: which week reschedules are allowed, what counts as a forfeit, how to request a swap. The schedule is half the story; what teams do when something breaks is the other half.

6

Keep a rolling reschedule window

Even with hard constraints, players get hurt, work travel happens, the city closes the building. Reserve one or two open slots in your ice contract that you only assign three weeks ahead. That buffer absorbs late changes without forcing you to rebuild the whole season.

Where Auto-Scheduling Still Falls Short

Auto-scheduling does not fix every problem. After a season of running HAHL Bronze on a constraint solver, here is what I still spend manual time on:

Mid-season player movement

A player gets hurt in week 6 and asks to skate as a sub on another roster the next week. The schedule has no idea this happened. Constraints around shared rosters need a human to spot and adjust.

Rink-side reschedules

Wilcoxon is a municipal building. When the city closes it for maintenance or a non-hockey event, every league at the complex moves together. That is not a generator problem — it is a logistics problem, and the generator can only help by re-validating the constraint list after the new dates land.

Late team additions or scratches

A team adds in week 2 (rare but it happens) or drops by week 8 (also rare, also happens). Both force a re-generation, and the generator has to make sure the new constraints do not create back-to-back matchups against the teams that are still around. Plan a buffer at the start of every season for one regeneration event.

The thing the constraint solver does not know about

Every season there is at least one rule we forgot to declare. One year we did not flag a captain's wedding weekend. Another year we forgot a tournament-prep week that took two referees out of the rotation. The generator does what you tell it. The work the generator cannot replace is the part where you imagine the season before it starts.

Build Your Schedule the Way HAHL Does

Declare your constraints, let the generator place games, read the output like a player. RocketHockey gives you the same scheduling engine we are running for HAHL's Fall 2025 Bronze season. League plan starts at $25/month.