Clicker Games With Scratch Card Mechanics in Scratch
Making a clicker game where scratching reveals bonuses is a common project request on the Scratch forums. The basic idea is simple: you click to earn currency, buy upgrades, and occasionally encounter scratch cards that reveal random rewards. The mechanics are straightforward individually, but combining them cleanly requires understanding how Scratch handles variable updates and sprite interactions under load. Start with the clicker foundation. Create a score variable and a clicker sprite. When clicked, add 1 to score. Then add a shop with at least two upgrade types — one that increases points per click and another that adds auto-clickers. Test that the numbers scale linearly before adding anything else. Most beginners skip this and get confused later when upgrades feel unbalanced. The scratch card system needs its own structure. Create a card sprite with two costumes — one showing the covered card surface and one showing the revealed content. When a player interacts with the card, switch to the revealed costume after a threshold of "scratching" is reached. I used a custom block called "scratch_amount" that increments whenever the mouse is pressed while hovering over the card. Once that value exceeds a set number, trigger the reveal. This is simpler than trying to detect partial scratching through pixel-level operations, which will kill your frame rate.
Auto-clickers deserve attention because they are the first thing that breaks a prototype. An auto-clicker that runs in the main thread will compete with your scratching logic and cause visible lag. The fix is to offload auto-clicks to a separate sprite with its own forever loop, and use a broadcast message to communicate the score increase back to the main variable. This keeps the two systems decoupled. You also want to cap the auto-click rate. Without a cap, the game becomes unplayable around the five-minute mark as click frequency compounds faster than upgrade costs can scale. Random reward generation is where most people make mistakes. If you use a simple random number block for card contents, you will get uneven distribution. I ran into this when testing — some cards repeated the same low-value reward three times in a row, which felt broken to players. The solution is to assign each reward a weighted probability and use a lookup list rather than pure randomness. Create a list called "reward_table" where each entry contains the reward name and its weight value. Then use a cumulative weight algorithm to pick from it. This ensures rare cards actually feel rare without vanishing entirely over a hundred plays. Another issue I encountered involves variable scope. If you create the scratch_amount variable inside the card sprite without setting it to "for this sprite only," it becomes a global variable that resets or gets overwritten by other sprites. I spent about forty minutes debugging what I thought was a clone bug before realizing the variable was being cleared by a different sprite's reset routine. Always double-check your variable scope settings.
Performance tends to degrade once you have more than six or seven active scratch cards on screen simultaneously. Each card running its own hover detection and scratch_amount increment creates overhead that adds up. The workaround is to use a single global "is_scratching" flag and a single broadcast-based system rather than having each card monitor the mouse independently. One central script checks mouse position against all active card sprites and updates their individual scratch amounts. This reduces the active script count significantly and keeps the game running smoothly even with a full board of cards. Save functionality is another area people overlook until it is too late. Scratch does not persist variables between sessions by default. Use the Storage extension or a simple local storage approach with the "Set [key] to [value]" blocks in JavaScript if you are publishing to the web. Without saves, players lose progress on refresh and will almost certainly abandon the game. I added a basic save system using a JSON-encoded string stored in localStorage. Load it on startup and merge any new values with saved ones to avoid overwriting upgrade levels the player earned. The economics need a light touch early on. A common mistake is making the first upgrade too expensive relative to the click value. If a player has to click fifty times to afford a +1 per click upgrade, they will lose interest before the second card appears. Keep the initial upgrade cost between three and ten times the current click value and scale the multiplier gradually. The goal is a short feedback loop where effort translates to reward quickly, then stretch that loop as the game progresses.
Get the Full Details

I also learned the hard way that Scratch's event handling has a quirk with overlapping broadcasts. If two sprites both respond to the same broadcast and one triggers another broadcast inside its handler, the order of execution is not guaranteed. I had a card reveal event that was sometimes triggering double rewards because the reveal broadcast fired while a second sprite was still processing the previous card's cleanup. The fix was to add a "revealed" flag to each card sprite that prevents the reward from being granted twice, and to sequence the broadcast chain so reveals happen only after all card interactions finish. If you are looking for a reference implementation, the Scratch community has several open projects that demonstrate these patterns. Searching for "idle clicker" or "scratch card" on the platform will give you working examples to study. The source code is visible on any published project, so you can reverse-engineer how other creators handled the variables, broadcasts, and timing. Learning from existing implementations saves time compared to discovering these edge cases through trial and error alone.