Best approach for mini-games loaded into a dynamically-sized Control slot?

Hi,

I’m building a mobile app (portrait, 1080×1920, stretch mode canvas_items / expand) where mini-games are scenes loaded dynamically into a slot. The main layout looks like this:

VBoxContainer
├── Header (Control)  ← fixed height
├── ContentSlot (Control, SIZE_EXPAND_FILL)  ← mini-games load here
└── Footer (Control)  ← fixed height

ContentSlot fills all remaining vertical space, so its height depends entirely on the device screen. At my test resolution (540×960) it’s roughly 500×400 px, but on a real device it will be different every time.

Mini-games are independent scenes instantiated and added to ContentSlot via add_child(). There are two types:

  • Control-based (UI games: quizzes etc.) anchors handle the resize naturally, no problem here

  • Node2D-based (action games) , this is where I’m unsure

For the Node2D mini-games, the issue is both at design time and at runtime.

At design time: when I open a Node2D scene in the Godot editor, I have no reference frame. The editor viewport is arbitrarily large, so I don’t know what space I’m actually designing for. There’s no equivalent to Control anchors for Node2D, a sprite placed at position (200, 150) will just be at (200, 150) regardless of what the actual available area will be at runtime.

At runtime: when the Node2D scene is added as a child of ContentSlot, it renders starting from ContentSlot’s canvas position. The Node2D has no built-in way to know the bounds of its parent Control, and nothing automatically constrains or adapts its content to fit.

For Control-based mini-games the answer is obvious, anchors do all the work and the scene adapts naturally. But I genuinely don’t know what the idiomatic Godot approach is for Node2D content in this situation.

Is this a case where you just accept that Node2D games need a different authoring strategy? Do you typically wrap them in something? Or do you design Node2D games differently from the ground up to be resolution-agnostic?

Any insight appreciated !

Generally speaking, anything built with Node2D is “floating” and you control what the player sees of the scene with Camera2D. Camera2D has some built-in functionality to manage this. If a Node2D’s position is screen-relevant then you’d program the Camera2D to follow the target or move to it, etc. If the aspect ratio changes, that would just change the view of the world around the target.

Note that until a Camera2D is added to the scene, the game just shows the content of the viewport you see in editor.

Also because Camera2D is a Node2D itself, you can use it as a parent for other node’s positions, or a RemoteTransform to control other Node2D positions across the scene tree heirarchy, or make it a child of something else, etc.

Thanks for the explanation! That makes sense for games where the camera follows a player through a world, aspect ratio changes just reveal more of the surroundings, which is fine.

The tricky part in my case is that these are self-contained microgames (think WarioWare-style), where the entire playfield needs to be visible at once. There’s no “world” to explore, the whole game fits in the slot. So if a target is placed at (300, 200), I need that position to mean something relative to the available space, not just be a fixed canvas coordinate that may end up off-screen or in the wrong corner depending on the device.

That’s why the Camera2D-follow approach doesn’t quite apply here, there’s nothing to follow, and I can’t let the aspect ratio just crop the sides. The whole thing has to fit.

I feel there is probably a way to finagle the Camera2D, like making the entire minigame a child of the Camera2D so everything just moves around within the space of the camera, then have the stretch settings to put the camera at a spot, or use a script to set it to a position based on something a Control provides.

Or consider SubViewport and SubViewportContainer, which are essentially render targets that output as nodes.

You could render the game scene into a type of Container and give it a fixed aspect ratio like 4:3, then just let the outside stretch around it. Note that this system has some implications on input handling, and seem like overkill (it shouldnt be expensive tho) but it would let you manipulate the view in different ways than building around Camera2D.

Thanks! The SubViewport route seems like the cleanest fit for what I need. The “make the game a child of Camera2D” idea is interesting but I’m not sure it solves the core issue, since I still wouldn’t have a defined boundary to design within.

Good point about input handling implications with SubViewport though, that’s something I’ll need to look into before committing to that approach.