Corona SDK – Saving player score on server using PHP

tl;dr for the impatient, just download or clone this Github repository: https://github.com/arekzb/CoronaSDK-tutorial1

Corona SDK provides methods of sending data to a server via Lua sockets. It can use GET and POST
just as well, leaving it up to the developer to make the final decision. In addition to sending data,
retrieving the server generated response is convenient when it’s encoded in JSON format.

An example of a GET and POST request looks like this:

local query = "id=1&game=3&score=100"
local query2 = "id=1&game=2&score=100"
local serverUrl = "http://mygame.com/index.php/savescore/"

local getHTTP = serverUrl .. "?" .. query
-- GET request. There is no second body paramater
local body, code, headers = http.request( getHTTP )

-- POST example
local b, c, h = http.request( serverUrl, query2 )

If the server responds with a JSON format, just use json.decode()
on the response body:

local asJsonG = json.decode(body)

For the server side, we will use a simple PHP framework, accurately named Slim. Being a micro framework, it does just enough to get boilerplate code out of the way and allows us to define routes and handler functions as callables.
Example code presumes PHP >= 5.3 is used. We take advantage of anonymous functions and ‘use’ keyword for scope manipulation. In addition to the web framework, we use PHP Doctrine ORM as our database abstraction layer. It provides us with and object relation mapper and active record type system to access the database – MySQL in this instance.

Checklist:

  1. Check that your hosts file has the domain defined
  2. Check that Apache has the virtual host entry defined
  3. Check that there is a .htaccess file in the same directory as index.php file
  4. Check that the host name you chose and the host name inside the Corona application match
  5. Check that the credentials for the database inside bootstrap.php match
  6. Check that the database exists and necessary tables are present
  7. Check that you can load the test example at http://YOURDOMAIN/index.php
  8. Nice to have – use mod_rewrite to hide away the index.php from the URL

Request lifecycle
As soon as above Lua code is executed, an HTTP request is sent to the server. Slim PHP framework will parse the parameters and allow us to handle them according to application logic. First entry point in this example happens inside index.php, which simply loads the bootstrap.php file from the parent directory. The boostrap files and any other non publicly accessible files are hidden outside of the Apache document root for a reason. As soon as the application bootstrapping begins, we load the Slim framework, Doctrine, create a database connection and load our models.

//require framework files
require 'Slim/Slim.php';
require 'doctrine/lib/doctrine.php';
spl_autoload_register(array('Doctrine', 'autoload'));
$manager = Doctrine_Manager::getInstance();

//Le database and other goodies
$dsn = 'mysql:dbname=mygame;host=127.0.0.1';
$dbuser = 'letme';
$dbpass = 'in';
$dbh = new PDO( $dsn, $dbuser, $dbpass );

$dbcon = Doctrine_Manager::connection($dbh);

$dbcon->setOption('username', $dbuser);
$dbcon->setOption('password', $dbpass);

$manager->setAttribute(Doctrine_Core::ATTR_AUTOLOAD_TABLE_CLASSES, true);

Doctrine_Core::loadModels(dirname(__FILE__).'/models');

//Le web application
$app = new Slim();
$app->dbcon = $dbcon;

//URL paths and such
require 'routes.php';

//Le start
$app->run();

Models and database:
We have three tables in this sample application: user, score, game. We will allow one score per game, where game is treated more like a level inside a game. Table relations allow for a user to have one high score per game. Score table will hold the user id, game id and the high score. Game table holds ids and names of our levels and User will contain the
user id and name. Three PHP files are created by hand, to match this structure on Doctrine side. This will allow us to manipulate the tables using Doctrine object or query model. These three files are located inside the models directory.

Saving and retrieving data from database:
To retrieve data from database, point your application to http://YOURDOMAIN/index.php/testdb/ inside the browser. Slim framework will dispatch the matching callable, in this case the GET handler on line 11 inside routes.php. On line 16, we get all users using this piece of code $users = Doctrine_Core::getTable('User')->findAll(); Iterating over the result is as simple as using a foreach loop. On line 19, we can check of the User object has any scores associated to it: if( count($user->Scores) ), if so – we can loop over these and retrieve them further. This can be streamlined by using a leftJoin method, left out on purpose to show the relation flow between the tables.

PHP handler for Lua request:
On line 31, we have a Slim handler that will be dispatched when /savescore/ URL path is requested. It will answer to GET and POST request in the same way, because we used a generic route mapper $app->map('/savescore/' and defined the HTTP methods inside the ->via('GET', 'POST') section. Parameters are extracted from either type of request and passed on to function that handles saving the score using Doctrine object notation. In case of an exception, we return the unfiltered message back to Corona application.

Corona SDK – build automation

In my experience, Corona SDK build process has been a source of pain. It feels like it has been an afterthought thrown in on top of the authorization and remote build system. For those that don’t know, building the code takes place on Ansca’s servers and the process follows something along the lines of:

  1. Edit and save the source files
  2. Launch or keep the Corona simulator open
  3. Go to File -> Build -> Android (or press , Cmd + shift + b)
  4. Fill in Application name, Version, Package, Keystore, Key alias and save path settings
  5. Press build button

Repeat builds do save some time by remembering typed in values, but it’s a far cry from a one click build I would like have. Ideally, the application should be launched on the device at the end of the sequence.

To achieve this, I had to resort to using SikuliGUI automation and little bit of Python scripting. Following gist contains the code: https://gist.github.com/1257755 . Variables in the beginning point to the location of your project, terminal application and so on. Application specific data like name and version should be set there as well. The script will use Android adb tool to install and run the application at the end.

Paths inside the script are OSX specific, but changing them to work on Windows should be very easy.

What you will need: Python, Sikuli and the above gist. Here is a ready zip archive of the script and screen captures required to make it work: http://bayfiles.com/file/1613/LFNkUY/corona.skl

Here it is in action building the sample Clock application:

 

Corona SDK – build automation from Arek Bochinski on Vimeo.

Return of the Banff Squirrel

A Photo Bomber’s joyride,

Located at http://zenebo.com/sq.php is a small script I created to copy and paste the famous by now Banff Squirrel.

You can view a test for overlaying the squirrel on Google by clicking here: http://zenebo.com/sq.php?http://google.com

The initial news broke out on http://reddit.com with us making the script for overlaying The Squirrel on any website by the end of the day. What happened next was a rollercoaster of traffic and squirrel buzz. We had a 4,000 % traffic spike as a result of increased demand for Squirrel LOLs . Other websites have used our image crop, located here http://zenebo.com/images/squirrel.png or simply followed suit in joining this fun activity of Photo Bombing a website.

Overall, we are happy to provide a few laughs and please remember to watch out for squirrels when you set that photo camera on a timer and strike a pose.

Esenthel Engine

Esenthel is an overachieving project that delivers a punch with minor developer effort. After trying out many game engines and rendering engines, I have learned to approach each with a certain grain of skepticism. Not because of the lackluster quality of most cheap, err. free engines. It’s a defense mechanism we engage in when learning principles of 3D, game development and overall story boarding is paramount to propping up a limping or incomplete development environment.

I have to say , with utmost respect , that it is by far one of my favorite pieces of software I have tried this year.

It delivers on most promises, encourages code centric, instead of drag-and-drop development and does it with ease.

I am getting ready to deliver a small demonstration game and post the code live.

Until then, check out more of the Esenthel Engine here.

Other mentions go out to OGRE Graphics Engine , C4 Engine , Irrlicht Engine , Unity 3D as some of many tried and tested , very good alternatives that almost suit my development style.

I would like to add that Valve Software’s Source Engine is still my favorite despite having only modded with it.

Overall, I feel very comfortable thinking grande for the first time when writing a non-mod . Esenthel might bring my mini-game idea to fruition.

Cheers,

Arek Bochinski

Reverse complement FASTA benchmark

FASTA format is used in bioinformatics to describe peptide sequences or nucleic acid sequences.

One of the benchmarks at the computer languages game requires that a program parse a ‘stdin’ redirected input of these FASTA formated sequences and print the content of the sequence in reverse order. Each character in the sequence should also be complemented according to this translation table:

code  meaning   complement

A    A                   T
C    C                   G
G    G                   C
T/U  T                   A
M    A or C              K
R    A or G              Y
W    A or T              W
S    C or G              S
Y    C or T              R
K    G or T              M
V    A or C or G         B
H    A or C or T         D
D    A or G or T         H
B    C or G or T         V
N    G or A or T or C    N

Headers

Each sequence contains a header with an id and description. These lines are printed ‘as is’ .

Challenges

  • String reversal
  • Translation table substitution
  • Input handling and memory allocation

String Reversal

Sequences are reversed using a bitwise XOR and without using a temporary character or string buffers.

Operations are performed in a loop where forward is the first index and end is the last index in the sequence.

buffer[forward]^=buffer[end];
buffer[end]^=buffer[forward];
buffer[forward]^=buffer[end];

Translation table substitution

A small character array of complement values is created and accessed with the integer value of the source character matching to arrays index. For example:

buffer[end]=FtoCOMP[buffer[end]];

Buffer at index end will receive a character at index ‘buffer[end]‘ from translation table array FtoCOMP. Index ‘buffer[end]’ translated to an integer , will point to a desired complement . This speeds up the process of substitution and allows for very fast array index notation.

Input handling

The requirement to handle input one line at a time corresponds quite well to the translation procedure. In pseudo-code,

  • process one line at a time
  • for each sequence , print header line, reverse the sequence, translate it into its complement and print it out

Only one buffer is used as a destination for reading input. Beginning pointer where each line is placed is dictated by moving a pointer through a character array. Once a line is read in, we check if it is the last line in a sequence by peeking into the input stream. If it is , it is processed according to above instructions and beginning pointer where the next line is placed is reset to 0.

These functions are called for each line N in the input stream:

fgets_unlocked, fgetc_unlocked.

These functions are called for each line that’s not a header line:

ungetc, strlen.

Other functions are called only at the end of a sequence and do not approach N runtime. This version written in C language has been compiled and tested using kernel 2.6.24 with GCC 4.2.3 .

Compile command:

gcc -Wall -O3 -fomit-frame-pointer revc.c -o revc.gcc_run

Source code is located here: http://zenebo.com/revc.c.tar.gz

Atoi() or not to Atoi()

Update: May 13th, 2008

My solution has been accepted and placed in the interesting alternative category. A bitter-sweet victory considering my program as tested by their standards is the fastest C language entry . It is still a small honor to be recognized and to know that my entry shaved off almost 30% off the next fastest C program.

Let’s see how the FASTA benchmark program stacks up in the next few days.

Cheers.

see it here: http://shootout.alioth.debian.org/gp4/benchmark.php?test=sumcol&lang=all

The computer language benchmarks game at http://shootout.alioth.debian.org/gp4/index.php matches up a fundamental processing task or algorithm in a variety of programming languages. One benchmark called ‘sumfile’ has the following requirements:

  • read integers from stdin, one line at a time
  • print the sum of those integers

It is based on this icon program:

procedure main(argv)
 sum:=0
 while(sum+:=read())
 write (sum)
end

The C language entry topped at 6th and 7th place. Surprising as it was, a Java 6 version came in second with more than a second shaved off the total CPU running time.

The task for all of these is to read a flat file containing one integer per line, add the integer to the total and print out the sum at the end. Three versions of test files containing 1,000, 11,000 and 21,000 lines are used. While there could be more interesting ways to tackle this task, it’s trivial and simple demands warranted a quick look.

The fastest C program used these function calls per each line in the file:

fgets_unlocked() , atoi() and a += operator to sum up the total. It seems that either one of these functions could be improved on, but since line-by-line reading is a strict requirement thus leaving the atoi function open to critique.

This following function will return an integer given a string. It handles positive and negative number strings.

int matoi(char *c) {
int res = 0,n=1;
if(*c=='-'){n=-1;*c++;}
while (*c >= '0' && *c <= '9')
res = res * 10 + *c++ - '0';
return res*n;

}

When compared to the standard atoi() function and parsing 500,000 lines of integers, this version on a 2.4 GHz Core2Duo performed 60% better . It’s simplicity is also it’s weakness as the matoi() function is designed to handle proper input. Perfect for a situation where input is controlled.

Original benchmark entry was modified with timing capture and the addition of matoi() function. Header contains any previous entry owners and information.

Archive with source code : http://zenebo.com/sum1.c.tar.gz