Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for responsive font sizes with relative length units (em, %, vw, vim, vmax, ...) #9746

Open
ZenithStar opened this issue May 15, 2024 · 4 comments

Comments

@ZenithStar
Copy link

ZenithStar commented May 15, 2024

Describe the project you are working on

UI-heavy Mobile Game

Describe the problem or limitation you are having in your project

One of the basic features of a responsive UI is that the font size rasters dynamically proportional to the viewport size. I've see many people recommend solving this by using scaling, leading to many more users searching for ways to make their scaled fonts appear sharper.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

HTML+CSS solves this by offering several relative unit lengths for the font-size, whereas Godot only supports pixel length.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

I'm not sure what the most minimally intrusive implementation would be, but I see two options.

  • Change the type of any integer font_size field of Theme and any Control Theme Property overrides to be of type string. This string is evaluated by Theme into an integer px length. Control nodes implementing a font_size property will also need to connect to Viewport.size_changed to trigger a reevaluation.

  • Change the type of any integer font_size field of Theme and any Control Theme Property overrides to be of a new FontSize Resource type. This resource holds a string expression and evaluates the expression into an integer px length. The FontSize resource also connects itself to Viewport.size_changed to trigger a reevaluation.

If this enhancement will not be used often, can it be worked around with a few lines of script?

This can be used often. It is used in virtually every modern GUI application, including the one you're reading this message on right now.

Is there a reason why this should be core and not an add-on in the asset library?

This is core. I can conceive of a workaround addon that supports this feature, but it would involve a server that maintains a list of references to every font_size field in the scene tree. There are other workaround addons such as https://github.com/LuisEscorza/GodotLabelFontAutoSizer solving a limited number of use cases (only for Labels and RichTextLabels, and not for any other Control nodes with text fields, like Buttons or TabBar)

@Calinou Calinou changed the title Support for responsive font_size with relative length units - (em % vw vim vmax etc.) Add support for responsive font sizes with relative length units (em, %, vw, vim, vmax, ...) May 15, 2024
@Calinou
Copy link
Member

Calinou commented May 15, 2024

One of the basic features of a responsive UI is that the font size rasters dynamically proportional to the viewport size. I've see many people recommend solving this by using scaling, leading to many more users searching for ways to make their scaled fonts appear sharper.

Godot already offers a built-in solution for this that doesn't involve scaling Control nodes: the canvas_items stretch mode. See Multiple resolutions in the documentation 🙂

This suffices for the vast majority of games, which work exactly the same way. If you look at most how modern AAA games scale their UI according to resolution, it's how they do it.

There are other workaround addons such as LuisEscorza/GodotLabelFontAutoSizer solving a limited number of use cases (only for Labels and RichTextLabels, and not for any other Control nodes with text fields, like Buttons or TabBar)

This is an entirely different problem which is being tracked in a separate proposal: #7750

@ZenithStar
Copy link
Author

If you look at most how modern AAA games scale their UI according to resolution, it's how they do it.

Most AAA titles offer support for only a very small number of resolutions and aspect ratios, which works, but isn't necessarily ideal. Most of them are designed primarily with console and controller in mind. Most PC-focused games will not scale the UI by default, but instead offer a slider bar in the options menu for the player to adjust the scaling. Some games that do this off the top of my head are Path of Exile, Terraria, and Age of Empires II:DE.

Mobile apps typically do not have this luxury, as they cater to a less-tech-savvy audience, while simultaneously needing to deal with more extreme scaling requirements (e.g. iPhone 15 Pro is 393x852 while iPad Pro 12.9" is 1024x1366). This is especially true for an app that supports auto-rotating between portrait and landscape layouts. Godot advertises its ability to create responsive UIs, but is missing certain features like this one that I would consider core to a responsive toolkit.

@Calinou
Copy link
Member

Calinou commented May 15, 2024

Most AAA titles offer support for only a very small number of resolutions and aspect ratios, which works, but isn't necessarily ideal.

You'd be surprised how many of them scale their UI just fine if you run them in a window and resize their window 🙂

Not all games allow resizing their window, but if you force it with third-party tools, it often works just fine in my experience. Aspect ratio support is a different thing, but it's already handled by anchors in Godot (plus the AspectRatioContainer node).

Most PC-focused games will not scale the UI by default, but instead offer a slider bar in the options menu for the player to adjust the scaling.

You can do that while using the canvas_items stretch mode using a stretch scale value different than 1.0.

Also, if the games you mentioned didn't scale the UI by default, then you'd end up with a tiny UI by default whenever the game is running on a 4K display. I haven't seen that on any game released in the last 5 years. Even old games end up getting patched to scale their UI according to the resolution.

Please test the Multiple Resolutions and Aspect Ratios demo; it covers stuff like that.

Mobile apps typically do not have this luxury, as they cater to a less-tech-savvy audience, while simultaneously needing to deal with more extreme scaling requirements (e.g. iPhone 15 Pro is 393x852 while iPad Pro 12.9" is 1024x1366). This is especially true for an app that supports auto-rotating between portrait and landscape layouts. Godot advertises its ability to create responsive UIs, but is missing certain features like this one that I would consider core to a responsive toolkit.

Mobile UIs (and non-game applications in general) are an entirely different landscape from games. They typically don't rely on automatic scaling based on viewport resolution and use the OS-provided scale factor instead.

It's already possible to script a breakpoint system like you would create breakpoints with media queries in CSS, or rely on FlowContainer for responsive grid layouts.

@ZenithStar
Copy link
Author

I'm well aware of the various solutions involving scaling, but it's ultimately a hack that leads to either artifacting and/or unnecessary overdrawing. Arguably, the most complicated function in this pipeline is the rasterization function, which is fully implemented for any pixel font_size value, but the upstream from that function is underutilizing its potential by only passing static font sizes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants