-
-
Someday, Tonight.
-
The gaming backlog that starts grey, and only takes on colour once you commit to a game.
-
Tonight: one pick, one reason. Commit to it and the whole app takes on that game's colour, taken from its cover.
-
Before you commit, everything is grey. Someday is grey, Tonight is in colour - the one rule behind the design.
-
Rate it with a slider from Rough to Unreal, not stars. Statuses update as you play, so nothing needs maintaining.
-
Your library, saved from any video in two taps. No typing, no account, and it never leaves your phone.
-
Cleanup asks about the games you added months ago and never touched. Let each one go or keep it.
-
The pile gets lighter as you go. Nothing is deleted behind your back: games you let go are filed under Dropped.
-
At 20 games, two ways past the ceiling: a small subscription, or one ad you choose to watch for one more slot.
-
The only ad in the app is one you ask for. Unlimited is one small monthly subscription through RevenueCat.
-
App Icon
-
Yet Another App Icon
Inspiration
We find most of our games in 30-second vertical videos, and we forget them within the hour. When we do remember one, it goes onto a backlog that turns into a to-do list and then into guilt. Every backlog tracker we tried made it worse: unplayed counts, completion percentages and red badges. They treat a hobby like debt.
So we wanted an app with only two jobs: catch a game in one gesture, and answer "what do I play tonight?" on one screen. The name carries the whole idea. Someday is the deferral, and Tonight answers it.
What it does
- Capture: share a video from any app and the game is in your library in two taps. You don't type anything and you don't need an account.
- Tonight: one card and one reason ("Short. You've been meaning to. 6 hours."). Flick it away to get another. Tap Start and the whole app takes on that game's colour.
- Cleanup, without guilt: every so often it asks about games you added months ago and never touched. You can let each one go or keep it, and the pile gets lighter. Nothing is deleted behind your back.
- Rate and share: five honest words from Rough to Unreal, plus a 9:16 card for your story.
- What's coming: users suggest features and vote on them. You get one notification that updates in place as your idea moves along, so it never buzzes you twice.
The design has one rule: Someday is grey, Tonight is in colour. The app starts grey, and a game only gets colour once you commit to it.
How we built it
- Kotlin + Compose Multiplatform for Android, iOS, desktop and web from one codebase. It uses Clean Architecture with MVI per screen and has one feature module per screen.
- A Cloudflare Worker (TypeScript) as the backend. It proxies the catalog, attetest, Play Integrity, Turnstile on web), resolves shared links to games, verifiesrewards and sends push. - A Go importer that turns IGDB dumps into a catalog served from **Cloudflare Dsearch.
- RevenueCat for the subscription and the rewarded ad. At the free ceiling, "Watch an ad" sits next to Subscribe as an equal option. Each view is verified server-side and grants one more slot. It's the only ad in the app, and the user has to ask for it.
- OneSignal for push. OneSignal holds no user content: it gets an opaque id and a status, and the app fetches the words from our own API.
- Local-first: the library never leaves the device, and the app works fully offline
- It ships in nine languages.
Challenges we ran into
Turning a video title into a game. YouTube titles look like "GTA 6 Dancing Looks TOO Real | Nightclubs…". A normal full-text query that requires every word finds nothing, and the typo fallback then happily answers with a nightclub game. The fix was to search for every phrase window in the title and keep only the rows whose full title or alias exactly matches a span. Thattakes 3–20 ms on the full catalog.
Ranking. Linear popularity either couldn't make up for FTS5's length normalisation or it drowned out better text matches. Ranking by $$\text{score} = \ln(1 + 10^4 \cdot b)$$ fixed it, where \( b \) is the blended signal. An exact title match also has to sort first explicitly, or "elden ring" returns Nightreign.
Colour from cover art. Every accent comes from the game's cover, so it can be any hue. Clamping in HSL produced mud, so the clamp works in OKLCh. It keeps the hue exactly and pushes chroma to the edge of the sRGB gamut, with one floor: relative luminance \( L \geq 0.205 \), so that dark ink text on any accent stays above 4.5:1 contrast.
Push that tells the truth. A feature request moves through five states, and five notifications would be spam. It's one thread with a fixed thread and collapse id, whose body is rewritteneach time. Permission is requested only when you tap Send it, never at launch.
Toolchain edges. JDK 26 breaks the Android Gradle Plugin, Gradle 9.7 breaks IDE sync, and the RevenueCat KMP SDK has no desktop or web artifacts, so billing lives in its own Android + iOS module.
Accomplishments that we're proud of
- One Kotlin codebase, live on Google Play and the App Store, with the same app also running on desktop and web.
- A design system the build enforces. "Nothing red", "every screen previewed in every state, in both themes" and "attribution is always a real link" are CI gates, so they held across 120+ commits. Every state has a reviewed golden screenshot.
- Capture that feels like magic: paste a messy video link and get the right game back, from a catalog of hundreds of thousands, in milliseconds.
- Monetisation that respects the player: 20 free games, one small subscription, or an ad you choose. There are no other ads anywhere.
- Privacy by construction: no account, the library stays on the device, and the push provider never sees user content.
What we learned
- Design rules only hold if the build enforces them. Written guidelines drift, and gates don't.
- Compliance can shape the design. Real cover art can't appear in screenshots or the demo, so typographic placeholder tiles became part of the look.
- Measure before you fix. Almost every search bug first looked like a plausible failure with an obvious wrong fix, and only testing against the real catalog showed the right one.
- Local-first simplifies everything downstream: no loading screens, no offline mode, no sync conflicts.
What's next for Someday, Tonight.
- Wishlist alerts: one notification when a game you saved is released or drops in price, and nothing else.
- Growth experiments on the free ceiling: test whether 20 is the right number, with the result read in RevenueCat.
- Translated store listings to match the nine languages the app already speaks.
- Open-sourcing the swipe-stack gesture behind Tonight and Cleanup as a small Compose Multiplatform library.
- Building what users vote for on the What's coming board, and telling them when it ships.

Log in or sign up for Devpost to join the conversation.