Brackeys Game Jam 2026.1 – Day 4 Closing the Loop
Today was different.
Not in a flashy, “I built something massive” kind of way - but in a quieter, more satisfying way. The kind of day where things stop feeling like systems and start feeling like a game.
Yesterday, all six chunks were finally built. The forest existed. The arc existed. The pacing felt right. But it was still missing something - the emotional landing. The moment that makes the theme stick.
Today, I closed the loop.
The Forced Flip
The biggest milestone of the day was implementing the forced world flip in the clearing.
Up until this point, swapping between the normal and corrupted world was entirely player-controlled. That control was part of the design language - the player chooses when to break reality.
So breaking that rule felt important.
I added an invisible Area2D trigger in the final clearing. As the player walks forward - thinking they’ve reached the end - the game flips the world for them. No input. No warning.
And it worked.
The moment the world snapped and the path behind disappeared... it finally felt like the concept landed.
Timing the Realisation
But the flip alone wasn’t enough.
If the screen faded immediately, it would feel abrupt. Cheap. Unprocessed.
So I added a short reaction timer - a 3–5 second window where the player can turn around and see that the path they walked is simply... gone.
It’s such a small detail, but it changes everything. That silence is where the idea breathes.
You don’t need an enemy. You don’t need a jump scare.
You just need space.
Fade to Black (And Letting It Linger)
After that pause, I implemented a proper fade-to-black using a CanvasLayer and a fullscreen ColorRect, tweening the alpha smoothly over 1.5 seconds.
Then came the final touch: text appearing after the fade. Minimal. No over-explaining. No exposition dump. Just enough to leave a mark.
And when I played it from start to finish and watched that final fade roll in... it finally felt complete.
Building a Real Title Screen
Another major shift today was adding a proper title screen.
Before today, the game just loaded straight into the level. Functional, yes - but not intentional.
I created a dedicated Control scene for the title, built a simple layout with a background, game title, and start button, and wired it up using change_scene_to_file().
It’s simple. Clean. No fancy animations.
But now the project opens like a game, not a test scene.
That psychological shift matters more than I expected.
Checkpoints & Fall Reset
Today was also about protecting the experience. Platformers without safety nets can quickly turn frustrating - especially in a jam context where polish time is limited.
So I implemented a lightweight checkpoint system. A central CheckpointManager stores the last safe position. Each chunk can have a reusable CheckpointTrigger that updates it automatically. If the player falls off the world into a FallResetZone, they respawn at the last checkpoint with their velocity reset.
No lost progress spirals. No punishing restarts.
Adding Feedback to Swapping
I also added a quick screen flash effect when swapping worlds. I originally attempted a fullscreen shader ripple - and while it didn’t cooperate in time for today’s scope, it was a valuable experiment. Instead, I pivoted (a very jam-specific skill) and implemented a clean, warm-toned flash using a ColorRect and tweens.
It’s subtle, responsive, it makes the swap feel intentional, and most importantly - it doesn’t risk destabilising the build.
The Technical Layer (For Dev Readers)
For those interested in the implementation side:
- The forced flip is triggered via
Area2D.body_entered, with player validation using groups. - The world swap logic is encapsulated in a reusable function (
force_swap()), maintaining clean separation of responsibility. - The fade is implemented using
create_tween()on aColorRect.modulate.a, avoiding animation players for simplicity. - Checkpoints auto-connect signals in
_ready()to allow duplication without manual signal wiring. - The respawn logic resets
CharacterBody2D.velocitybefore repositioning to avoid fall-through issues.
The entire system remains modular and decoupled - no tight coupling between level logic and swap logic.
That’s a small win I’m proud of.
🌿 Where It Stands Now
As of today:
- Full level structure is complete.
- Forced flip works.
- Reaction window works.
- Fade and ending text work.
- Title screen works.
- Checkpoints and fall resets are stable.
- Swap feedback feels good.
And most importantly:
The game now has a beginning, middle, and end.
Slightly Tired, But Proud
I’m not exhausted. I’m not overwhelmed. I’m slightly tired... but proud.
Today wasn’t about expanding the scope. It was about finishing something.
And for a first fully scoped Godot jam project, that feels huge.
