Get the source: Automata on Github
Every once in a while I like to engage in some wildly impractical coding experiments. You know the sort, the “Hey, I got Gentoo running on my toaster!” stuff. Today’s experiement was implementing Conway’s Game of Life using nothing more than Appcelerator Titanium views and deploying it to iOS. Let me explain a bit more why this is a ridiculous idea…
Why It’s A Bad Idea
So Not What Titanium Is Built For
Titanium makes high-quality, cross-platform mobile applications leveraging native UI and functionality. It does exceptionally well with data-driven apps that make heavy use of the underlying mobile platform’s own UI. It will win the app bake-off against any other cross-platform mobile framework there is, and often times native counterparts as well.
It is, however, not well-suited for any type of gaming. It is not a rendering canvas. It is not a game/particle engine. It has no standard render loop like you would expect in those aforementioned tools. Implementing any kind of graphical game-like experience is ill-advised. But sometimes ill can be a good thing. Just ask the Beastie Boys (RIP MCA).
Despite that fact, you should see what the Appcelerator-funded Lanica is doing with the Platino. Now there’s a game engine. Be sure to hit up Carlos Icaza, former co-founder/CEO of Ansca (makers of the Corona SDK), if you want more info about it.
But I digress…
Titanium Has Webviews!
Any normal person implementing this in Titanium would use a webview. Why? Because webviews, depending on the platform, actually have rendering facilities for these exact type of experiences. You could use an HTML5 canvas or even a WebGL surface to render this zero-person game, like I did with my experiment rendering 3D STL files on the web, just like Github.
Why It’s A Good Idea
Because writing code to see “what if” is what makes a hacker a hacker.
Automata
Here’s a test run of Automata on my iPhone Simulator (6.1) using Titanium SDK 3.1.1. As you can see, as the number of live cells dwindles, the speed increases drastically, as is to be expected. Despite it’s limitations, Titanium makes for a pretty cool demo of this game.
The Blood And Guts
In order to implement the Game of Life with nothing more than Appcelerator Titanium Views I needed to do the following:
Implement a crude render loop.
And by crude, I mean really crude, along the lines of:
1 2 3 4 5 |
|
This so far only plays well with iOS. The perpetual while loop seems to prevent the UI from updating on Titanium’s other supported platforms. Perhaps some toying around with setInterval
or other timing methods could alleviate this limitation.
Implement The Game Of Life Algorithm
I needed to execute the game in performance-conscious JavaScript. I’m sure someone can squeeze a little more performance out of this, but this section accounts for less than 1% of the actual execution time. It doesn’t really seem worth the time investment to push it further.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
Handle Titanium’s UI state
Titanium’s UI handling of each cell needed to be handled in an even more performance-conscious manner, as this is where over 99% of the execution time would eventually end up. The views are wrapped in a plain JS object in order to keep track of state and toggle the UI’s dead/alive rendering as infrequently as possible. The single cell.proxy.visible
assignment below accounts for over 99% of the total execution time on each loop. Future versions of Titanium are actually planning to make these “native bridge crossings” much faster. Automata can serve as a bar by which some of these improvements can be measured.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Final Notes
- Despite abusing Titanium to no end, it was still able to render the game.
- Titanium UI proxies are where the majority of execution time is consumed. This is true of all Titanium apps. It would be interesting to see if it was possible to make tweaks to the native bridge crossing to speed this particular app up significantly. (batching updates, custom APIs via modules)
- Changing
opacity
instead ofvisible
had no discernable affect on performance. - Creating the live cells on-demand, rather than all cells up front, resulted in slower performance. In this particular case, the initial overhead of creating all possible cells suits the app much better.
- I’m curious if anyone out there has any clever ideas for speeding this up. I’m all ears.
Resources & Links
- Source Code: https://github.com/tonylukasavage/Automata
- Carlos Icaza presenting Lanica’s Platino: http://player.vimeo.com/video/52802376
- Conway’s Game of Life: http://en.wikipedia.org/wiki/Conway’s_Game_of_Life