More Than a Simple Bucket

More Than a Simple Bucket

I’ve been hard at work on my game, Cursor Incremental. I learn more every day. As I build out my code and tools, some things get much easier and faster. The new stuff, though, always takes a lot of time.

Lately, I’ve been spending more time on Reddit in the r/godot and r/gamedev subreddits. It’s a LOT of people just starting out, like me, but also a fair number of industry veterans. I see a lot of posts from high school and college students. I see a lot of my younger self in them. Their ambition often far outweighs what’s feasible.

My current experience is shaped by years of professional software development and some dabbling in games. That’s why my current project is much smaller in scope. Still, this “simple” game has already eaten two months of my time, and I don't even have a barebones demo yet to show for it.

I’ve seen posts from solo devs who want to make a crossover between Monster Hunter and Minecraft. These are games that full teams of professional developers and artists spend years building. It’s a good reminder of how big ideas can get lost in the weeds of actual implementation.

A close up of a dragon figure from Monster Hunter on a table
Photo by Robert Schwarz / Unsplash

Recently, I added a new bucket cursor to my game. In Cursor Incremental, “cursors” are the player’s main way to interact with the world. They are among the most complex parts of the game, even if they seem simple at a glance.

I want to break down all the work that went into this one cursor to show how much effort is involved.


Creating the sprite

I started by recoloring an existing sprite from kenney.nl. My cursor color palette is limited to three colors, so I had to make sure the new design fit visually.

Draggable and embodiable

The cursor needs to be draggable and “embodiable.” That means it can take on different forms, like the bucket form. Fortunately, the base components for this behavior were already built, so I mostly had to plug them in and configure them.

Hover effect

The bucket needed to appear to hover so the player could easily identify it. Luckily I had a component that would make it move up and down and appear to float. However, I spent half a day on trying to add a shadow before settling on a simple transparent circular shadow that finally looked right.

0:00
/0:09

Sucking in items

This part had two layers: the visual animation and the behavior.Items in range move toward the bucket and shrink to show they’re being consumed. Once they hit the center, they’re removed from the ground and added to the bucket. If the bucket is full, the animation and behavior stop, and any incoming items pop back to normal.

    • Visuals: When the bucket lands, I use particles to simulate resources being sucked in. I used a basic GPUParticles2D node in Godot to make pixels zoom toward the bucket’s center. A progress bar shows how full the bucket is and syncs with its internal data.
    • Behavior: This was the tricky part. When the player clicks, the bucket locks in place and begins collecting. Locking the bucket and mouse position was tough. I solved it by locking the bucket and warping the mouse back when the player releases the button. I also had to handle differences in mouse behavior between PC and web exports.
0:00
/0:04

Dumping items

This had multiple animation steps:I built this on top of the existing item dropper component I originally made for trees and rocks.

    • The bucket tips when it’s over the storage bag, but only if it has items.
    • When the player clicks while hovering over the bag, the bucket flips upside down. It also locks in place to avoid dumping items in the wrong spot.
    • The bucket has to rise high enough so players can actually see the items dumping.
    • The drop timing needs to feel good visually and still be functional. Items have variable "density"—one log might represent several. I handle this by spawning the items back into the environment and letting the existing storage bag logic collect them.

State machine

Managing the transitions between actions was the hardest part. Dumping can’t start before the bucket flips. What if the player releases the button before the flip finishes? I had to build out a proper state machine to manage all these edge cases. Even with the state machine, there is some spaghetti code holding it all together.

0:00
/0:07

]

Sound effects

Surprisingly, this was the easiest part. I found some free commercial use sounds vai Soundly and just wired them up to the right events in the code. Are those sound effect currently burp and fart sounds? Yes... I may leave them in as a little easter egg that plays one in a million times, just to make people question their sanity a bit


This is just a rough summary of a few days of work—all for a 16x16 pixel bucket that picks up and drops a few items. I’m writing this to highlight how much hidden complexity exists in game development. For people who’ve never tried building a game, it’s easy to assume something will be simple just because the concept is.

The hardest part is when systems need to start interacting. Moving a bucket around the screen is relatively easy. But when a log needs to move from the world into the bucket, back to the world, into the storage bag, and finally show up in your inventory to be to be displayed on screen then used for an upgrade—that’s when you’re trying to maintain data integrity across several systems: player objects, UI, and game state. It's challenging, but ultimately satisfying once it all starts working together.