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:
What the script does and how to use it
The script accepts 4 mandatory and 2 optional arguments (total of 6):
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:
Here is a quick example of how to use those values:
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
EDIT : Added GMS2.3 version of the script
What's the catch?
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:
Edit: Known limitations:
This is a minor but necessary update. Compatible with GMS2.3.7.403 and later. The latest version of the scripts are backwards compatible and they won't break your projects. Just remove the old version before importing the new one.
Now all arguments except the
is the same as:
The
Thank you for you time
George Kritikos
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.
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)
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 is_design_value_vertical as true . 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 is_design_value_vertical as true, if the application surface is enabled the graphics are heavily distorted.
Affets VM->Test builds with is_design_value_vertical as true . 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 is_design_value_vertical as true, 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 with is_design_value_vertical as true , anyway...
Affets VM->Test builds with is_design_value_vertical as true. 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...
UPDATE - 7 Jan 2022:This is a minor but necessary update. Compatible with GMS2.3.7.403 and later. The latest version of the scripts are backwards compatible and they won't break your projects. Just remove the old version before importing the new one.
Now all arguments except the
_design_value
in the set_resolution
are optional meaning that:set_resolution(640);
is the same as:
set_resolution(640, false, false, false);
The
set_gui_size
script has been impoved. Both arguments are optional now. If both arguments omitted then the GUI layers size will be the same as the game's resolution. If either argument omitted then it will be calculated to fit the current aspect ratio of the game's resolution.Thank you for you time
George Kritikos
Last edited: