@abridgedun,
I sense the wrong attitude. It seems like you want a universal answer to be provided to you without putting in the effort to learn about how this stuff works.
First, I suggest you make a simple app that puts a few shapes and images on the screen.
Second, read about and experiment with config.lua settings till you understand them.
Third, settle in on a configuration that meets your scaling needs.
Fourth, Now worry about things like virtual cameras. You’re jumping the gun trying to figure out a semi-complex concept like a virtual camera when you don’t even understand design-space vs true screen resolution and the ramifcations of auto-scaling.
By the way, these topics are pretty simple, but you’ve got to spend the time. The staff and community at large have put in a lot of effort to document, discuss, and give examples of content scaling (specifically focused on config.lua). You simply need to look for it, read it, and experiment with it. Useful experience is sometimes hard-won.
I must admit I am a bit offended by your leading statement, “Love Lua; Corona’s okay”. It’s like saying, “Hey guys, I think Corona kinda sucks, but don’t mind that. Just spend your time packaging up a universal solve-all answer and give it to me ok!” Now, if you’d said, “Corona’s OK, and here is why I think so…vast experience list follows…” then I might not be so irked. 
Lastly, you’re certainly still welcome here, so take this semi-rebuke with a grain of salt (or a little sugar). Corona is an excellent API, but you’ll have to invest some effort in it. The more you invest, the more you will be rewarded.
Best of luck to you, and to show I’m not a bad guy, here is a very simple camera:
local centerX = display.contentCenterX local centerY = display.contentCenterY local isDisplayObject = function ( obj ) return( obj and obj.removeSelf and type(obj.removeSelf) == "function") end -- == -- fixedCamera() - Follows target exactly. -- == local function fixedCamera( trackObj, layers, params ) if( not isDisplayObject( layers ) ) then return end params = params or {} local lockX = params.lockX local lockY = params.lockY local centered = fnn( params.centered, false) local lx = 0 local ly = 0 if( centered ) then if( lockX ) then lx = trackObj.x else lx = centerX end if( lockY ) then ly = trackObj.y else ly = centerY end else lx = trackObj.x ly = trackObj.y end layers.world.enterFrame = function( event ) if( not isDisplayObject( layers ) ) then return end if( not isDisplayObject( trackObj ) ) then return end local dx = 0 local dy = 0 if(not lockX) then dx = trackObj.x - lx end if(not lockY) then dy = trackObj.y - ly end if(dx or dy) then layers.world:translate(-dx,-dy) lx = trackObj.x ly = trackObj.y end return true end Runtime:addEventListener( "enterFrame", layers.world ) end
This is how you would use the above code:
local layers = display.newGroup() layers.world = display.newGroup() layers.underlay = display.newGroup() layers.overlay = display.newGroup() layers.content1 = display.newGroup() layers.content2 = display.newGroup() layers.content3 = display.newGroup() layers:insert(layers.underlay) layers:insert(layers.world) layers:insert(layers.overlay) layers.world:insert(layers.content1) layers.world:insert(layers.content2) layers.world:insert(layers.content3) -- Display groups are now layerd(bottom-to-top): -- underlay, world, content1, content2, content3, overlay -- -- Place ground tiles in layers.content1 -- Place 'cloud' tiles in layers.content3 -- Place player object and other objects in layers.content2 -- Place interface elements in layers.overlay -- Place Static backgrounds in layers.underlay --Ex: local player = display.newCircle( layers.content2, 10, 10, 20 ) fixedCamera( player, layers, {} ) --Alt: { lockX = true } lock horizontal movement
You’ll have to experiment from here to learn more about cameras.