Corona SDK Pro Tip #36
SmartPixel config.lua

You all know the config.lua file and you know how important it is. However, using the standard configuration makes your apps and games a little blurry on devices with different resolution than iPhone 4 or 5.

Here is the standard config.lua.

Standard config.lua

application = {  
    content = {
        width = 320,
        height = 480,
        scale = 'letterbox',
        fps = 60,
        imageSuffix = {
            ['@2x'] = 1.1,
            ['@4x'] = 2.1
        }
    }
}

The problem here is that content width and content height are fixed. And on iPad the game will be a little blurry. But to make it pixel perfect for iPad you must specify 384x512 as the content size. Being multiplied by 2 that would result in 768x1024 - native screen resolution of non-retina iPad.

So my idea was to take display.pixelWidth with display.pixelHeight and calculate optimal content width with content height for the current screen.

Corona Labs recently introduced "adaptive content scaling", which is very similar to my idea, however it's goal is to provide same physical size of your screen elements. It doesn't take into account pixel perfection, so your games and apps will still be blurry on different devices.

So my goal was to make content scaling pixel perfect on as much devices as possible. And here is how I achieved that.

Smart pixel config.lua

local w, h = display.pixelWidth, display.pixelHeight

local modes = {1, 1.5, 2, 3, 4, 6, 8} -- Scaling factors to try  
local contentW, contentH = 320, 480   -- Minimal size your content can fit in

-- Try each mode and find the best one
local _w, _h, _m = w, h, 1  
for i = 1, #modes do  
    local m = modes[i]
    local lw, lh = w / m, h / m
    if lw < contentW or lh < contentH then
        break
    else
        _w, _h, _m = lw, lh, m
    end
end  
-- If scaling is not pixel perfect (between 1 and 2) - use letterbox
if _m < 2 then  
    local scale = math.max(contentW / w, contentH / h)
    _w, _h = w * scale, h * scale
end

application = {  
    content = {
        width = _w,
        height = _h,
        scale = 'letterbox',
        fps = 60,
        imageSuffix = {
            ['@2x'] = 1.1,
            ['@4x'] = 2.1
        }
    }
}

display.pixelWidth and display.pixelHeight is the native resolution of a device. modes are scaling coefficients that this script will try to use. It iterates over this table, applies scaling with the current coefficient and checks if it's OK or not. If the resulting content size is smaller than desired such coefficient is not used and the one before it is chosen instead.

There is a number of devices, for which pixel perfect resolution is impossible with desired content size. For example 480x800 screen. For them 1.5 factor is chosen by the script. However since it is not pixel perfect anyway, the script recalculates the coefficient using the letterbox method. So effectively scaling factor becomes somewhere between 1.0 and 2.0.

Inside the application.content table it doesn't matter what scaling method is choosen. zoomScale, zoomStretch or letterbox - all will be the same, because the script already made all the necessary calculation.

As a positive side effect there will be no black bars and it's easier to work with device corners and edges. Because x = 0, y = 0 coordinates is always the top left corner of the screen on any device. And x = display.contentWidth, y = display.contentHeight is always the bottom right corner. That makes positioning elements much easier and more conscious. Bear in mind that your code must account for the dynamic content size and not use fixed coordinates for your on screen elements. They all must be relative to device edges or corners.

You can download this config.lua with a demo project from GitHub - https://github.com/Lerg/smartpixel-config-lua

The demo project shows you what it would be like running on different devices. It reports content size, scaling factor and if it's pixel perfect or not.

Here is how it looks like on iPhone 4, iPhone 6 and iPad.


iPhone4 iPhone6 iPad

Moreover inside the demo project you will find a special file called testscaling.lua. It's purpose is to tell you what actual content width and content height would be on all popular screen resolutions. You can run this file with Corona, with a command line Lua interpreter or inside ZeroBrane Studio IDE. Here it's output.

testscaling.lua output

iPhone 3  screen:     320 x 480   aspect: 1.5  
          content:    320 x 480   scale:  1

iPhone 4  screen:     640 x 960   aspect: 1.5  
          content:    320 x 480   scale:  2

iPhone 5  screen:     640 x 1136  aspect: 1.775  
          content:    320 x 568   scale:  2

iPhone 6  screen:     750 x 1334  aspect: 1.7786  
          content:    375 x 667   scale:  2

iPhone 6+ screen:     1080 x 1920 aspect: 1.7777  
          content:     360 x 640  scale:  3

iPad Mini screen:     768 x 1024  aspect: 1.3333  
          content:    384 x 512   scale:  2

iPad Air  screen:     1536 x 2048 aspect: 1.3333  
          content:     384 x 512  scale:  4

medium 1  screen:     400 x 854   aspect: 2.135  
          content:    320 x 683   scale:  1.25

medium 2  screen:     480 x 800   aspect: 1.6666  
          content:    320 x 533   scale:  1.5

medium 3  screen:     480 x 854   aspect: 1.7791  
          content:    320 x 569   scale:  1.5

medium 4  screen:     600 x 800   aspect: 1.3333  
          content:    360 x 480   scale:  1.6666

high 1    screen:     540 x 960   aspect: 1.7777  
          content:    320 x 568   scale:  1.6875

high 2    screen:     600 x 1024  aspect: 1.7066  
          content:    320 x 546   scale:  1.875

high 3    screen:     800 x 1024  aspect: 1.28  
          content:    400 x 512   scale:  2

xhigh 1   screen:     720 x 1280  aspect: 1.7777  
          content:    360 x 640   scale:  2

xhigh 2   screen:     768 x 1280  aspect: 1.6666  
          content:    384 x 640   scale:  2

xhigh 3   screen:     768 x 1366  aspect: 1.7786  
          content:    384 x 683   scale:  2

xhigh 4   screen:     800 x 1280  aspect: 1.6  
          content:    400 x 640   scale:  2

xxhigh 1  screen:     1200 x 1920 aspect: 1.6  
          content:     400 x 640  scale:  3

xxhigh 2  screen:     1600 x 2560 aspect: 1.6  
          content:     400 x 640  scale:  4

I've collected here all iOS screen variants as well as all popular Android resolutions.

Using this table you can check what would be the maximum content width and content height. You need this info for say making a large enough background image. You can see it would be 400x667 in content points. That would make it 1600x2668 pixels for a "@4x" file.

In the table if scale has decimal part - the scaling is not pixel perfect, without decimal part - pixel perfect. As you can see all iOS devices would be pixel perfect. And the majority of modern Android devices are pixel perfect as well.

If you've been waiting for a such config.lua file for a long time - feel free to make a donation. It will support all my future work on Corona SDK Pro Tips.

Indie Game Developer