GML Advanced resolution manager (very mobile friendly)

gkri

Member
I wrote this (hopefully) handy script and I would love to share it with this wonderful community.

The scripts has two primary uses:
  • To help developers handling multi-resolution easier.
  • To offer to mobile developers a couple of quality of life features.
This script is heavily based on the Resolution and Aspect Ratio Management for Game Maker tutorial series by @Pixelated_Pope. Thank you @Pixelated_Pope! And no need to mention that It is absolutely free (MIT License)!


What the script does and how to use it

The script accepts 4 mandatory and 2 optional arguments (total of 6):

Code:
set_resolution (design_value, is_design_vertical, is_orientation_vertical, resize_all_rooms, scale (optional), overide_other_value (optional))
  • @arg design_value (real) One of the most important decisions must be taken, is the ideal resolution of the game. The first argument is very flexible; you can pass either the width or the height of your ideal resolution the remaining one will be calculated by the script.
  • @arg is_design_value_vertical (boolean) Here you specify if the first argument is referring to width (false) or height (true) of your ideal resolution.
  • @arg is_orientation_vertical (boolean) Here you specify if the orientation of the game is landscape (false) or portrait (true). The most obvious reason to set it as true, is for mobile games but I suppose it could be useful to html5 games with unique design or ported from mobile platforms.
  • @resize_all_rooms (boolean) It will resize all rooms except the 0 indexed one, to the resulted resolution from the previous arguments, if true. Some games have fixed room dimensions (eg break out clones, card games) while others not (rpgs, platformers); pass true or false accordingly.
  • @arg scale (real) Optional argument. Nowadays most mobile devices have bigger screen resolution than a desktop or laptop screen. This may be inconvenient, especially if the mobile game that is being developed has portrait orientation. You can pass a custom scale to fit the game window within your monitor. The scale only effects builds on os_windows and os_macosx (usually you build Test->VM on them) and is ignored on device or emulator builds.
  • @arg overide_other_value (real) Optional argument. You can pass the other ideal dimension than the one you passed on first argument to make a customized screen ratio for a quick sneak peek without using real device or emulator. If you passed the ideal width on first argument, you can pass a height value here and vice versa. Like scale argument, it will ignored on device or emulator builds.

The most common place to call the script, should be inside your init room, which should be on top of the room list. Unless you want to change the resolution again inside the game, you will not need to call this script again. When the script is executed, it will store its results to the global variables:
Code:
global.ideal_width
global.ideal_height

Here is a quick example of how to use those values:

Code:
//Room Start Event

view_enabled = true;
view_visible[0] = true;
view_wport[0] = global.ideal_width;
view_hport[0] = global.ideal_height;
camera_set_view_size(view_camera[0], view_wport[0], view_hport[0]);


(I might upload a demo project If I see some demand)
Edit: Now you can download three example projects and find a more detailed tutorial of how to use the Advanced Resolution Manager on itch.io



The source code of the script (GMS2.2)

GML:
///@func set_resolution(design_value, is_design_vertical, is_orientation_vertical, resize_all_rooms, scale (optional), overide_other_value (optional))
///@arg design_value - real - Width or height of ideal resolution
///@arg is_design_value_vertical  - boolean -  When true, the design_value is condidered as height; when false, as width
///@arg is_orientation_vertical - boolean -  When true, the screen orientation is considered as portrait; when false, as landscape
///@arg resize_all_rooms - boolean - When true: Rooms (except room index 0), will be resized to resulting value
///@arg scale(optional) - real - (Optional) Scale the game window to better fit the monitor. Will ommited on any non windows and non macos builds
///@arg overide_other_value(optional) - real - (Optional) Overides the value other than the design_value arg for a custom aspect ratio. Will ommited like scale arg

///Written by George Kritikos (Harpwood studio) - Based on code written by Pixelated_Pope
///@License MIT License https://opensource.org/licenses/MIT


// arguments evaluation
if argument_count < 4 or argument_count > 6 then show_error("Error set_resolution script: Incorect number of arguments. Expected number of arguments are minimum of 4 to maximum of 6.", true);

var _arg = [];

for (var i = 0; i < 6; i++;)
{
    if argument_count > i then _arg[i] = argument[i] else _arg[i] = undefined;
}


// assigning _arg[] values for readability
var _design_value = _arg[0];
var _is_design_value_vertical = _arg[1];
var _is_orientation_vertical = _arg[2];
var _resize_all_rooms = _arg[3];
var _scale = _arg[4] == undefined ? 1 : _arg[4]; // default scale = 1
var _overide_other_value  = _arg[5];

//detect os_type only if is GMS2 IDE approprate
_os_type = os_type == os_windows ? os_windows : os_macosx;

// The design value is either the design width or height. Every calculation in build with Test -> VM get a temporary scaling
var _desing_width = os_type == _os_type ? _design_value * _scale : _design_value;
var _desing_height = os_type == _os_type ? _design_value * _scale : _design_value;

var _real_width, _real_height, _aspect_ratio, _ideal_width, _ideal_height;

if _is_orientation_vertical
{
    //dirty way to get portait orientation for os_windows/os_macosx
    _real_width = os_type == _os_type ? display_get_height()  * _scale : display_get_width();
    _real_height = os_type == _os_type ? display_get_width()    * _scale : display_get_height();
    _aspect_ratio  = _real_width >= _real_height ? _real_height / _real_width : _real_width / _real_height;

    if _is_design_value_vertical    //The design value is reffering to vertical so we calculate the horizontal
    {
        _ideal_height = _desing_height;
        if os_type == _os_type then _ideal_width = _overide_other_value == undefined ? round(_ideal_height * _aspect_ratio) : _overide_other_value * _scale;
        else _ideal_width = round(_ideal_height * _aspect_ratio);
    }
    else                            //and vice versa
    {
        _ideal_width = _desing_width;
        if os_type == _os_type then _ideal_height = _overide_other_value == undefined ? round(_ideal_width / _aspect_ratio) : _overide_other_value * _scale;
        else _ideal_height = round(_ideal_width / _aspect_ratio);
    }

}
else
{
    _real_width = os_type == _os_type ? display_get_width()  * _scale : display_get_width();
    _real_height = os_type == _os_type ? display_get_height() * _scale : display_get_height();
    _aspect_ratio = _real_width >= _real_height ? _real_height / _real_width : _real_width / _real_height;


    if _is_design_value_vertical    //The design value is reffering to vertical so we calculate the horizontal
    {
        _ideal_height = _desing_height;
        if os_type == _os_type then _ideal_width = _overide_other_value == undefined ?  round(_ideal_height / _aspect_ratio) : _overide_other_value * _scale;
        else _ideal_width =  round(_ideal_height / _aspect_ratio);
    }
    else                            //and vice versa
    {
        _ideal_width = _desing_width;
        if os_type == _os_type then _ideal_height = _overide_other_value == undefined ? round(_ideal_width * _aspect_ratio) : _overide_other_value * _scale;
        else _ideal_height = round(_ideal_width * _aspect_ratio);
    }
}

//make the results more pixel perfect friendly
if _ideal_width & 1 then _ideal_width++;
if _ideal_height & 1 then _ideal_height++;

if _resize_all_rooms //apply resolution results to all rooms?
{
    for (var i = 1; i < room_last; i++) //all rooms except room with index 0, which usually is the init room
    {
        if room_exists(i)
        {
            room_set_width(i, _ideal_width);
            room_set_height(i, _ideal_height);
        }
    }
}

application_surface_enable(false);  // false as default behaviour
window_set_size(_ideal_width, _ideal_height);
surface_resize(application_surface, _real_width, _real_height);

//remove the temporary scaling if building with Test -> VM and apply results in global vars for further use
global.ideal_width = os_type == _os_type ? _ideal_width / _scale : _ideal_width;
global.ideal_height = os_type == _os_type ? _ideal_height / _scale : _ideal_height;



To make the script compatible with GMS2.3:

Code:
function set_resolution()
{

    [PASTE THE GMS2.2 SOURCE CODE HERE]

}

EDIT : Added GMS2.3 version of the script

GML:
function set_resolution(_design_value, _is_design_value_vertical, _is_orientation_vertical, _resize_all_rooms, _scale, _overide_other_value) {
///@func set_resolution(design_value, is_design_vertical, is_orientation_vertical, resize_all_rooms, [scale], overide_other_value [optional])
///@arg _design_value                  real        width or height of ideal resolution
///@arg _is_design_value_vertical      boolean    When true, the design_value is condidered as height; when false, as width
///@arg _is_orientation_vertical      boolean    When true, the screen orientation is considered as portrait; when false, as landscape
///@arg _resize_all_rooms              boolean    When true: Rooms (except room index 0), will be resized to resulting value
///@arg _scale(optional)              real        (Optional) Scale the game window to better fit the monitor. Will ommited on any non windows and non macos builds
///@arg _overide_other_value(optional) real        (Optional) Overides the value other than the design_value arg for a custom aspect ratio. Will ommited like scale arg

    ///Written by George Kritikos (Harpwood studio) - Based on code written by Pixelated_Pope
    ///@License MIT License https://opensource.org/licenses/MIT

    //arguments evaluation
    if _design_value == undefined or _is_design_value_vertical == undefined or _is_orientation_vertical == undefined or _resize_all_rooms == undefined
    then show_error("Error set_resolution script: Incorect number of arguments. Expected number of arguments are minimum of 4 to maximum of 6.", true);

    if 0 then return argument[0]; //A workaround to avoid warnings if you do not pass the optional arguments

    if _scale == undefined then _scale = 1;

    //detect os_type only if is GMS2 IDE approprate
    _os_type = os_type == os_windows ? os_windows : os_macosx;

    // The design value is either the design width or height. Every calculation in build with Test -> VM get a temporary scaling
    var _desing_width    = os_type == _os_type ? _design_value * _scale : _design_value;
    var _desing_height    = os_type == _os_type ? _design_value * _scale : _design_value;

    var _real_width, _real_height, _aspect_ratio, _ideal_width, _ideal_height;

    if _is_orientation_vertical
    {
        //dirty way to get portait orientation for os_windows/os_macosx
        _real_width        = os_type == _os_type ? display_get_height()  * _scale : display_get_width();
        _real_height    = os_type == _os_type ? display_get_width()    * _scale : display_get_height();
        _aspect_ratio    = _real_width >= _real_height ? _real_height / _real_width : _real_width / _real_height;

        if _is_design_value_vertical    //The design value is reffering to vertical so we calculate the horizontal
        {
            _ideal_height = _desing_height;
            if os_type == _os_type then _ideal_width = _overide_other_value == undefined ? round(_ideal_height * _aspect_ratio) : _overide_other_value * _scale;
            else _ideal_width = round(_ideal_height * _aspect_ratio);
        }
        else                            //and vice versa
        {
            _ideal_width = _desing_width;
            if os_type == _os_type then _ideal_height = _overide_other_value == undefined ? round(_ideal_width / _aspect_ratio) : _overide_other_value * _scale;
            else _ideal_height = round(_ideal_width / _aspect_ratio);
        }

    }
    else
    {
        _real_width        = os_type == _os_type ? display_get_width()  * _scale : display_get_width();
        _real_height    = os_type == _os_type ? display_get_height() * _scale : display_get_height();
        _aspect_ratio    = _real_width >= _real_height ? _real_height / _real_width : _real_width / _real_height;


        if _is_design_value_vertical    //The design value is reffering to vertical so we calculate the horizontal
        {
            _ideal_height = _desing_height;
            if os_type == _os_type then _ideal_width = _overide_other_value == undefined ?  round(_ideal_height / _aspect_ratio) : _overide_other_value * _scale;
            else _ideal_width =  round(_ideal_height / _aspect_ratio);
        }
        else                            //and vice versa
        {
            _ideal_width = _desing_width;
            if os_type == _os_type then _ideal_height = _overide_other_value == undefined ? round(_ideal_width * _aspect_ratio) : _overide_other_value * _scale;
            else _ideal_height = round(_ideal_width * _aspect_ratio);
        }
    }

    //make the results more pixel perfect friendly
    if _ideal_width & 1 then _ideal_width++;
    if _ideal_height & 1 then _ideal_height++;

    if _resize_all_rooms //apply resolution results to all rooms?
    {
        for (var i = 1; i < room_last; i++) //all rooms except room with index 0, which usually is the init room
        {
            if room_exists(i)
            {
                room_set_width(i, _ideal_width);
                room_set_height(i, _ideal_height);
            }
        }
    }

    application_surface_enable(false);  // false as default behaviour
    window_set_size(_ideal_width, _ideal_height);
    surface_resize(application_surface, _real_width, _real_height);

    //remove the temporary scaling if building with Test -> VM and apply results in global vars for further use
    global.ideal_width = os_type == _os_type ? _ideal_width / _scale : _ideal_width;
    global.ideal_height = os_type == _os_type ? _ideal_height / _scale : _ideal_height;


}


What's the catch?

I have tested the script with any way I could come up with. As long as the values I pass are appropriate for the assets I am using everything looks fine. I have even used an early version of this script in production without any problems. But I am just a culinary chef and I am developing games and animation as a hobbyist. My coding experience is limited to about 2-2 1/2 years. Soooo do not trust my coding skills (I wouldn't trust my coding skills). Maybe my inexperience is tricking me and the script is nothing more than a few worthless lines of code. So I need your help. If you are willing to help me, take the script and test the s**t out of it, even improve it, or adapt it to your needs and if you want post your improved code here and I will credit you. Or help me by giving feedback or reporting bugs. Please help me foolproof it.

Edit: There is no catch! It's free! You can use it in any project commercial or personal! Your only obligation is to read the license (MIT License) before using it. The code code now is proven without any known issues! If you find any bug or you want to suggest an improvement just reply to this thread...

Edit: Compatibility:
  • The script is working 100% as it should on mobile and desktop targets. It has not tested on UWP, HTML5 and any console target. If you own any license from the not tested platforms, if you test it, please let us know if is working correctly!
  • When targeting desktop the parameter _is_orientation_vertical should be false.
  • Mobile quality of life features are intended for mobile projects. If the project is cross platform, you should use those features only when working the mobile aspects of your project. The mobile quality of life features are _is_orientation_vertical as true, and the optional arguments: scale and overide_other_value.

Edit: Known limitations:

1. If the game window is bigger that your monitor screen, GMS will scale it unevenly causing distortion on graphics.​
Affets VM->Test builds with "faking" portrait orientation only. It does not affect landscape aspect ratios and it does not affect any build on actual mobile devices.​
Solution: Use the optional scale argument to scale the window down in order to fit inside your monitor.​
2. When working on VM->Test builds with "faking" portrait orientation, if the application surface is enabled the graphics are heavily distorted.​
Affets VM->Test builds with "faking" portrait orientation only. It does not affect landscape aspect ratios and it does not affect any build on actual mobile devices.​
Solution: Enable and use the application surface, conditional based on os_type, so you can keep enjoying the "faking" portrait orientation on VM->Test builds
3. When working on VM->Test builds with "faking" portrait orientation, if window_set_fullscreen is enabled the graphics are heavily distorted. It does not make sense to use window_set_fullscreen enabled with VM->Test build "faking" portrait orientation, anyway...​
Affets VM->Test builds with "faking" portrait orientation only. It does not affect landscape aspect ratios and it does not affect any build on actual mobile devices. The build on an actual mobile device will be full screen anyway...​
Solution: Unless getting a second monitor and having oriented vertically, there is not any actual solution nor needed one...​

Thank you for you time

George Kritikos
 
Last edited:

gkri

Member
Updated the script to be more pixel perfect friendly.
Added:
GML:
//make the results more pixel perfect friendly
if _ideal_width & 1 then _ideal_width++;
if _ideal_height & 1 then _ideal_height++;
 

gkri

Member
EDIT : Added GMS2.3 version of the script

GML:
function set_resolution(_design_value, _is_design_value_vertical, _is_orientation_vertical, _resize_all_rooms, _scale, _overide_other_value) {
///@func set_resolution(design_value, is_design_vertical, is_orientation_vertical, resize_all_rooms, [scale], overide_other_value [optional])
///@arg _design_value                  real        width or height of ideal resolution
///@arg _is_design_value_vertical      boolean    When true, the design_value is condidered as height; when false, as width
///@arg _is_orientation_vertical      boolean    When true, the screen orientation is considered as portrait; when false, as landscape
///@arg _resize_all_rooms              boolean    When true: Rooms (except room index 0), will be resized to resulting value
///@arg _scale(optional)              real        (Optional) Scale the game window to better fit the monitor. Will ommited on any non windows and non macos builds
///@arg _overide_other_value(optional) real        (Optional) Overides the value other than the design_value arg for a custom aspect ratio. Will ommited like scale arg

    ///Written by George Kritikos (Harpwood studio) - Based on code written by Pixelated_Pope
    ///@License MIT License https://opensource.org/licenses/MIT
   
    //arguments evaluation
    if _design_value == undefined or _is_design_value_vertical == undefined or _is_orientation_vertical == undefined or _resize_all_rooms == undefined
    then show_error("Error set_resolution script: Incorect number of arguments. Expected number of arguments are minimum of 4 to maximum of 6.", true);
   
    if 0 then return argument[0]; //A workaround to avoid warnings if you do not pass the optional arguments
   
    if _scale == undefined then _scale = 1;
   
    //detect os_type only if is GMS2 IDE approprate
    _os_type = os_type == os_windows ? os_windows : os_macosx;

    // The design value is either the design width or height. Every calculation in build with Test -> VM get a temporary scaling
    var _desing_width    = os_type == _os_type ? _design_value * _scale : _design_value;
    var _desing_height    = os_type == _os_type ? _design_value * _scale : _design_value;

    var _real_width, _real_height, _aspect_ratio, _ideal_width, _ideal_height;

    if _is_orientation_vertical
    {
        //dirty way to get portait orientation for os_windows/os_macosx
        _real_width        = os_type == _os_type ? display_get_height()  * _scale : display_get_width();
        _real_height    = os_type == _os_type ? display_get_width()    * _scale : display_get_height();
        _aspect_ratio    = _real_width >= _real_height ? _real_height / _real_width : _real_width / _real_height;
   
        if _is_design_value_vertical    //The design value is reffering to vertical so we calculate the horizontal
        {
            _ideal_height = _desing_height;
            if os_type == _os_type then _ideal_width = _overide_other_value == undefined ? round(_ideal_height * _aspect_ratio) : _overide_other_value * _scale;
            else _ideal_width = round(_ideal_height * _aspect_ratio);
        }
        else                            //and vice versa
        {
            _ideal_width = _desing_width;
            if os_type == _os_type then _ideal_height = _overide_other_value == undefined ? round(_ideal_width / _aspect_ratio) : _overide_other_value * _scale;
            else _ideal_height = round(_ideal_width / _aspect_ratio);
        }
   
    }
    else
    {
        _real_width        = os_type == _os_type ? display_get_width()  * _scale : display_get_width();
        _real_height    = os_type == _os_type ? display_get_height() * _scale : display_get_height();
        _aspect_ratio    = _real_width >= _real_height ? _real_height / _real_width : _real_width / _real_height;
   
   
        if _is_design_value_vertical    //The design value is reffering to vertical so we calculate the horizontal
        {
            _ideal_height = _desing_height;
            if os_type == _os_type then _ideal_width = _overide_other_value == undefined ?  round(_ideal_height / _aspect_ratio) : _overide_other_value * _scale;
            else _ideal_width =  round(_ideal_height / _aspect_ratio);
        }
        else                            //and vice versa
        {
            _ideal_width = _desing_width;
            if os_type == _os_type then _ideal_height = _overide_other_value == undefined ? round(_ideal_width * _aspect_ratio) : _overide_other_value * _scale;
            else _ideal_height = round(_ideal_width * _aspect_ratio);
        }
    }
   
    //make the results more pixel perfect friendly
    if _ideal_width & 1 then _ideal_width++;
    if _ideal_height & 1 then _ideal_height++;

    if _resize_all_rooms //apply resolution results to all rooms?
    {
        for (var i = 1; i < room_last; i++) //all rooms except room with index 0, which usually is the init room
        {
            if room_exists(i)
            {
                room_set_width(i, _ideal_width);
                room_set_height(i, _ideal_height);
            }
        }
    }

    application_surface_enable(false);  // false as default behaviour
    window_set_size(_ideal_width, _ideal_height);
    surface_resize(application_surface, _real_width, _real_height);

    //remove the temporary scaling if building with Test -> VM and apply results in global vars for further use
    global.ideal_width = os_type == _os_type ? _ideal_width / _scale : _ideal_width;
    global.ideal_height = os_type == _os_type ? _ideal_height / _scale : _ideal_height;

   
}
 

gkri

Member
so you implement the script in the room start event?
Here is a script that will handle the resolution for you:

GML:
function set_resolution(_design_value, _is_design_value_vertical, _is_orientation_vertical, _resize_all_rooms, _scale, _overide_other_value) {
///@func set_resolution(design_value, is_design_vertical, is_orientation_vertical, resize_all_rooms, [scale], overide_other_value [optional])
///@arg _design_value                  real        width or height of ideal resolution
///@arg _is_design_value_vertical      boolean    When true, the design_value is condidered as height; when false, as width
///@arg _is_orientation_vertical      boolean    When true, the screen orientation is considered as portrait; when false, as landscape
///@arg _resize_all_rooms              boolean    When true: Rooms (except room index 0), will be resized to resulting value
///@arg _scale(optional)              real        (Optional) Scale the game window to better fit the monitor. Will ommited on any non windows and non macos builds
///@arg _overide_other_value(optional) real        (Optional) Overides the value other than the design_value arg for a custom aspect ratio. Will ommited like scale arg

    ///Written by George Kritikos (Harpwood studio) - Based on code written by Pixelpope
    ///@License MIT License https://opensource.org/licenses/MIT

    if _design_value == undefined or _is_design_value_vertical == undefined or _is_orientation_vertical == undefined or _resize_all_rooms == undefined
    then show_error("Error set_resolution script: Incorect number of arguments. Expected number of arguments are minimum of 4 to maximum of 6.", true);

    if 0 then return argument[0];
    if _scale == undefined then _scale = 1;
    //detect os_type only if is GMS2 IDE approprate
    _os_type = os_type == os_windows ? os_windows : os_macosx;

    // The design value is either the design width or height. Every calculation in build with Test -> VM get a temporary scaling
    var _desing_width    = os_type == _os_type ? _design_value * _scale : _design_value;
    var _desing_height    = os_type == _os_type ? _design_value * _scale : _design_value;

    var _real_width, _real_height, _aspect_ratio, _ideal_width, _ideal_height;

    if _is_orientation_vertical
    {
        //dirty way to get portait orientation for os_windows/os_macosx
        _real_width        = os_type == _os_type ? display_get_height()  * _scale : display_get_width();
        _real_height    = os_type == _os_type ? display_get_width()    * _scale : display_get_height();
        _aspect_ratio    = _real_width >= _real_height ? _real_height / _real_width : _real_width / _real_height;

        if _is_design_value_vertical    //The design value is reffering to vertical so we calculate the horizontal
        {
            _ideal_height = _desing_height;
            if os_type == _os_type then _ideal_width = _overide_other_value == undefined ? round(_ideal_height * _aspect_ratio) : _overide_other_value * _scale;
            else _ideal_width = round(_ideal_height * _aspect_ratio);
        }
        else                            //and vice versa
        {
            _ideal_width = _desing_width;
            if os_type == _os_type then _ideal_height = _overide_other_value == undefined ? round(_ideal_width / _aspect_ratio) : _overide_other_value * _scale;
            else _ideal_height = round(_ideal_width / _aspect_ratio);
        }

    }
    else
    {
        _real_width        = os_type == _os_type ? display_get_width()  * _scale : display_get_width();
        _real_height    = os_type == _os_type ? display_get_height() * _scale : display_get_height();
        _aspect_ratio    = _real_width >= _real_height ? _real_height / _real_width : _real_width / _real_height;


        if _is_design_value_vertical    //The design value is reffering to vertical so we calculate the horizontal
        {
            _ideal_height = _desing_height;
            if os_type == _os_type then _ideal_width = _overide_other_value == undefined ?  round(_ideal_height / _aspect_ratio) : _overide_other_value * _scale;
            else _ideal_width =  round(_ideal_height / _aspect_ratio);
        }
        else                            //and vice versa
        {
            _ideal_width = _desing_width;
            if os_type == _os_type then _ideal_height = _overide_other_value == undefined ? round(_ideal_width * _aspect_ratio) : _overide_other_value * _scale;
            else _ideal_height = round(_ideal_width * _aspect_ratio);
        }
    }

    //make the results more pixel perfect friendly
    if _ideal_width & 1 then _ideal_width++;
    if _ideal_height & 1 then _ideal_height++;

    if _resize_all_rooms //apply resolution results to all rooms?
    {
        for (var i = 1; i < room_last; i++) //all rooms except room with index 0, which usually is the init room
        {
            if room_exists(i)
            {
                room_set_width(i, _ideal_width);
                room_set_height(i, _ideal_height);
            }
        }
    }

    application_surface_enable(false);  // false as default behaviour
    window_set_size(_ideal_width, _ideal_height);
    surface_resize(application_surface, _real_width, _real_height);

    //remove the temporary scaling if building with Test -> VM and apply results in global vars for further use
    global.ideal_width = os_type == _os_type ? _ideal_width / _scale : _ideal_width;
    global.ideal_height = os_type == _os_type ? _ideal_height / _scale : _ideal_height;


}

Simply call the advanced resolution manager once on your very first (init) room and it will handle all the rooms of your game except the very first (init room).

Then at EVERY room call the next script (start event), passing x1 =0, y1 = 0 and the x2 = global.ideal_width and y2 = global.ideal_height values from previous script :

GML:
function set_camera(x1, y1, x2, y2) {
///@func set_camera
///@arg x1
///@arg y1
///@arg x2
///@arg y2

        view_enabled = true;
        view_visible[0] = true;
        view_wport[0] = x2;
        view_hport[0] = y2;

        view_camera[0] = camera_create_view(x1, y1, view_wport[0], view_hport[0], 0, -1, -1, -1, 0, 0);
}


Then for a smooth GUI developing experience, you can use this script ONCE at the very next room (after init room). It should be in effect for the rest of the game, unless you change the GUI size yourself.

GML:
function set_gui_size(_width, _height) {

    if 0 then return argument[0];

    if _height == undefined then _height = HEIGHT * _width / WIDTH;
    display_set_gui_size(_width, _height);

    global.width_gui = _width;
    global.height_gui = _height;
}

The 2nd argument is optional, so pass as width your ideal width, the script will figure out the ideal height...

If you need more help let me know!
 
Thank you very much, I will try my best to implement this in my game, because I 'm new in GMS2 and I 'm trying to create a game in portrait mode but making the game to adjust to every (or atleast the majority) mobile devie is driving me crazy.

some questions:

when you say: Then at EVERY room call the next script (start event) , you refer to create an object and then in the start event call that script?
and for the last script where should I call it? in a new object to?

(sorry for this newbie questions)
 
Last edited:

gkri

Member
Thank you very much, I will try my best to implement this in my game, because I 'm new in GMS2 and I 'm trying to create a game in portrait mode but making the game to adjust to every (or atleast the majority) mobile devie is driving me crazy.

some questions:

when you say: Then at EVERY room call the next script (start event) , you refer to create an object and then in the start event call that script?
and for the last script where should I call it? in a new object to?

(sorry for this newbie questions)
The second script is for setting the camera. You can call it once, using the start event. For more help about events see here (What you need is "Other -> Room Start").
In which object should you apply that event? Well, that depends of your project structure. If you are using a persistent object through all your game you could put this event on this object. Additionally at every room you usually have a "game manager object", you can put this event (or the script in create event) on this object instead. Or maybe you can have a dedicated object for camera in every rom, which in this case you is very good candidate for calling this script once per room start.

If you need more help tell me!
 

gkri

Member
-------------------------------------------------
I see there is some interest about this script,
so after finishing my WIP project (should take
about 10 days to finish) I will try to create an
example project.
--------------------------------------------------

What's the catch?

I have tested the script with any way I could come up with. As long as the values I pass are appropriate for the assets I am using everything looks fine. I have even used an early version of this script in production without any problems. But I am just a culinary chef and I am developing games and animation as a hobbyist. My coding experience is limited to about 2-2 1/2 years. Soooo do not trust my coding skills (I wouldn't trust my coding skills). Maybe my inexperience is tricking me and the script is nothing more than a few worthless lines of code. So I need your help. If you are willing to help me, take the script and test the s**t out of it, even improve it, or adapt it to your needs and if you want post your improved code here and I will credit you. Or help me by giving feedback or reporting bugs. Please help me foolproof it.

Edit: There is no catch! It's free! You can use it in any project commercial or personal! Your only obligation is to read the license (MIT License) before using it. The code now is proven without any known issues! If you find any bug or you want to suggest an improvement just reply to this thread...
 

Mert

Member
This works perfectly on mobile devices, but won't work on HTML5 target(or am I doing it wrong?)
 

gkri

Member
This works perfectly on mobile devices, but won't work on HTML5 target(or am I doing it wrong?)
Unfortunately, I do not have the html5 module (I was planning to buy it, but I lost my job cause of covid), thus I am not able to test it. I am suspecting that it won't work on html5, because as far as I know, the canvas size is based on browser. Am I right?

You could make a test project and confirm if it is working or not, both on browser window and on full screen mode.
 

Mert

Member
Unfortunately, I do not have the html5 module (I was planning to buy it, but I lost my job cause of covid), thus I am not able to test it. I am suspecting that it won't work on html5, because as far as I know, the canvas size is based on browser. Am I right?

You could make a test project and confirm if it is working or not, both on browser window and on full screen mode.
Oh, happy to confirm that. I might work on that.

There's one piece I don't understand tho. You disable application surface, yet try to resize it afterwards. Why?
GML:
application_surface_enable(false);  // false as default behaviour
window_set_size(_ideal_width, _ideal_height);
surface_resize(application_surface, _real_width, _real_height);
 

gkri

Member
This is because of the scale argument
Code:
set_resolution (design_value, is_design_vertical, is_orientation_vertical, resize_all_rooms, scale (optional), overide_other_value (optional))
It is for a quality of life feature for mobile development. As long as scale argument is omitted (optional) or is passed as 1 (aka no scale), you can enable the surface and should not have any problem.

More specifically it is for faking the portrait orientation on VM->Test builds, while scaling down the game window so it can fit into a desktop monitor.

Edit: Also iirc Pixaleted pope does the same thing with surface (the code is heavily based on his code)
 

gkri

Member
You disable application surface, yet try to resize it afterwards. Why?
Ohh! I am really sorry! I replied you last night without actually answering your question! It was quite late here (Greece) and I was sleepy...

Before I implemented the scaling feature, I had the application_surface_enabled to true, but eventually I changed it to false (as I said to prev reply). I did not remove the surface_resize, because it felt to me that the surface should be resized anyway (even not enabled is still there, right?), since you can always enable it afterwards.

I have prepared 3 example projects which I'll upload soon on itch.io (and maybe later at yoyo marketplace) and along with them, I will try to document the script as much as I can.

Additionally, I am more that happy to answer any question about the script and as well getting feedback to make it better!
 
Last edited:

Mert

Member
Ohh! I am really sorry! I replied you last night without actually answering your question! It was quite late here (Greece) and I was sleepy...

Before I implemented the scaling feature, I had the application_surface_enabled to true, but eventually I changed it to false (as I said to prev reply). I did not remove the surface_resize, because it felt to me that the surface should be resized anyway (even not enabled is still there, right?), since you can always enable it afterwards.

I have prepared 3 example projects which I'll upload soon on itch.io (and maybe later at yoyo marketplace) and along with them, I will try to document the script as much as I can.

Additionally, I am more that happy to answer any question about the script and as well getting feedback to make it better!
Hi neighbour. Now I understood the logic. I have tested it and the screen looks crystal clear. I might be able to work on it to adapt it to HTML5
 

gkri

Member
Hi neighbour.
I had to hover the mouse over your profile pic to understand that reference :p XD, neighbor.

If you manage to find time and adapt it to HTML5, please, share it here if you want and I will include it into this thread, with the appropriate credit of course!
 

gkri

Member
Added to thread
--------------------

Edit: Compatibility:
  • The script is working 100% as it should on mobile and desktop targets. It has not tested on UWP, HTML5 and any console target. If you own any license from the not tested platforms, if you test it, please let us know if is working correctly!
  • When targeting desktop the parameter _is_orientation_vertical should be false.
  • Mobile quality of life features are intended for mobile projects. If the project is cross platform, you should use those features only when working the mobile aspects of your project. The mobile quality of life features are _is_orientation_vertical as true, and the optional arguments: scale and overide_other_value.

Edit: Known limitations:

1. If the game window is bigger that your monitor screen, GMS will scale it unevenly causing distortion on graphics.
Affets VM->Test builds with "faking" portrait orientation only. It does not affect landscape aspect ratios and it does not affect any build on actual mobile devices.
Solution: Use the optional scale argument to scale the window down in order to fit inside your monitor.

2. When working on VM->Test builds with "faking" portrait orientation, if the application surface is enabled the graphics are heavily distorted.
Affets VM->Test builds with "faking" portrait orientation only. It does not affect landscape aspect ratios and it does not affect any build on actual mobile devices.
Solution: Enable and use the application surface, conditional based on os_type, so you can keep enjoying the "faking" portrait orientation on VM->Test builds

3. When working on VM->Test builds with "faking" portrait orientation, if window_set_fullscreen is enabled the graphics are heavily distorted. It does not make sense to use window_set_fullscreen enabled with VM->Test build "faking" portrait orientation, anyway...
Affets VM->Test builds with "faking" portrait orientation only. It does not affect landscape aspect ratios and it does not affect any build on actual mobile devices. The build on an actual mobile device will be full screen anyway...
Solution: Unless getting a second monitor and having oriented vertically, there is not any actual solution nor needed one...
 
Last edited:

gkri

Member
Now you can download three example projects and find a more detailed tutorial of how to use the Advanced Resolution Manager on itch.io



Sneak peek of the Dynamic orientation example:
 
Last edited:
I have one question, its posible to adjust the scripts or how can them be implemented for adjusting the backgrounds of a mobile game? or its possible to use them to adjust?(thanks for that example projects)
 

gkri

Member
I am not sure If I understand the question. So, if you are asking for any kind of permission to modify the scripts, is not necessary. You may modify/adapt it as want. You can use it at any kind of projects, commercial or personal. Also no attribution is required.

If your question is not about licensing but technical, please let me know...
 
the script change the resolution of the room according to the display size, when I add a background to the room, when I run the game, the room size changes but the background image stay with the first size, It is possible to use this script shomehow to also adapt the background size?
 

gkri

Member
the script change the resolution of the room according to the display size, when I add a background to the room, when I run the game, the room size changes but the background image stay with the first size, It is possible to use this script shomehow to also adapt the background size?
What is your design resolution? What is the size of the background image? What is the screen resolution of the mobile device? Also a screenshot could help...
 
What is your design resolution? What is the size of the background image? What is the screen resolution of the mobile device? Also a screenshot could help...
My room resolution is 1080x1920, the background image is the same, for example in my mobile device the resolution is 1080x 2400, when I run the game the room size changes thanks to the script but the background stays the same and looks bad.
 

gkri

Member
My room resolution is 1080x1920, the background image is the same, for example in my mobile device the resolution is 1080x 2400, when I run the game the room size changes thanks to the script but the background stays the same and looks bad.
The most possible scenario here is that you passed the ideal width (1080 pixels):

GML:
set_resolution(1080, false, true, true);
That means that your background image (1080x1920) will fit perfectly on the width of your mobile device (which is 1080), so no resize will occur, thus, seeing a black box on the bottom of your device screen.

Let's say this is the CASE A in following picture inside the spoiler:

If you go with the CASE B, using:

GML:
set_resolution(1920, true, true, true);
...then the background will scale up to fit the height of the mobile screen while is not fit on width.

I chose a pic which is bad for mobile multi-resolution, to show that having a background picture with the ideal resolution is not enough. I do not know what game you are making, but you should be smart when designing, so your assets will look appropriate on any aspect ratio.

See that picture of a design example:
design.png

The design is going on the bottom of the screen then inside GMS2 put a solid color as bottom background (sky). Now no matter how big will be the height of the mobile screen, this background will always look apropriately as long as you use the CASE A from above.
 
Last edited:
Top