#TheoreticalThursday Making your PC game resolution agnostic - Solving the PC game resolution problem
One of the biggest problems with creating a PC game is figuring out what resolution to use, and how to give the users the same, or at least a very similar, experience regardless of the size of screen with which they view the game.
Of course if you're doing a 3D game, the user is usually just picking the size of the viewport, and the biggest issues you will have with screen resolution is the placement of the HUD (short for Heads Up Display) elements. The article will focus more on 2D games, with some principles that can be applied to HUDs as well.
My previous approach on Plethora 2012 Disclosure was to scale the graphics based on the user's resolution. This gave consistent sized objects on all the included resolutions, but had the downside of a limited number of different resolutions, and graphics that didn't look their best on anything but 1920x1080. The problem is, if you are scaling a 4 pixel graphic to ½ size, you get 2 pixels, but if you're scaling a 3 pixel graphic to ½ size, you are going to get 1 or 2 pixels, depending on which way the number is rounded off. There are no half pixels! Heheh So only graphics that have no single pixel edges are going to look right. Simply scaling the graphics gives a strange aliased look, like the graphics are wrinkling as they move. So this approach worked, but it made my graphics look worse and I don't need any help making my graphics look bad, heheheh
There are so many possible resolutions, I had no idea which ones to include in Platfinity, and realized the best solution was to make it so the game would work no matter what. The solution I came up with was to make the interface fit into the smallest common Windows desktop resolution, 800x600. Yes, I know almost no one in the entire world uses that small a resolution on a desktop or laptop, but you have to consider there are netbooks out there that can run at 800x600 or 1024x600, like the popular Acer Aspire One. So there would be a few, and there's no reason Platfinity wouldn't run on a netbook.
The first thing a game should do, and I'm not sure why all games don't do this, but as of 2014 they still don't, is to figure out what resolution the user is already using. In Platfinity, I did this with a system call to figure out the desktop resolution. This is a default highest resolution the user will be comfortable with, and gives us our native resolution. For the biggest group of people, this will be 1920x1080, or HD 1080p. The second most popular resolution is 1366x768, or what I think of as typical laptop resolution, if we're cutting things to their lowest common denominator. Nearly 60% of resolutions are 1920x1080 or 1366x768, so we can just support those two and a few more and we're good, right? WRONG. We need to realize, that in the PC market at least, there is always going to be someone out there with a weird resolution. You can't even count on 16:9 ratio, as there are a lot of people out there still running 4:3 monitor setups...and you need to support these people.
But in order to support potentially everyone, we have to figure out a baseline, or the absolute lowest resolution we're going to see. In 2014, that's 800x600. I would be very shocked if you found anyone running their Windows desktop at 800x600 unless it's a netbook, but it makes a good baseline. You may see 1024x768 or 1280x1024. And there are a ton of additional resolutions that are not too far from these. What do these numbers all have in common? Just about any graphics card in the world is going to support 800x600. And 1024x768 are supporting the x768 in the most popular laptop resolution, 1366x768.
So what have we learned from all this? That 800x600 is the absolute minimum, but also that the Y figure is rarely greater than 768. And at the most, it's 1080. Sure, there are 1200 Y configurations out there, but aren't they going to be used to letterboxing at the bottom on all these games designed for 1080p? The point is, we need to plan for 600 to 1080 Y pixels. And 800 to 1920 X pixels. Looking at this, we can see the X pixel difference is much bigger, and will be much more of a factor in our design considerations.
OK, so what can we do - I.E.: get to the point - to solve these resolution problems and make just one game, or write code one time that will work regardless of the user's setup?
Step one: make everything based on the center of the screen. This may seem incredibly obvious, but the first thing you'll want to do, once you've figured out the user's native resolution, is to figure out where the center of the screen is. Then you base everything on this. In Platfinity, resolutions from 800x600 to 1920x1080 are supported, regardless of aspect ratio and with no resolution menu. All of the interface elements fit into a 800x600 space. So no matter the size of the screen, the interface still works correctly. All of your graphics X,Y locations should be relative to the CenterX, CenterY location you get by DesktopResX/2-1, DesktopResY/2-1. Everything is drawn at a location offset from the center X,Y and nothing in the interface is outside the 800x600 area that you can guarantee every user will have.
Step two: figure out where the edges are. The top left edge is going to be 0,0 in most cases. The bottom right is going to be DesktopResX-1, DesktopResY-1. Things that go on the side of the screen move inward from these positions. Text starts on the left and goes to the right, so text can be set to zero on the left but is X border minus len(text) on the right.
Everything in your user interface is going to be set to the edges, or offset from the middle. Use variables for every positioning of anything in the interface, that way anything can be moved, and everything is based on the center of the screen or a known screen edge.
The playfield in Platfinity is 1920x1080. The character stays in the middle of the screen, as if the 'camera' is focusing on the character. There are two levels of zoom, 2X and 4X. Regardless of the level of zoom or the users screen size, the playfield scrolls around to show the visible pixels. If the character approaches the edges of the playfield, the playfield stops scrolling to avoid showing the empty pixels off the sides or top/bottom of the playfield. The offset from the side of the playfield to the character's position is calculated for each resolution, and everything is based on the same math regardless of the size of the screen the user is viewing the game on. When editing, the mouse cursor scrolls the screen when it gets close to the edges, so the user can place objects or tiles anywhere, no matter how small their actual screen resolution is. None of the numbers are hard coded, so they work in any case.
I hope this gives you some ideas on how to solve your resolution problems with PC games. I think some of these same principles could be used for Android games, as there's a great variety of different screen resolutions on there too, or on web based games that may be played on different browser setups.
Platfinity is on Steam Greenlight now if you want to check it out:
You can buy it on itch.io, IndieGameStand, and Desura: