godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.07k stars 69 forks source link

Expose scene_tree's _update_font_oversampling() to the scripting API #3325

Closed HeartoLazor closed 2 years ago

HeartoLazor commented 2 years ago

Describe the project you are working on

A pixel perfect game with Corgis. This game uses CJK characters with font oversampling for clarity.

Describe the problem or limitation you are having in your project

I required a pixel perfect solution for my game, where I can only scale the game in perfect multiples of the base size (1x,2x,3x,4x, etc) and celeste style HD font rendering (font oversampling). Reading the documentation, there is a recommendation for the integer resolution handler plugin:

Godot currently doesn't have a way to enforce integer scaling when using the 2d or viewport stretch mode, which means pixel art may look bad if the final window size is not a multiple of the base window size. To fix this, use an add-on such as the Integer Resolution Handler.

That plugin replicates the godot internal scaling found in gdscript scene_tree with the exception of the "_update_font_oversampling" line because the method isn't available in GDScript. This plugin uses "STRETCH_MODE_DISABLED" + "STRETCH_ASPECT_IGNORE" flags scaling the base resolution in floored screen values (1x,2x,3x, etc). Because of this engine limitation, that plugin misses the font oversampling support, only available for "STRETCH_MODE_2D" using an internal scaling formula not compatible with all custom implementations.

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

A way to set the font oversampling value in STRETCH_MODE_DISABLED, as this mode objective is custom scaling implementations.

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

With this proposal the user can call in gdscript: get_tree().update_font_oversampling(scale_value) Where scale_value is the scale of the base resolution for full font oversampling support in any stretch mode or any custom scaling implementation. The implementation is available in this PR: https://github.com/godotengine/godot/pull/52881

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

This can be worked around in a hacky way in the current godot 3.3.3.stable, here is the example using the Yukitty's integer resolution handler plugin code as reference:

if(SceneTree.STRETCH_MODE_2D): #This hack can't be implemented in another mode
    get_tree().set_screen_stretch(SceneTree.STRETCH_MODE_2D, SceneTree.STRETCH_ASPECT_KEEP, video_mode / scale, 1.0) #Hack for missing update_font_oversampling, reverse enginered the original oversampling formula resulting in semi perfect rounded values (2.0014 for example instead of 2.0) in the internal _update_font_oversampling call from scene_tree
    #Apply custom scaling values
    _root.set_size((viewport_size / stretch_shrink).floor())
    _root.set_attach_to_screen_rect(Rect2(margin, viewport_size))
    _root.set_size_override_stretch(true)
    _root.set_size_override(true, (screen_size / stretch_shrink).floor())

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

Because this is the missing piece for pixel perfect custom scaling support using font oversampling. I think is a bad practice to limit the font oversampling to "STRETCH_MODE_2D" too, as the aim for "STRETCH_MODE_DISABLED" is to have a custom resolution implementation. This helps to fix missing features for addons like integer resolution handler plugin or overscan custom implementations, as in our project.

akien-mga commented 2 years ago

Fixed by https://github.com/godotengine/godot/pull/55718 (implementing a different API but that enables the same use case).