On pixel art and PC games

Posted by Gift of Death on Feb. 7, 2016, 3:13 p.m.

I started and project and I'm feeling good about it for the first time in ages! Yaaaay!

However. I figured that before I go all nuts on building things I go through all the technical stuff. Keyboard controls and gamepads, mouse navigating in menu, game options… and, now this is where I ran into a wall: game resolution.

Okay so if I'm going to make a game, I'm going to make one that I'd like to play myself. Not just for the sake of making something and half-arseing it. And I like it when games have versatile configuration chances, especially in case of PC gaming. And that includes proper video options. And proper video options have a good variety of resolutions to choose from.

My choice of graphical style causes a bit of trouble with this though. You see, pixels don't scale very well with uneven multipliers. Hand drawn graphics would be simple enough to scale down as lowering the resolution but scaling pixels up isn't as self explanationary. I've figured of a couple solutions but they both have their problems.

Okay, so one solution would be to simply have black borders around the game picture. That would be a silly thing to do, though. I guess we can all agree on that. Or you could add a fancy border overlay thing instead of the plain black box, but it's not much better.

Okay the better solution would be to simply scale the view port in relation to the wanted resolution. This works great in games that have a bunch of empty space around the game area/you can add it and it won't have impact on the experience, no problem. But how should we approach this with games with a moving field of vision? I did a little math.

Say, I want the real resolution of the view be around 640x360. If I scaled the view with some of the most used resolutions (according to this), ignoring the phone/tablet ones, here's how they would scale:

1920x1080 - 640x360

1680x1050 - 560x350

1600x900 - 533x300 or 800x450

1440x900 - 480x300 or 720x450

1366x768 - 683x384

1280x800 - 640x400

1280x720 - 640x360

1024x768 - 512x384

So, if my math is correct, between the widest and highest views views we have the differences of whopping 171/288 pixels in width and 100 pixels in height. That equals 75/144px left-right and 50px up-down of extra viewable area around the player. It depends a whole lot on the style of the game, but that can be a whole lot. The height difference I would still be willing to fix by letterboxing the thing, but 50 pixels aren't that much, not even the full height of a 64x64 sprite, and a projectile would be visible for some 5-10 frames (okay that's a big deal to some players) before it would on on the smaller screen. The width is a bit different though. It's the stupid 3 resolutions between 1920x1080 and 1366x768 and the old 1024x768 screwing it over the worst.

What I'll probably do is do the resolutions as listed above without letterboxing, scaling the view port to the resolution rather than scaling the view, and add the highest 2 real resolutions (since they are bigger in different directions) as an option to pick for windowed view - or fullscreen if you don't care about the distortion - in case somebody happens to feel discriminated for having picked a display with "wrong resolution".

But… I really don't know what to do with the 2 pieces of shit there. The smaller choices are too small and the bigger choices are too big. Why can't we just stick to a single standard (or say, 1920x1080 and 1366x768 because lol laptops). It would make things for devs easier.

[/QQ]

Sorry if that's hard to follow, I'm far from a decent writer.

Comments

Nopykon 8 years, 2 months ago

I'm lazy about this stuff, but I tend to make very low res games, like 320x240. I think the error is more noticeable if the scale factor is smaller (like 2 instead of 3 or 4). A row that is 3px instead of 4 is much less apparent than a row that is 1px instead of 2.

Usually I render at fixed height, but then vary width depending on aspect of the big screen, like:

"render_width = render_height* (big_screen_width / big_screen_height);"

Unaligned 8 years, 2 months ago

Since a standard screen resolution (let alone a ratio) is far from happening, give the end-user options.

Some people want to keep pixel ratios and use letterboxing, others don't mind if a sprite is a pixel or two wider or taller every other frame so they just keep the total aspect ratio. There's others who don't care at all about that stuff and would rather have the game render stretching to the whole screen (screen real state yo), disregarding ratios or whathaveyou.

If you're that worried, I'd say the easiest solution is to stick to whatever resolution best fits your game and then offer the different scaling options to the player.

mazimadu 8 years, 2 months ago

I usually design the game to run at a fairly salable resolution (say 940x540) calculate the width of the display in the first room. Then I scale the view width and viewport based on the calculated scaling factor. Refer to https://www.yoyogames.com/tech_blog/79

Mega 8 years, 2 months ago

I calculate my resolution based on a "minimum viable resolution". That's anything below 1024x768, and I tend to go for 800x450 (Because the widescreen ratios are more common than 4:3 or the rare 1:1).

Then, to 'fill' the screen I just find the maximum integral scale along the shorter dimension (Usually Y), and set the scale for both horizontal and vertical resolution to that scale, and letterbox anything outside that area.

The other way to do things is to render with a "safe area". Basically, make your game render in a resolution that has extra space around the borders (So maybe an 800x800 resolution), then calculate the positioning of on-screen HUD objects at runtime; that way you can do a nice 'fill' of the screen at almost any resolution while keeping your aspect ratio intact.

Relevant reading: https://en.wikipedia.org/wiki/Safe_area_(television)

mrpete 8 years, 2 months ago

I like to keep my pixel view even if possible. Afterwards, centering is used depending on the desired affect I'm trying to achieve.