Stop the game rescaling when the window is resized #34

Closed
opened 2026-08-23 16:05:23 +01:00 by liamjd · 2 comments
Owner

There should be a minium resolution and hence minimum window size.
When the window is enlarged, simply show more of the game world. Don't rescale the entire UI and terrain drawing.

There should be a minium resolution and hence minimum window size. When the window is enlarged, simply show more of the game world. Don't rescale the entire UI and terrain drawing.
Author
Owner

Not a bug: the symptom was the editor's embedded Game view

Closing this. The rescaling and the blank space around the game were an artifact
of how the game was being launched, not of the game itself.

The editor's Game view had defaulted to a fixed 1920x1080 embed, so on a
3440x1440 ultrawide the game was drawn at a fixed size inside a much larger
panel, leaving blank space around it. Switching that setting to Stretch to Fit
fills the window as expected.

Two independent confirmations that the game itself is fine:

  • Every screenshot in the investigation below was taken from a standalone
    -s run, and none of them ever reproduced the symptom - which in
    hindsight was the tell that we were looking at different things.
  • Launching from JetBrains Rider (which runs the game standalone rather
    than embedded) gives the same correct behaviour as the -s runs.

What was measured on the way

A throwaway harness loaded the real game.tscn, resized the window at runtime
and shot each size, printing the camera and viewport state. Standalone, no editor:

label window cam.size aspect world visible
A 1280x720 60.00 1.778 106.7 x 60.0 m
B 960x540 60.00 1.778 106.7 x 60.0 m
C 1280x400 60.00 3.200 192.0 x 60.0 m
D 640x720 60.00 0.889 53.3 x 60.0 m
E 2560x1080 60.00 2.370 142.2 x 60.0 m
F 3440x1440 (fullscreen) 60.00 2.389 143.3 x 60.0 m

Camera3D is KEEP_HEIGHT and CameraRig._apply_zoom() sets size = zoom, so
the vertical world span is pinned at 60 m regardless of window size, and the
horizontal span is 60 * aspect. That means viewport height determines scale
and viewport width determines coverage.

That behaviour is a design choice rather than a defect, and it is being left as
is. "Enlarging the window shows more world" would require size to scale with
viewport pixel height - worth revisiting only if the fixed-world-span behaviour
actually becomes annoying in play.

Loose ends found while investigating

These are unrelated to this ticket and are not fixed by closing it:

  1. MainMenu anchors collapse in game.tscn. The instance overrides the
    scene's anchors_preset = 15 with = 8 and supplies no offsets, so every
    full-rect Control inside it resolves to zero size. Measured at 1920x1080:

    MainMenu                          size=(0, 0)
    MainMenu/Background               size=(0, 0)     <- backdrop draws nothing
      .../PanelContainer              size=(196, 234) <- the only real one
    MainMenu/.../ModalLayer           size=(0, 0)
    MainMenu/.../ModalLayer/Scrim     size=(0, 0)     <- blocks no mouse input
    

    The menu only looks right because a zero-size Control at screen centre puts
    a +/-90-offset child where a full-rect parent would. main_menu.gd:39 asserts
    "The scrim blocks the mouse but not Tab", which the geometry says is not true
    today - needs a manual click-through test to confirm. Fix is deleting the
    override.

  2. CameraRig.max_zoom has a stale comment. It justifies 120 as "far enough
    out to frame the whole map", derived at 16:9. At 2.389 aspect it yields
    287 m of visible width against a 128 m map. The value is fine; the reasoning
    in the comment is not.

  3. View extends past the map edge above ~2.13:1 aspect. visible width = zoom * aspect > 128 m when aspect > 2.133, so 21:9 and wider see sky and
    the map's cut face at the edges. _clamp_to_map() bounds the focus point via
    edge_margin, a world-space constant that knows nothing about aspect. Judged
    cosmetic and acceptable for now.

  4. min_size does not apply on the main menu. get_window().min_size is set
    in game.gd._ready(), but run/main_scene is main_menu.tscn and
    game.tscn only loads on New Game (main_menu.gd:115), so the window is
    unconstrained until a game starts. GameState would apply it from launch.

  5. window/stretch/mode is currently unset (disabled) in the working tree,
    changed during this investigation. Its effect was never measured against the
    previous canvas_items value. At 3440x1440 disabled leaves the building
    panel at ~330 px, about 9% of screen width; canvas_items would have scaled
    it up. Whether that change is an improvement is undecided, and a
    player-facing UI scale (Window.content_scale_factor) is probably the real
    answer - see #21.

## Not a bug: the symptom was the editor's embedded Game view Closing this. The rescaling and the blank space around the game were an artifact of how the game was being launched, not of the game itself. The editor's Game view had defaulted to a **fixed 1920x1080 embed**, so on a 3440x1440 ultrawide the game was drawn at a fixed size inside a much larger panel, leaving blank space around it. Switching that setting to **Stretch to Fit** fills the window as expected. Two independent confirmations that the game itself is fine: - Every screenshot in the investigation below was taken from a standalone `-s` run, and **none of them ever reproduced the symptom** - which in hindsight was the tell that we were looking at different things. - Launching from **JetBrains Rider** (which runs the game standalone rather than embedded) gives the same correct behaviour as the `-s` runs. ## What was measured on the way A throwaway harness loaded the real `game.tscn`, resized the window at runtime and shot each size, printing the camera and viewport state. Standalone, no editor: | label | window | `cam.size` | aspect | world visible | | --- | --- | --- | --- | --- | | A | 1280x720 | 60.00 | 1.778 | 106.7 x 60.0 m | | B | 960x540 | 60.00 | 1.778 | 106.7 x 60.0 m | | C | 1280x400 | 60.00 | 3.200 | 192.0 x 60.0 m | | D | 640x720 | 60.00 | 0.889 | 53.3 x 60.0 m | | E | 2560x1080 | 60.00 | 2.370 | 142.2 x 60.0 m | | F | 3440x1440 (fullscreen) | 60.00 | 2.389 | 143.3 x 60.0 m | `Camera3D` is `KEEP_HEIGHT` and `CameraRig._apply_zoom()` sets `size = zoom`, so the vertical world span is pinned at 60 m regardless of window size, and the horizontal span is `60 * aspect`. That means **viewport height determines scale and viewport width determines coverage.** That behaviour is a design choice rather than a defect, and it is being left as is. "Enlarging the window shows more world" would require `size` to scale with viewport pixel height - worth revisiting only if the fixed-world-span behaviour actually becomes annoying in play. ## Loose ends found while investigating These are unrelated to this ticket and are not fixed by closing it: 1. **`MainMenu` anchors collapse in `game.tscn`.** The instance overrides the scene's `anchors_preset = 15` with `= 8` and supplies no offsets, so every full-rect Control inside it resolves to zero size. Measured at 1920x1080: ``` MainMenu size=(0, 0) MainMenu/Background size=(0, 0) <- backdrop draws nothing .../PanelContainer size=(196, 234) <- the only real one MainMenu/.../ModalLayer size=(0, 0) MainMenu/.../ModalLayer/Scrim size=(0, 0) <- blocks no mouse input ``` The menu only *looks* right because a zero-size Control at screen centre puts a +/-90-offset child where a full-rect parent would. `main_menu.gd:39` asserts "The scrim blocks the mouse but not Tab", which the geometry says is not true today - needs a manual click-through test to confirm. Fix is deleting the override. 2. **`CameraRig.max_zoom` has a stale comment.** It justifies 120 as "far enough out to frame the whole map", derived at 16:9. At 2.389 aspect it yields 287 m of visible width against a 128 m map. The value is fine; the reasoning in the comment is not. 3. **View extends past the map edge above ~2.13:1 aspect.** `visible width = zoom * aspect > 128 m` when `aspect > 2.133`, so 21:9 and wider see sky and the map's cut face at the edges. `_clamp_to_map()` bounds the focus point via `edge_margin`, a world-space constant that knows nothing about aspect. Judged cosmetic and acceptable for now. 4. **`min_size` does not apply on the main menu.** `get_window().min_size` is set in `game.gd._ready()`, but `run/main_scene` is `main_menu.tscn` and `game.tscn` only loads on New Game (`main_menu.gd:115`), so the window is unconstrained until a game starts. `GameState` would apply it from launch. 5. **`window/stretch/mode` is currently unset (`disabled`) in the working tree**, changed during this investigation. Its effect was never measured against the previous `canvas_items` value. At 3440x1440 `disabled` leaves the building panel at ~330 px, about 9% of screen width; `canvas_items` would have scaled it up. Whether that change is an improvement is undecided, and a player-facing UI scale (`Window.content_scale_factor`) is probably the real answer - see #21.
Author
Owner

Not a bug - editor Game view was set to a fixed 1920x1080 embed. Standalone runs (-s harness, and launching from Rider) behave correctly. See the comment above for measurements and the unrelated loose ends found on the way.

Not a bug - editor Game view was set to a fixed 1920x1080 embed. Standalone runs (-s harness, and launching from Rider) behave correctly. See the comment above for measurements and the unrelated loose ends found on the way.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
liamjd/UntitledColonyBuilder#34
No description provided.