Your Friends Can Now Actually Join Your Season (Without You Copy-Pasting a Code)

By Vincent Luder
Published February 16, 2026

We built a proper invitation system for private seasons, fixed some annoying bugs, and made a few quality-of-life improvements. Here's everything that changed.

Let me paint you a picture. You create a private season on HappyCharts. You're excited. You want your friends to join. So what do you do? You copy an access code, open WhatsApp, paste it, add some context because the code alone means nothing, and then hope your friend figures out where to enter it. Then they message you back: "Where do I put this?" And you explain it. Again. For each friend.

That's how it worked before. Functional? Sure. Elegant? Absolutely not.

So we fixed it. You can now just... invite people. Like a normal application built after 2010.

How Invitations Work Now

There are two ways to invite friends, depending on where you are in the flow.

During season creation: When you're setting up a new private season, step 4 (Access & Friends) now has a friend list on the right side of the screen. Your friends show up, there's a search bar at the top, and you click to select whoever you want to invite. Selected friends get a nice checkmark. When you finish creating the season, invitations go out automatically. No copy-pasting. No "hey check your DMs" messages.

From the season detail page: Already running a season and want to add someone? There's now an "Invite Friends" button in the header. Click it, a modal pops up with your friends list, you select who you want, hit "Invite," and you're done. Friends who already joined show a "Joined" badge so you don't accidentally invite someone who's already in.

On the receiving end, your friend sees a notification badge in the navbar. They open the Friends Drawer, go to the Seasons tab, and there's the invitation with accept and decline buttons. Accept, and you're in. The season shows up in "Your Seasons" with a Play button ready to go.

Simple. The way it should have been from the start.

The Seasons Tab

Speaking of the Friends Drawer — it got a new tab. "Seasons" combines two things into one view: your participating seasons (with a Play button for each) and any pending invitations. Before this, there was no central place to see "what seasons am I part of?" without navigating to the Private Seasons hub. Now it's one click away, always accessible from the navbar.

The notification badge in the navbar also got smarter. It used to only count pending friend requests. Now it includes season invitations too. And here's the part that was genuinely broken before: the badge count only loaded when you opened the Friends Drawer. So you'd have 3 pending invitations and zero indication until you happened to click the right button. Now it loads immediately when the page loads. You know, like a notification should.

Bug Fixes & Other Improvements

While we were in there, we fixed a few things that had been bugging us:

Winrate display was wrong. The calculation for displaying your winrate on the platform was off. Not the underlying data — just how it was shown. If you looked at your stats and thought "that doesn't seem right," you were correct. It's accurate now.

Articles page was hiding content. The articles page was only showing the 3 most recent articles instead of all of them. If you're reading this article right now, you can verify this is fixed by scrolling down and seeing more than three entries. You're welcome.

Private season cronjob had an error. The background job that transitions seasons between states (upcoming to active, active to completed) had a bug that could cause it to fail silently. Fixed. Your seasons now reliably transition on schedule.

Tournament creation is still fast. Just a reminder from last update: creating a tournament used to take over a minute. It now takes a few seconds. If you haven't tried creating one recently, give it a shot. Blink and you'll miss the loading screen.

What's Actually Happening Under the Hood

For those of you who care about the technical side: the invitation system is a full backend implementation. New database table, new API endpoints, proper status tracking (pending, accepted, rejected). When a host sends an invitation, it validates that the season isn't full, the user isn't already a participant, and there isn't already a pending invite. When someone accepts, it creates a proper participant record with the join method tracked as "invite."

We didn't take shortcuts here. The old "invite" was literally just adding someone as a participant without asking them. No consent, no choice, just "surprise, you're in a tournament now." The new system actually asks first. Novel concept.

What's Next

We're not done with the social features. Notification improvements, season chat, and more are on the roadmap. The invitation system was the foundation — now we can build on it.

But for now: go invite your friends to a season. It takes about 5 seconds. And this time, they won't have to ask you "where do I enter this code?"