Trench Run

Codea Talk 2015 Christmas Competition entry

This was my entry for the Codea Talk 2015 Christmas Competition, which had a Star Wars theme to celebrate the launch of The Force Awakens. It only took a day or two to put together, as I already had the .OBJ importer code and the wireframe shader ready, and the models all came from BlendSwap (please see credits below), and had fairly minimal processing in Blender before exporting them as .OBJ files.

The Stormtrooper helmet was the only model I simplified, by reducing the number in the subdivision surface modifier. For some reason the texture for the helmet appears to be inside out—all the stylings are on the inside of the helmet. But it’s still a fantastic model.

Into the trench

These models are way more detailed than ones that you’d use in a game, but I thought I’d try to put them into a simple game like the old trench run arcade machine, with gyroscope tilt steering. Although the frame rate does dip when there are lots of tie-fighters on screen, it’s surprisingly playable.

I added the wireframe mode for the true old-school feel. It’s an unlockable bonus if you do well in the game. Interestingly, the wireframe mode performs better than the diffuse lighting shader. Although this does kind of make sense if you think about it, as lots of fragments are being discarded rather than drawn, Apple GLES guidelines warn about potential performance issues with discard operations.

I think the wireframe looks great. It’s a really interesting aesthetic that you don’t really see at all in contemporary gaming. I wonder whether there’s some game concept out there that could use the wireframe style in a well-integrated way, and not just as a gimmick, or an easy way of evoking a retro feel.

The full source code is available here. The easiest way to get the code into Codea is to use this installer:

Trench Run Installer

local url = ""

local function install(data)
    --parse plist into list of tab files
    local array = data:match("<key>Buffer Order</key>%s-<array>(.-)</array>")
    local files = {}
    for tabName in array:gmatch("<string>(.-)</string>%s") do
        table.insert(files, {name = tabName})
    --success function
    local function success(i, name, data)
        if not data then alert("No data", name) return end
        print("Loaded "..i.."/"..#files..":"
        files[i].data = data
        for i,v in ipairs(files) do
            if not then 
                return --quit this function if any files have mssing data
        --if all data is present then save...
        for i,v in ipairs(files) do
            print("Saved "..i.."/"..#files..":"
        for i,v in ipairs(files) do --load...
        setup() --and run
    --request all the tab files
    for i,v in ipairs(files) do
        http.request(".lua", function(data) success(i,, data) end, function(error) alert(error," not found") end)

http.request(url.."Info.plist", install, function (error) alert(error) end)

Model Credits


Stormtrooper Helmet

Tie Fighter

Built with Jekyll      © Salt Pig Media