Inspiration

The idea struck me while watching adventure films where the ground gives way at any moment. I wanted to recreate that heart-in-your-throat tension in a simple 2D platformer—every step could be your last until you reach the only door out.

What it does

Only One Door challenges players to traverse a series of fragile platforms. As you approach gaps, the ground slides away; step on the wrong spot and a hidden pit opens beneath you. The goal is to reach the lone exit door in each level without falling.

How we built it

  • Engine: Godot 4.x
  • Scene setup: A Node2D root with Ground nodes, Player (CharacterBody2D), and three Area2D triggers (GapTrigger, HoleTrigger, DoorTrigger).
  • Smooth animations: Used SceneTreeTween to slide platforms away when GapTrigger fires.
  • Precision pits: Split one CollisionShape2D into three shapes (full, left, right) and swap them in HoleTrigger callback with set_deferred() to carve out a safe hole.
  • Respawn & transitions: Player fall-limit triggers get_tree().reload_current_scene(), and reaching the door calls change_scene_to(next_scene).

Challenges we ran into

  • Collision hiccups: Directly disabling a collision shape in the physics callback kept the player stuck in mid-air. We solved it by deferring the disable call.
  • Trigger timing: Getting the gap to slide at just the right moment required iterative tweaks to trigger area positions and adding small code delays.
  • Scene management: Ensuring smooth respawns and door transitions without frame drops led us to streamline scene reloads and preload the next level.

Accomplishments that we’re proud of

  • A fully modular Level.gd that cleanly handles three distinct triggers (gap, hole, door).
  • Robust deferred collision swapping for realistic pit openings without any physics glitches.
  • Seamless scene transitions and reliable instant respawn on falls, creating a tight, responsive gameplay loop.

What we learned

  • Mastery of Godot’s SceneTreeTween and chainable tween API.
  • Why and how to use set_deferred() when modifying physics properties mid-frame.
  • Best practices for signal-driven architecture in 2D platformers.
  • Managing multiple levels via change_scene_to() and exportable PackedScene properties.

What’s next for Only One Door

  • Add new trap types: moving platforms, timed spikes, rotating blades.
  • Implement a fade-out/fade-in transition tween for even smoother level changes.
  • Design an “endless mode” with procedural level generation and a global high-score board.
  • Polish mobile controls and touch-friendly UI for a wider audience.

Built With

  • godot
Share this project:

Updates