Devlog 1: Starting Tuggy - Building a Clicker Game That Scales

5 min read
launch product architecture

Devlog 1: Starting Tuggy - Building a Clicker Game That Scales

I'm starting a new project this week. The idea is simple: what if you could create viral 1v1 battles for anything? Turkey vs Brazil. Cats vs Dogs. Zuck vs Musk. Each one gets its own URL, and people just click like crazy to vote.

I got the idea watching TikTok Live Battles. People love that competitive voting energy. But I wanted to make it more accessible, no streaming required. Just pure clicker game mechanics with global real-time sync.

The Technical Challenge

The hard part isn't making a button that increments a counter. The hard part is making it work when thousands of people are smashing that button simultaneously, and everyone needs to see the same numbers. Plus it needs to feel instant, even though there's a database somewhere trying to keep up.

I spent the first few days just thinking through the architecture. Here's what I landed on:

Tuggy Architecture - SvelteKit frontend with client batching, Supabase for real-time subscriptions, and Fly.io deployment

SvelteKit for the frontend because I wanted something that compiles to vanilla JS and doesn't ship a massive runtime. Performance is going to matter when we're updating vote counts and rendering particles on every click.

Supabase for the backend which gives me Postgres, real-time subscriptions, and auth all in one. The real-time piece is critical because I need to broadcast vote changes to everyone watching a matchup.

Fly.io for deployment mainly because they support wildcard subdomains out of the box. Each matchup can be cats-vs-dogs.tuggy.io instead of ugly query params.

Early Decisions That Might Matter

One thing I'm doing differently: no login required to play. I see too many apps put up barriers before you can even try them. For Tuggy, you land on a matchup and you can start voting immediately. I'll use device fingerprinting to track anonymous users, and they can optionally sign up later if they want leaderboard stuff.

I'm also keeping all progression temporary and scoped to each matchup. No grinding, no permanent upgrades. When you open a new matchup, everyone starts equal. This keeps it accessible and prevents the "I'm too far behind" problem that kills most idle games.

What's Actually Built

Right now I have the basic voting loop working locally. You can click a button, it batches votes client-side for 1 second, then flushes them to Supabase (I later wrote a detailed breakdown of how vote batching works). Other connected clients get the update via real-time subscriptions. It works, but there's so much polish missing.

No particles yet. No sound. The vote bar just jumps around instead of smoothly animating (I fixed this with smooth interpolation). The upgrade system is stubbed out. But the core loop is there.

Next Week

I need to tackle the mobile experience. This is going to be primarily a mobile game, so touch events need to feel perfect (later covered in mobile touch optimization). I'm planning to add PixiJS for particle effects and work on making each tap feel satisfying with haptics and visual feedback.

Also need to set up proper deployment and get a real domain. Running on localhost doesn't help anyone discover this thing.