I’ve been a Leafs fan my whole life. I was born this way, it wasn’t by choice.
Growing up, I always wanted one of those Budweiser goal lights - the ones that flash red and sound like a foghorn when a goal goes in. Every Canadian kid watching Hockey Night in Canada wanted one.
That was twenty-something years ago. I now have a house, disposable income, and enough programming knowledge to do something about it.
Nobody can stop me anymore.
The idea
I wanted the lights behind my TV to react when the Leafs score.
Not a phone notification. Not a button press. I wanted the room itself to react in the moment.
At first, this sounded like a pretty straightforward weekend project:
- watch for a goal
- send a command to the lights
- done
The deeper I got into it, the more I realized the entire project lives or dies on one thing: latency.
The problem with “real-time”
When a goal is scored, the experience happens instantly - the puck crosses the line, the crowd erupts, the announcers lose their minds, you jump out of your seat.
If the lights trigger 10 seconds later, the illusion is gone. Even 3 seconds feels wrong.
The goal wasn’t …
“Can the system eventually figure out that a goal happened?”
The goal was…
“Can the system react at the same moment I experience the goal on the broadcast?”
Those are completely different problems.
The obvious solution
I started by looking into APIs.
The NHL has public APIs. There are commercial sports data providers. There are already apps tracking game state in real time. Surely somebody had already solved this problem.
The rough idea looked something like this:
- Poll the current game state
- Detect when the score changes
- Trigger the lights
Easy.
…right?
The problem with APIs
The first thing I learned is that “live” sports data isn’t really live.
There’s delay everywhere:
- score validation
- provider ingestion
- API updates
- polling intervals
- network latency
- broadcast delay
And worst of all, your TV broadcast may already be delayed differently depending on:
- cable
- streaming provider
- device buffering
- internet latency
That means even a fast API isn’t synchronized with your game feed.
If you pause the game to take your kids back to bed after they had to ask you one more question, the API doesn’t pause with you. If your stream buffers for a few seconds, the API doesn’t buffer with you.
That’s not what I wanted.
Trying to define the real problem
This was the first major shift in thinking.
Originally I thought I was building:
“A system that knows when a goal happens.”
What I was actually trying to build was:
“A system that reacts to the broadcast itself.”
That distinction ended up shaping the entire project.
Once I started thinking about it that way, something became obvious: the broadcast is the real source of truth. Not any API.
So instead of asking:
“Did the internet say a goal happened?”
I started asking:
“Can I detect the goal directly from the screen?”
The pivot
At this point, I still had no idea how detection would actually work.
Maybe OCR?
What I did know was:
- APIs weren’t fast enough
- I needed direct access to the broadcast
- and I was probably about to make this project significantly more complicated than necessary
Naturally, I kept going.
Next: How do I actually detect a goal from the broadcast?