How do I implement borders for my game?

Godot Version

v4.7.2.stable.official [ed1daf0bf]

Question

My game is in a 4:3 aspect ratio, which in fullscreen mode looks hideous on ultra-wide screens where like half of that space is taken up by black void. So I decided to implement borders by shoving the game into its own viewport and putting a texture around it. However, I have run into 2 problems.

  1. My player character is on a separate layer since the game’s main mechanic is being able to break out of the game window, and if I put the stage into its own viewport, the player can’t interact with it anymore
  2. Same thing with the camera: since it’s on a separate layer, it doesn’t follow the game viewport.

So what can I do about it? I’ve been considering forgoing the viewport entirely and just blocking the non-stage parts with textures, but then I don’t know how to set it up that the player wouldn’t be able to leave the game “window” unless they’re in glitch mode and how to make the camera stop scrolling at the ends of the stage correctly (since the actual stage would probably extend way past the visible limits).

also I kinda want a “fit” and “pixel perfect” modes for my fullscreen views but that’ll be later, for now I just want to setup this whole thing so it’s working properly

Post the scene structure because it’s not clear. The player or camera being in different layers shouldn’t be an issue if they are all part of the same viewport.

If they are not part of the same viewport then you’ll probably need to have multiple viewports, one per different layer.

You can make them share the same physics space by pointing World2D.space of each Viewport.world_2d to the same one.

They’re not in the same viewport, or at least they weren’t originally before I decided to transfer the player between the GameViewport and the PlayerCanvas every time they used the glitch ability, but that kinda messed up their position a lot and while I have figured out how to get the player’s position relative to the root viewport while they’re in the “game” viewport, I haven’t figured out how to do it the other way round.

Also since I’m planning to store secret rooms as part of the same tilemap, just shoved somewhere out of bounds, wouldn’t setting the same physics space mess up player’s interaction with the world every time they basically enter the same world but from a new position?

A collision shape set to the players layer as a child of the texture reacts or camera would do the trick.

I tried doing that and it throws an error saying “Cannot assign a new value to a read-only property.”

But how do I synchronize their position if the player jumps between different “game” viewports? Does this mean I would need several collision shapes for however many viewports there might be?

Sorry, you are right. Looks like that property is read-only. Then just try using the same World2D in the viewports.

That results in a copy of the game world where borders would be and also in this

I assume he’s not actually standing in that wall since he’s programmed to explode when inside walls, he’s probably standing on the ground but because the World2Ds are misaligned, it looks kinda wacky. No idea why the background and ladders are glitching out tho.

Okay so, for completion’s sake, here’s what worked for me:

Stage viewport to global area:

var screen_pos = get_global_transform_with_canvas().origin
reparent(GameWindow.player_canvas)
global_position = screen_pos

Global area to stage viewport:

var diff = ingame_cam.get_global_transform_with_canvas().origin - global_position
reparent(GameWindow.game_vp)
global_position = ingame_cam.position - diff