Corona Quick Thought – meta tricks, example: user data

Uh oh, you know you’re in for trouble when the first thing is a disclaimer: This is meant to demo a *technique*, not necessarily a practical application of that technique, fair?

This was motivated by a brief discussion with @PANCSoftware. It may or may not be even close to what he’s trying to achieve, but it seemed something worth demonstrating anyway.

HERE IS THE SOURCE if you’d like to follow along. I don’t plan on writing a whole lot about the code, comments are there for those interested enough to study it. (‘cuz if not interested enough to study it, then no point in me writing at length about it, right?)

What the code is intended to demonstrate is a metamethod whereby a containing class can serve as proxy for several different data categories and keep track of them all in a manner transparent to the end-user (aka developer).

(This will likely seem trivial nonsense if you’re coming here as a Lua expert. On the other hand might seem like black magic if you’re coming here as a typical Corona newbie. So the intended audience is somewhere in the middle of those two extremes.)

The scenario is a game’s user-data. Games often have two distinct categories of data:

  • Temporary/Transient “in game” data, for example current score
  • Permanent/Persistent “on disk” data, for example high score
  • (and of course there are others, like music/sound settings that might need to persist, etc)

    The technique used here is to provide a “prototype” to the class, indicating which properties are intended to be temporary and which are persistent. The class is agnostic – it doesn’t really know or care anything about your user data, other than what you “tell it” via the prototype.

    The class then hides those details from you and provides “simple” access to those properties, for example userdata.score and userdata.hiscore. Internally those are stored separately, so that when it comes time to serialize to disk, the class “knows” which properties to include.

    Take a look at the code if interested, that’s all for now. I may expand upon this in the future, maybe provide some code walk-through or etc, if seems needed.

    Corona Quick Thought – “cheap” antialiased lines

    “Cheap” as in “it will work with Starter”. 😀 (on the other hand, if you have a Pro+ subscription, then you have access to other alternatives)

    I was motivated to share this by a conversation started here, in the forum. Hope it’ll be helpful to someone somewhere.

    One of the less-than-pretty things about Corona is that vector geometry is rendered aliased (those “jaggy edges” arising from not antialiasing .. and i will not antiapologize for using double-negatives).

    But there are workarounds that might be suitable in certain instances, particularly if it’s just single line segments you’re after..

    bitmap_lines_sample_output_zoomThose are 2X pixel zoom crops from actual output, vector lines on the left, bitmap lines on the right. Which do you prefer? (or click below for full image at 1X if you’d rather)

    The “trick” used here is to create the line segments using pre-rendered bitmaps. Bitmaps do render antialiased due to the bilinear texture sampling that occurs.

    The bitmaps are just a single-pixel-wide portion of a line with the desired stroke width. (height of the bitmap is just whatever is necessary to fit the designed stroke width) For example, at left is a 4px stroke in a 1x8px bitmap, magnified 40X, against dark magenta to reveal transparency.

    I’ll keep this short for now.. here’s a functional demo with code you can experiment with.

    Look for the function named newBitmappedLine() within, read its docs, then see how used in the demonstration code later on.

    Corona Quick Thought – performance: use native methods whenever you can

    I recently saw a Corona tutorial of the painter’s algorithm, where the author demonstrated how they had depth-sorted their sprites by screen y-coordinate in order to simulate depth in 2D.

    The effect works well, but I was surprised to see that the author had implemented their own insertion sort in pure Lua rather than rely on Lua’s built-in table.sort() (a quicksort implementation).

    (I’ll avoid mentioning where to find that tutorial, lest this seem like my intent is just to criticize that work, ‘cuz it isn’t. I’ll try to use it as a case study for a general principle, while trying to avoid nitpicking it as a specific case. Unless that author wants a link back, then sure, just let me know! Fair?)

    I won’t delve into comparing the merits of various sort algorithms (much), except to say that the choice of an insertion sort was probably a good one. If the number of sprites is relatively small, and if they remain “mostly” sorted from frame to frame, then those are nearly ideal conditions for an insertion sort.

    However, …, it’s really hard to beat native code! Especially on a mobile device. If there’s an existing library routine that already does something, you are almost always better off using the built-in rather than rolling your own with interpreted Lua. Even if the built-in isn’t quite a perfect “fit” for your usage. (only in an extreme case with a known-optimal solution might you “win” via interpreted code versus a more generic solution in native code)

    The example here is that a somewhat-less-than-optimal-quicksort in native code is going to beat the pants off (aka orders of magnitude) even a more-optimal-insertion-sort if in interpreted code. Even with a relatively small list (50-ish sprites or so?), and even if already mostly sorted. (and certainly even moreso in general cases where those ideal conditions for an insertion sort aren’t met, giving the advantage to quicksort anyway)

    You can apply this principle across the board, whenever/wherever possible. For example, it’s not uncommon to see “tedious” string parsing being done with interpreted Lua that could have been accomplished so much more efficiently via string.gsub() and/or string.find(). Granted that Lua’s pattern-matching syntax can seem a bit “obscure”, but it’s well worth the time to learn the libraries.

    And performance is not the only issue here. The Lua libraries have been battle-tested, so usually there’s no concern about the “correctness” of the implementation – you can just rely on it working. Huge time saver, why reinvent the wheel?

    Back to sorting, let’s whip up an example for those who might not be familiar with table.sort().

    table.sort() can work directly on a list of atomic values (numbers, strings), or can accept a comparison function to deal with a list of arbitrary table (aka an “object” in typical usage) values having sortable properties within. (a comparison function can also be used to handle primary-secondary type sorts on multiple properties as well)

    (and for advanced readers, note that table.sort() can operate directly on a list of tables, provided they’ve got a metamethod for the less-than operator)

    A quick silly example just to illustrate some various bits:

    Corona Quick Thought – more Windows simulator skins

    I mentioned elsewhere how you can customize the list of available devices in Corona’s Windows simulator.

    I also mentioned elsewhere some reasons why you might want to do so, for example: taking screenshots at various resolutions.

    (I suppose this mainly applies if you have a fast action -type game where taking screenshots on-device would be tricky to capture the exact moment you were after. For a slower-paced app it’s easier to just capture from device.)

    Another handy little trick is to take your screenshot at double the intended resolution, then resample it down to improve the antialiasing. The Windows simulator doesn’t do nearly as good a job rendering as an actual device, so this trick will yield far better quality screenshots. So, for example, let’s say you need 800×1280 images for Google Play, you’d run a 1600×2560 simulated device… um, except that there isn’t one… unless you do it yourself… so…

    HERE is collection of 45 “generic” android devices (that is, no frame image and not intended to directly mimic any specific real-world device, just their resolutions) in a wide range of standard resolutions.

    You probably will not want to use all of them, or your “View As” menu will become enormous! 😀 In particular, there a half-a-dozen or so very low resolution ones that are of very little use, since any phones out there with those resolutions (fe Samsung Galaxy Spica??) probably have too old an OS to run Corona apps anyway – they’re provided mainly just for completeness (and silliness).

    The most useful ones are probably 1600×2560 (WQXVGA) as discussed above, and those that match iOS resolutions, but also includes the full list of resolutions cited in the Android docs for testing.

    So pick the several that seem useful and copy them into the \Program Files (x86)\Corona Labs\Corona SDK\Resources\Skins folder. (typically, your install location may vary, and you’ll likely need administrator rights to do so) Then restart the simulator.