Improvement to the Ultimate config.lua File?

Hi all,

The ultimate config.lua file (http://www.coronalabs.com/blog/2012/12/04/the-ultimate-config-lua-file/) is quite a popular way to deal with devices with different aspect ratios.  But I think I just hit on an approach that simplifies it a lot yet yields the same effect.  I wanted to share it / test it with the community to see if it’s helpful and to make sure I’m not missing something.

First, let me quickly describe how I’ve been doing content scaling.  I actually haven’t been using the ultimate config.lua.  Instead, my config.lua looks like this:

[lua]

application = 

{

    content = 

    { 

        width = 320,

        height = 480,

        scale = “letterbox”,

        imageSuffix =

        {

            ["@2x"] = 1.5,

            ["@4x"] = 3.0,

        },

    },

}

[/lua]

In order to know where the corners are and manage potential issues with letterbox cutting off parts of images, I define some useful variables like this:

[lua]

_W = display.contentWidth - display.screenOriginX*2

_H = display.contentHeight - display.screenOriginY*2

_UL = { x = 0 + display.screenOriginX, y = 0 + display.screenOriginY }

_UR = { x = display.contentWidth - display.screenOriginX, y = 0 + display.screenOriginY }

_BL = { x = 0 + display.screenOriginX, y = display.contentHeight - display.screenOriginY }

_BR = { x = display.contentWidth - display.screenOriginX, y = display.contentHeight - display.screenOriginY }

_C = { x = display.contentWidth/2, y = display.contentHeight/2 }

[/lua]

These represent the width and height of the screen, the coordinates of the four corners, and the coordinates of the center (all in content units).  I then place all of my assets relative to the corners or the center.

The only disadvantage I’ve encountered with the approach I’ve been using, and what I think the ultimate config.lua file is trying to address, is that the upper-left corner isn’t at (0,0).  Instead, it’s at (display.screenOriginX, display.screenOriginY).  That shouldn’t really be a big deal, since I use (_UL.x, _UL.y) as the coordinates of the upper-left corner.  The potential issue is that some third-party modules wouldn’t do this.  They might mistakenly think (0,0) is the upper-left corner (it’s not), and display.contentWidth and display.contentHeight span the full width of the screen (they don’t).  In that case, we’d have a problem.

The solution I’d like to run by the community is a config.lua like this:

[lua]

application = 

{

    content = 

    { 

        width = 320 * (display.pixelHeight/display.pixelWidth>1.5 and 1 or 1.5/(display.pixelHeight/display.pixelWidth)),

        height = 480 * (display.pixelHeight/display.pixelWidth<1.5 and 1 or (display.pixelHeight/display.pixelWidth)/1.5),

        scale = “letterbox”,

        imageSuffix =

        {

            ["@2x"] = 1.5,

            ["@4x"] = 3.0,

        },

    },

}

[/lua]

The effect of that bit of math is to set the content width or height appropriately for letterbox scaling according to the aspect ratio of the device.  Why is that good?  Because the upper-left corner is now (0,0), and display.contentWidth and display.contentHeight now cover the entire screen.  For example, on an iPhone 5, display.pixelHeight is 1136 and display.pixelHeight is 640.  If you do the math, you’ll see that it’ll set width to 320 and height to 568.

Is this an improvement to the ultimate config.lua?  I think so.  It’ll set the width and height appropriately for every single device, no matter what the resolution or aspect ratio.  And there’s no need to code into your config.lua different blocks for different devices.

I’m curious if folks try using this instead of the ultimate config.lua in one of their projects, whether it’ll work just the same.

Thanks!

  • Andrew

(P.S.: This approach is somewhat similar to a comment about halfway down that blog post made by a Tom71, but I think it’s even more general.)

Any of my modules in the code exchange should take into account the screen origin

Right, good modules do.  :-)  But the ChartBoost module, currently in beta, doesn’t yet seem to.

  • Andrew

The code is a little cut off for me, so I’m having a little trouble following the math.

One of the key’s for the ultimate config.lua was to deal with the iPad’s by making them 360px instead of 320px.  This keeps the center of the screen in the 320x480 pixel range  I’m assuming that the math does that?

Hi Rob,

Yes, the math does do that – for iPads, it gives a width of 360 and a height of 480.

Basically, what the math does in words is this:

  • If the device has an aspect ratio that’s taller than 3:2, then it leaves the width at 320, and it increases the height from 480 to the value that matches the device aspect ratio (e.g., 568 for an iPhone 5)

  • If the device has an aspect ratio that’s squatter than 3:2, then it leaves the height at 480, and it increase the width from 320 to the value that matches the device aspect ratio (e.g., 360 for an iPad)

I used 320x480 as my base coordinate system (i.e., my lowest resolution images target this size, my placement of images uses content coordinates based on this size, etc.), but it doesn’t have to be.  In the example above, one could replace 320 with 768, replace 480 with 1024, and replace 1.5 with 1.33333 (or 4/3, to avoid rounding), and it’ll work fine, but with 768x1024 as the “base” coordinate system.

  • Andrew

It looks like it simplifies things, especially for business type apps that typically have responsive design?

But the math is really *woosh* for me. Ultimate config file itself is easier to understand. Could you be bothered to put line by line comments in the code? Specifically line 6 and 7? 

Sure, here’s an annotated version.

[lua]

application = 

{

    content = 

    { 

        – The aspect ratio of the device we’re running on is display.pixelHeight/display.pixelWidth.  (We can’t use display.contentHeight/display.contentWidth as the aspect ratio, because it’s the content area that we’re now about to define!  Also, we can’t save the aspect to a variable, because config.lua is just a table.  So we’ll have to repeat it a few times.)

        – This example uses a base size of 320x480, which is an aspect ratio of 1.5.  One could modify this example to use other base sizes by simply replacing the 320, 480, and 1.5s with some other values

        – The content width will be 320, our base value, *unless* the device we’re running on has a squatter aspect ratio, i.e., an aspect ratio *below* 1.5.  In that case, we’ll keep the height constant at 480, and we’ll make the width wider than 320 so that the aspect ratio is the squat ratio.  What should the width be?  We’ll take 320 and multiply it by the ratio of our assumed aspect ratio (1.5) and the device’s actual aspect ratio

        width = 320 * (display.pixelHeight/display.pixelWidth>1.5 and 1 or 1.5/(display.pixelHeight/display.pixelWidth)),

        – The content height will be 480, our base value, *unless* the device we’re running on has a taller aspect ratio, i.e., an aspect ratio *above* 1.5.  In that case, we’ll keep the width constant at 320, and we’ll make the height taller than 480 so that the aspect ratio is the tall ratio.  What should the height be?  We’ll take 480 and multiply it by the ratio of the device’s actual aspect ratio and our assumed aspect ratio (1.5)

        height = 480 * (display.pixelHeight/display.pixelWidth<1.5 and 1 or (display.pixelHeight/display.pixelWidth)/1.5),

        – We’re using letterbox scaling

        scale = “letterbox”,

        imageSuffix =

        {

            ["@2x"] = 1.5,

            ["@4x"] = 3.0,

        },

    },

}

[/lua]

To help the math challenged, you could put:

local aspectRatio = display.contentHeight / display.contentWidth

at the top, and make the code a bit more understandable.

can you make the line shorter so its not cut off

Sure, it’s not cut off in my browser, but I guess it is on some.

And you’re right Rob.  For some reason I assumed config.lua was special and couldn’t handle any code aside from the application table.

[lua]

local aspectRatio = display.pixelHeight/display.pixelWidth

application = 

{

    content = 

    { 

        width = 320 * (aspectRatio>1.5 and 1 or 1.5/aspectRatio),

        height = 480 * (aspectRatio<1.5 and 1 or aspectRatio/1.5),

        scale = “letterbox”,

        imageSuffix =

        {

            ["@2x"] = 1.5,

            ["@4x"] = 3.0,

        },

    },

}

[/lua]

Here’s an equivalent way to do the math that’s probably even easier to understand.

[lua]

local aspectRatio = display.pixelHeight/display.pixelWidth

application = 

{

    content = 

    { 

        width = aspectRatio>1.5 and 320 or 480/aspectRatio,

        height = aspectRatio<1.5 and 480 or 320*aspectRatio,

        scale = “letterbox”,

        fps = 60,

        imageSuffix =

        {

            ["@2x"] = 1.5,

            ["@4x"] = 3.0,

        },

    },

}

[/lua]

removed to not cause confusion

Any 640px wide device will pick up the -568h@2x prefix.  The scale is anything greater than that scale factor.  The iPhone 4/4s are a 2.0 scale factor which is greater than 1.7775.

thats what i thought but its not loading my 568 file all im getting is regular images and @2x images

just checked after the above change and now im getting regular and 568 but not 2x

Right, the @2x will only load on devices from 480px to 567px wide.  568px wide and greater up to 959px wide will get your -568h@2x images.  960px wide and higher use @4x images.

This doesn’t look at the height only the width.  Your iPhone 5 is going to pick up the same images as the iPhone 4 because they are both 640px wide devices.

so if i want different images for iphone3, iphone4, iphone5 the config will select iphone3 / iphone4 and load correct image and if i want a different image for iphone5 i will need to detect the iphone5 and switch to that image in my code?

Corona deals with dynamic scaling so that your iPhone 3 can use a lower resolution image than your retina iPhones.  So yes, if you don’t have the ability to use backgrounds that have bleed areas, then yes, you need to test for tall devices and load in accordingly.

thx

Hi there, thanks for this! :slight_smile:

I am new to Corona, and I was wondering if anyone would be able to tell me why my background image isn’t scaling to the entire screen? It only takes up the top left corner of the screen instead of scaling to fit.

I used this config, and also it does same thing with the ultimate config. Here is my code (not sure if I need the set reference point code, I found it on one of the pages that talked about how to do dynamic image scaling). And, I made back.png 360x570px and I also have a back@2x.png and a back@4x.png like how the post on ultimate config describes.

Thanks in advance! :slight_smile:

[lua]

    local group = self.view
  

    local background = display.newImageRect( “back.png”, 360, 570 )    
    background:setReferencePoint( display.CenterReferencePoint )
    background.x = display.contentCenterX
    background.y = display.contentCenterY

    group:insert( background, true )
[/lua]  

Can you post a screen shot?  Are you seeing your entire image, just scaled down or are you only seeing the bottom right quarter of the image?

Can you post your config.lua too.