Scaling, Resolution, and Aspect Ratio Management for GMS1 & GMS2

T

TheMatrixHasMe

Guest
Yeah, if that's showing up outside of the game window and on your desktop, that is most definitely a video card related issue and not a GM related issue.
Thanks for the assistance, i'll take a look at it from that angle.
 
A

Almightyblob

Guest
In Game Maker Studio 2, the room_set_view function has been removed. I wondered if this tutorial is useless now in this new version or whether there is a workaround / update to come this with viewports and cameras?
 
S

saintlowfi

Guest
Thanks for the Great tutorial !! @Pixelated_Pope
I have some issue i don't know how to fix. I think it is due to the monitor resolution and game resolution.
when i test on Win(not full screen,window size is game resolution) , all looks fine.
but i test on iphone the pixel is deformed while the instance is rotating.
I use an iphone 5s(1136*640) My game resolution is 320*180;
is it occur because not integral multiple?

if i change the game resolution 640/180=3.56,so it should be smaller 4 times
but if i use an iphone 6s(1334*750) 750 can only exact division 5 times nearest that size which means iphone 6s view is quite smaller than iphone5s , not logical.
is there a way that the view keeps the same no matter what iphone i use?

rotate
2.png
vertical
3.png

how to fix it to looks the skull & bone below?(the pixel is not deformed but jagged into smaller pixel)
1.png

Please advise : )
 
@saintlowfi

If you want your rotations to be cleaner you need to resize your application surface to be the same size as your window/display size.

Go to 16:45 in Part 3 to learn how to do that. Although, what you might want to do is when you are setting up your views and gui size and everything in the create event of your display manager, set the application surface size to dipsplay_get_width and display get height.

Keep in mind this WILL IMPACT PERFORMANCE. Your game will run slower. You may want to do half the display size or some other ratio. Do some tests and calculations to figure out a size that is below the same size as the display, but makes things look better.
 

superschure

Member
Firstly, thanks for this; all of this! This information is invaluable.

I'm building a project in a 960x540 native res with the intent to have it on Vita and scale 2x to 1920x1080 and still look sexy. Understandably 720p is still out there and I'm trying to facilitate it as an scalable option but I know this is 1.5x so bleh. I've been tinkering with you code trying to get my ideal height at 540 to handle 720p but of course 1.5x so bleh. My question is should I just say screw you 720p and stick with 540p & 1080p or downscale to 640x360 native res and screw the 540p? I'm still early enough in the project that switching isn't going to be an issue. I just know that if I go with 360p then scaling to 540p is going to be that bleh 1.5x.

Anybody have success with this going from 540p to 720p?
 
@superschure If you can downscale, downscale. The smaller the base resolution of your game the better it will scale. Even if it doesn't scale perfectly, once you get over 2x (or even better 3x), the distortion really starts to be less and less noticeable. Couple that with a visually interesting game, and all those little things won't even register with the player.

Make your game smaller. And perceived downside of a lower res game will be completely overruled by all the gains in other areas (texture page size, performance, etc).
 

superschure

Member
@Pixelated_Pope Even though it pains me to drop it down from 960x540 since I've got some assets that look awesome with the extra native res; dropping it to 480x270 is looking like my best bet after you stated performance being a key benefit. That will still give me a good 2x res and FULL GLORIOUS HD at 4x res. I believe HLD used that native res too and it worked out well in the end.
 
I am also wondering about GMS2 implementation. I am currently stuck on my project because of not knowing what to do for resolution, scaling, and how big of sprite images I should be importing. My game is like a visual novel with drawn/CG portraits as well as vector art and needs the art to be good without pixelation. I was thinking about doing 640x360 for HTML5 export and then for desktop export I would do 640x360, 1280x720, and 1920x1080 with full screen. Can somebody tell me if this will maintain and make the art look great? I am concerned about the art and how well the display will adapt to the resolution.
 

Jaqueta

Member
My game is like a visual novel with drawn/CG portraits as well as vector art and needs the art to be good without pixelation.
Vectors are drawn with primitives, so they won't loose quality, regardless of resolution. If you import the .swf files, of course. For the sake of consistency, I recommend using Vectors for most of the art, and only use bitmaps when really necessary.

Other thing, if your game is NOT pixel art (and you use Pixel Interpolation to avoid aliasing), it's very likely that it will look good on any resolution, as long as the sprites are High Quality.
 
it's very likely that it will look good on any resolution, as long as the sprites are High Quality.
Along with this, increasing the size of your application surface will improve the fidelity of vector images (as it gives them more pixels to "rasterize" to).

@thaaks No immediate plans, but it has certainly been requested. I'm still not terribly comfortable with the new camera system, so I don't want to tell people "this is how to do it" when there is a better way. That being said, it is possible to adapt the current tutorial to "work" I just don't make any promises about it being the "best" way.

http://pastebin.com/vTdRGBCw
 

thaaks

Member
@Pixelated_Pope thanks for the answer and the code. What are you using the Alt_Camera for? Zooming? Then you might additionally add the remaining code to pastebin where you switch between cameras and implement zooming using cameras?
But at least it gives me something to start with - thanks a lot for that!
 
@thaaks Nah. I use two "cameras" in my game. One that always focuses on the group of player characters and another that is more "free". So the players both move and are restricted by camera 1, but when I want to pan over to show a door that a switch just unlocked, I can switch to camera 2 seamlessly.

 
Vectors are drawn with primitives, so they won't loose quality, regardless of resolution. If you import the .swf files, of course. For the sake of consistency, I recommend using Vectors for most of the art, and only use bitmaps when really necessary.
My only problem with swf vector art is that for some reason when I import it to GMS2, some of the vectors become pixelated no matter what I do.

I have an alternate approach instead of using vector art if I can't get it to work. Would using pixel art mainly for backgrounds and some objects go well with drawn/CG HD full body characters? Would resolution sizing mess up? I am just trying to avoid having to pay an artist to draw backgrounds and simple objects when I could do that myself and just have the artist draw the full body characters instead.

Thank you :)
 
I have an alternate approach instead of using vector art if I can't get it to work. Would using pixel art mainly for backgrounds and some objects go well with drawn/CG HD full body characters? Would resolution sizing mess up?
Typically you see the other way around. The backgrounds are a bit more "painterly" and the foregrounds are more simple/pixelated. This is especially common in animation (traditional and anime, etc). But that will largely be up to you as the creator to determine if that's the aesthetic you want to go with. If you are using pixel art, scaling is always going to be a factor. If your game is sufficiently low res enough, scaling up past the 3x or 4x mark will make most distortion invisible (especially for a visually interesting game).

My only problem with swf vector art is that for some reason when I import it to GMS2, some of the vectors become pixelated no matter what I do.
Interesting. I haven't messed with vector on GMS2. Have you messed with application surface size? I know in GMS1 you could use draw_enable_swf_aa() and draw_set_swf_aa_level() to adjust the quality of your SWF.
 

ajan-ko

Member
@Pixelated_Pope

After watching all your chapter.

I set the ideal height into 540, (960x540)
so the 1080p monitor can go fullscreen without worry.
surface_resize(application_surface,ideal_width*2,ideal_height*2);

On full screen, almost no distortion.

but when I'm not in fullscreen mode
then I tried to zoom in into 1.5.

It will distort.
hmm... (o_o)a
at this point... gonna throw out the zoom feature, it's not worth it...
 
Last edited:
Hey Guys! New update for those of you using GMS2. Here's how to transfer everything over from GMS1 and get your old view controls back.

 
Hello, I saw your videos and im a huge fan.
what if i have a game that is set to 900,1200 which is the resolution for ipads (3/4) but i want it to be able to scale for phones which is 9/16 among others. how does the code change?
 
@Michael Hart
It shouldn't. You've set your ideal width OR height and you let the other adjust accordingly.
Im not sure what happened but i set the height, and did the code to find the width but for some reason the ideal width (originally set at 0) was larger than the screen disply.
Is there anything that would depend on the app being landscape or portrait? im currently doing portrait.
 

Ethanicus

Ethan L!
This is all I'm doing in my startup room:
Code:
window_set_fullscreen(true)

display_aspect_ratio=display_get_width()/display_get_height();

view_wview=view_hview*display_aspect_ratio;
view_wport=view_hview*display_aspect_ratio;

sdiv=1;
gdiv=1;

display_set_gui_size(display_get_width()/gdiv,display_get_height()/gdiv)
surface_resize(application_surface,display_get_width()/sdiv,display_get_height()/sdiv);
Then my camera grabs this and applies it to every room it enters. Is there anything wrong with this, or should it be fine?
 
Im not sure what happened but i set the height, and did the code to find the width but for some reason the ideal width (originally set at 0) was larger than the screen disply.
Is there anything that would depend on the app being landscape or portrait? im currently doing portrait.
Again, I recommend watching part 1 and learning about the difference between maintaining the width or maintaining the height. You'll have to accept changes in one of them to get rid of the black bars. Try both ways to see which one works better for your game, but neither is going to be exactly like the other display with the different aspect ratio.

Is there anything wrong with this, or should it be fine?
I mean... I guess that's fine. ¯\_(ツ)_/¯ No reason to set your port in code, it doesn't really do anything. I also like to have my gui the same size as my view so that the pixel grid at least appears to be the same, but that's up to you. If it's working, then great. Don't worry about it until you find a reason to change it.
 
Hey Buddy Its a great video series and it worked wonders when making a project with gms 1
I am now using gms2 and am a little lost.
Im not using and zoom or follow the player i just want it to ditch the black bars.

This is what i had before for a landscape app

how do i fix only this part?
I watched the video (part 5) but i am not getting it.


///Display Properties
ideal_w = 900
ideal_h = 0

//aspect_ratio = display_get_height()/display_get_width()


ideal_h = round(ideal_w*aspect_ratio)

if (ideal_w & 1)
ideal_w++

for (var i = 1; i<=room_last; i++)
{
if (room_exists (i))
{
room_set_view(i,0,true,0,0,ideal_w,ideal_h,0,0,ideal_w,ideal_h,0,0,0,0,-1)
room_set_view_enabled(i,true)
}
}

surface_resize(application_surface,ideal_w,ideal_h)
window_set_size(ideal_w,ideal_h)

room_goto(room_next(room))











thanks for any help you can provide
 
for (var i = 1; i<=room_last; i++)
{
if (room_exists (i))
{
room_set_view(i,0,true,0,0,ideal_w,ideal_h,0,0,ideal_w,ideal_h,0,0,0,0,-1)
room_set_view_enabled(i,true)
}
}
Maybe you should watch part 5 again. I explicitly state that this for loop should be removed from the original manager's code. The replacement is in the room start event.
 

jonjons

Member
hello
Ive started using this tutorial again its the best for removing black bars
the problem ive come to face is the player following
somehow the:
view_xview = obj_player.x-view_wview/2 - 10;
view_yview = obj_player.y-view_hview/2 - 10;
doesnt seem to work well... i think its a code order begin step, step, end step... on obj_player

Is there a way to set the view following with: view_object[0] = obj_player; ?
 
You shouldn't use the view_object/object following feature because it will force your view's position to be locked to a whole number. If you are using sub pixels, this will make your scrolling much more choppy. You also lose total control over when your view is actually moved. That code works fine. Put it in the end step. But the idea is to do it after you've moved your player, but before any draw events start. End step is ideal. Pre-draw might work as well.
 

jonjons

Member
You shouldn't use the view_object/object following feature because it will force your view's position to be locked to a whole number. If you are using sub pixels, this will make your scrolling much more choppy. You also lose total control over when your view is actually moved. That code works fine. Put it in the end step. But the idea is to do it after you've moved your player, but before any draw events start. End step is ideal. Pre-draw might work as well.
It doesnt seem work...
although its very strange ive commented the entire "Aspect Ratio Management for GMS1 & GMS2"
left only the view_object[0] = obj_player... and still didnt worked...
but view_object[0] seems to work on a diferente object.
 
Last edited:

jonjons

Member
it seems view_object[0] only works on the room that contains the obj_display_manager
when going to the next room the view_object[0] is no longer active...
even with obj_display_manager set to presistent
 

WuTom

Member
I am having a hard time with full screen resolution setting. I want my game to be mainly 1600 x 900 (if it is 16:9 aspect ratio), 1600 x 1000 id 16:10 and 1600 x 1200 if 4:3. How can I set my game to be from corner to corner (unless it is some other ASPECT RATIO, then I want black bars)?

Code:
global.gameWidth = 1600;
global.gameHeight = 900;

window_set_fullscreen(true);

aspectRatio = display_get_width() / display_get_height();

if(aspectRatio > 1.7) //16:9
{
    global.gameWidth = 1600;
    global.gameHeight = 900;
}
else if(aspectRatio > 1.5) //16:10
{
    global.gameWidth = 1600;
    global.gameHeight = 1000;
}
else //4:3
{
    global.gameWidth = 1600;
    global.gameHeight = 1200;
}

global.camera = camera_create_view(0, 0, global.gameWidth, global.gameHeight, 0, -1, -1, -1, 32, 32);

for (var i = 1; i <= room_last; i++)
    {

        // enable view and setup viewport
        room_set_view_enabled(i, true)
        room_set_viewport(i, 0, true, 0, 0, global.gameWidth, global.gameHeight);

        // set camera for room
        room_set_camera(i, 0, global.camera);
    }

surface_resize(application_surface, global.gameWidth, global.gameHeight);
window_set_position(display_get_width() / 2 - global.gameWidth / 2, display_get_height() / 2 - global.gameHeight / 2);

room_goto_next()
 
So, it looks like you are pretty close, but don't use > 1.7 or whatever. say == 16/9 or ==16/10 or ==4/3. That should set your game size to the desired sizes based on the display's resolution and default to 1600x900 on unsupported resolutions with black bars.
 

WuTom

Member
So, it looks like you are pretty close, but don't use > 1.7 or whatever. say == 16/9 or ==16/10 or ==4/3. That should set your game size to the desired sizes based on the display's resolution and default to 1600x900 on unsupported resolutions with black bars.
But it still behaves so weirdly, when I put the resolution to 1600x1200 (should be perfect fit) it leaves black bars also below =S it's so weird. Only time when everything looks fine is when I have set 16:9 ratio on my display :/
 
Put a breakpoint and step through everything from where it checks the aspect ratio forward. See if it's actually setting your desired width and height appropriately. Make sure that you are also updating the application surface to match the changed view aspect ratio.
 
Hi @Pixelated_Pope - thanks for this tutorial is has helped me immensely.

I have a question about GUI positioning... What is the best way to position GUI elements when setting the GUI size to ideal_width and ideal_height? I am currently positioning the different elements by subtracting a certain amount of pixels from the display_get_gui_width/height functions. The problem is, when I change resolutions on my computer, it throws the GUI elements way off the intended X and Y positions. I must have misunderstood setting the GUI size to ideal_width and ideal_height because I thought that would scale and position the GUI elements correctly when resolutions varied. Any guidance would be greatly appreciated, thanks!
 
@Noloughlin
No, your understanding is perfect, but something must be going wrong. If you have set the gui size to be your ideal width and height then your UI elements should not change size as you change resolutions or enter/exit full screen... Something else must be going wrong.

Make sure you only have a single display_set_gui_size in your project, and that it is set to ideal width and ideal height.
 
2@Pixelated_Pope I have been playing with this for a few weeks now and I cannot for the life of me figure out what is going on. I followed your tutorial pretty religiously in implementing this into my project. Here are two pics showing my battle GUI in two different resolutions (1920x1080 and 1600x900). You can see my view is also changing a bit and it seems to be a wider view with 900, which my assumption was that is just how the ideal_width and ideal_height are driving the camera_set_view_size.

1080


900
 
Here are a few examples of my drawing code in the Draw GUI event. The global variables are just display_get_gui_width/height.
draw_sprite(sprBattleMenuBox, 0, global.guiWidth-394, global.guiHeight-70);
draw_sprite(sprCallanHealthBox, 0, global.guiWidth-495, global.guiHeight-270)
draw_text(global.guiWidth-396, global.guiHeight-245, string(objCallan.currentHealth) + " / " + string(objCallan.maxHealth));

I did check and make sure there was only one place I was setting my GUI size, which I am. The GUI size also matches up with the ideal_width/height numbers.

What it seems is happening is my camera's view is changing (gets wider with the 1600x900 resolution), since the camera_set_view_size is driven by the ideal_width/height which increases or creases depending on the resolution I am testing. The GUI elements don't seem to be shifting with my changing camera view size as you can see in the example above my "state" string in the upper right appears to move to the left.

One more thing to note, when I remove the perfect pixel scaling code (pasted below) this problem completely goes away. Although I have pixel distortion problems, of course. So it seems to be a problem of getting the GUI to position and scale correctly with the perfect pixel scaling code.

if(display_width mod ideal_width != 0)
{
var d = round(display_width/ideal_width);
ideal_width=display_width/d;
}
if(display_height mod ideal_height != 0)
{
var d = round(display_height/ideal_height);
ideal_height=display_height/d;
}
 
i think the issue may be your hard coded values there. The -394 the -70, etc.

Ideally you would use "proportional" positioning. You want something to be positioned "5 percent of the screen from the right edge" instead of global.guiWidth-50 or whatever, it's global.guiWidth-global.guiWidth*.05;

Try getting rid of all your magic numbers and replacing them with relative calculations and see what happens... If that doesn't help, would you be willing to share your project with me privately so I can investigate and give you a solution?
 
That seems to have corrected the problem, thank you so much! There is slight variance between resolutions (a pixel or two) but that is no doubt a trivial matter. Thanks again for doing this tutorial, this is something I have struggled with for awhile now.
 
No problem! I've been thinking of doing a tutorial for dynamically positioning GUI elements that would more clearly explain the issues you've been running up against... but I haven't had much time for tutorials lately. Glad you got it working!
 
Hey @Pixelated_Pope, I hate to backtrack the conversation on ya (and bug you more), but I actually may send you my project for you to take a look. It seems I have run into a few use cases where the slight altering of positioning of my GUI elements is in fact detrimental (I.e. the health string in the boxes above are not always centered in the box depending on the resolution). Another thing that seems to be happening is my camera view is altering too much given the shifting ideal_height and ideal_width variables driving the camera_set_view_size. I banged my head on the wall for quite awhile before I decided to reach out again, but I am at a loss for ideas.
 

tjuven

Member
Thank you for sharing this piece of golden nugget @Pixelated_Pope !
Just a heads up, when I tried to build for an android device with GM2 (IDE 2.1.4.218 - Runtime 2.1.4.218) I got stuck on a black screen after the initial splash and it took me some time to find what was messing stuff up, it was this line: globalvar view_x, view_y, view_w, view_h
 
Thank you for sharing this piece of golden nugget @Pixelated_Pope !
Just a heads up, when I tried to build for an android device with GM2 (IDE 2.1.4.218 - Runtime 2.1.4.218) I got stuck on a black screen after the initial splash and it took me some time to find what was messing stuff up, it was this line: globalvar view_x, view_y, view_w, view_h
Interesting. I'll have to spin the project up and maybe re-post the example code. Glad you found it useful, though.
 
Top