Lucas Vieira

Pip’s Flight: A game in 10 days

[Source] [Demo]

Last summer I finally did something I’d been meaning to do for years: I entered a game jam. Shovel Jam 2025 was a good fit for a first-timer. Welcoming community, a reasonable 10-day timeline, and an interesting theme: “Just Get Started.”

The result was Pip’s Flight, a 2D platformer about an owl who can’t fly yet. You guide Pip through three levels with limited jumps, trying to collect stars and reach the clouds. I handled everything solo:

The Idea

The theme “Just Get Started” got me thinking about first attempts at anything, those awkward early stages where you don’t really know what you’re doing yet. Learning to fly felt like the right metaphor. Pip is an owl, but grounded. Each level gives you just enough jumps to get through, so every leap matters.

I wanted that feeling of carefully planned movement. You can’t spam the jump button. You have to think about your route, commit to it, and sometimes just trust that you’ll make it across the gap.

Building in Godot

This was my first real Godot project. I picked it because it is lightweight, open-source, and has a nice community. GDScript (Godot’s scripting language) felt Python-adjacent enough to just jump in, and the scene system just makes sense once you get it.

The movement system uses a state machine pattern: Idle, Walk, Jump, Fall, Glide. Each state handles its own physics and transitions:

1# From player_state.gd
2const IDLE = "Idle"
3const WALK = "Walk"
4const JUMP = "Jump"
5const FALL = "Fall"
6const GLIDE = "Glide"

The jump state checks if you have jumps available before executing:

1func enter(_previous_state_path: String, _data := {}) -> void:
2    if jump_cooldown.is_stopped() and player.can_jump():
3        animated_sprite_2d.play("flap")
4        player.velocity.y = player.JUMP_VELOCITY
5        Game.increase_jump_counter()
6        jump_cooldown.start()

The state machine handled the edge cases cleanly, like blocking mid-air jumps unless you’ve unlocked the double jump, or moving smoothly from glide back to fall when you let go of the button.

Art and Animations

I love crafts in my free time; sketching, painting, that kind of thing. So I was excited to do all the art and animation myself. I used Aseprite for the sprites and animations.

Pip’s animations

Pip’s animations

What Went Wrong

Everything takes longer than you think. I spent two days just getting the physics to feel right. The collision detection was buggy until day 6. I had planned four levels and cut it to three at the last minute because level design is slow.

The game is also pretty short—you can finish all three levels in about 10 minutes if you know what you’re doing. But honestly? For a first jam, shipping something complete felt more important than shipping something huge.

What Went Right

The jump limit mechanic worked exactly how I wanted. Players feel the constraint. You’re constantly counting remaining jumps in your head, planning your next three moves. That tension between “can I make this jump?” and “do I have jumps left?” is the whole game.

I also managed to avoid scope creep. No enemies, no combat, no power-ups beyond the glide. Just movement, jumping, and careful planning. For 10 days, that was the right call.

Lessons Learned

Start even simpler. I thought “three levels, basic platformer” was minimal. It wasn’t. Next time: one mechanic, one level, iterate from there.

Juice matters. Adding screen shake when you land, particles when you collect stars, sound effects for everything—these tiny details made the game feel way more polished than it actually was.


If you want to try it, it’s free on itch.io.

#game