3 min read10 hours ago
–
Picture this: a top-down 2D realm split between white and black dimensions. You’re locked in one at a time — walls, enemies, and secrets from the other side lurk invisible but very real. Bump into a ghost wall? Oof. Ambushed by unseen foes? Game over. The hero’s lifeline? A flickering torch that rips open the veil, revealing a circular glimpse of the hidden world wherever your cursor glows. This was my wild ride for a game jam themed Duality, and Godot was my chaotic playground.
But here’s the rub: making invisible worlds feel alive — collidable, deadly, animated — without tanking performance or glitching into oblivion? That became my three-week obsession.
Experiment 1: Clipping Masks — The Jittery Parenting Nightmare
Godot’s clippin…
3 min read10 hours ago
–
Picture this: a top-down 2D realm split between white and black dimensions. You’re locked in one at a time — walls, enemies, and secrets from the other side lurk invisible but very real. Bump into a ghost wall? Oof. Ambushed by unseen foes? Game over. The hero’s lifeline? A flickering torch that rips open the veil, revealing a circular glimpse of the hidden world wherever your cursor glows. This was my wild ride for a game jam themed Duality, and Godot was my chaotic playground.
But here’s the rub: making invisible worlds feel alive — collidable, deadly, animated — without tanking performance or glitching into oblivion? That became my three-week obsession.
Experiment 1: Clipping Masks — The Jittery Parenting Nightmare
Godot’s clipping masks seemed perfect at first. Set a node to “clip only,” and its children vanish outside that shape. So, I dreamed up parenting the entire opposite dimension to the torch node. Switch worlds? Reparent on the fly. Boom — torch reveals a masked peek.
It worked… kinda. A script flipped parenting between black and white worlds. But children follow their parent. Mouse moves? The whole damn dimension dragged along, turning your cursor into a world-wobbling curse.
My fix? A per-frame script resetting the child’s global position to match the camera. Jitters everywhere. Player glitches through walls. Constant reparenting hammered performance. Verdict: Cool hack, trash execution. Scrapped.
Experiment 2: Viewports — Visual Magic, Physics Fail
Viewports to the rescue! I built two: one for each dimension. In a CanvasLayer, two textures rendered them side-by-side. The top one got a custom shader — radial gradient at mouse pos, blending pixels from the other viewport like a spectral spotlight. Camera tweaks synced it all smoothly. The reveal effect? Chef’s kiss.
But visuals aren’t enough. Physics? Zilch. The viewport worlds were just pretty pictures — no collisions, no enemy AI pinging the player.
Crude workaround: Keep both dimensions as live physics scenes (invisible by default). On world-switch, recursively duplicate every node into the viewport, flip visibility, and pray. Detect changes each frame? Copy-paste city. It interacted perfectly… until animations hit. Enemies stuttered like broken flipbooks. Performance dipped hard on bigger scenes. Still, it’s my current champ — choppy but functional.
The Nuclear Option: Forking Godot’s Source
Godot’s open-source soul whispered temptation. Why not patch viewports to clip any external node, not just kids? Downloaded the source, built a custom editor binary, dove into OpenCode for analysis. Added an “external clip target” field to Viewport code.
It compiled, even showed in the inspector… but no dice on runtime magic. Rendering pipeline fought back. I shelved it (for now) — but damn, modding your engine mid-jam feels godlike.
Press enter or click to view image in full size
What’s Next? Lessons from the Veil
This mess birthed a beast of a prototype. The torch reveal pops, duality tension slaps, and it’s playable. Performance tweaks (culling, object pooling) might tame the copy-paste beast. Or… RemoteTransform2D for viewport syncing? Subviewports with canvas culling? Community, hit me with ideas.
Game jams thrive on “good enough chaos.” Duality’s duality nailed it — fun hacks, brutal tradeoffs. Can’t wait to polish and ship.
[Play the prototype here once it’s up!] #GodotEngine #GameJam #Duality #GamedevHorrorStories