Feb. 25, 2011

Cool, I just broke my previous record for number of commits to the Infinite 8-bit Platformer codebase in one month! 40 commits and there are still 5 days left in February.

Infinite 8-bit Platformer commits graph for February 2011

The good news is that I think this baby is almost ready for beta-release candidate one. With just 6 items left in the TODO list, I'm getting very excited!

Infinite 8-bit Platformer screenshot for version 252 February 2011

(Perhaps the kind reader and Infinite 8-bit Platformer fan will overlook the previous three months of childbirth related decompression in which not a single commit was made. :] )

"It's done, when it's done." -- John Carmack

Sept. 26, 2010

CanOfBeats running on Android

There's a good reason I haven't been posting many squeakyshoecore tunes lately, or making much progress on my video game Infinite8BitPlatformer. I've been hacking hard in my spare time, and the good news is that CanOfBeats, my algorithmic hiphop beat generator, is now available for Android phones and devices! So if you are seeking beats and you rock an Android phone, help an indie developer out and get yrself a copy from the Android Market.

Enjoy!

Sept. 12, 2010

Hello!

Here is the build script which I use for deploying my apps such as Infinite8BitPlatformer on Windows and OSX. I have used it to build both Pygame and wxWindows apps in the past. "Cross platform" might be a bit of a misnomer; you need to run it on the environment you are targetting (e.g. be on Windows to build for Windows) and have the correct environment, libraries etc. installed, but the same script should work on both platforms.

For notes about installing Python libraries into somewhere other than the default Python root directory, see this earlier post.

Please pay attention to the comments marked NOTE.

### Cross platform (win32, mac) build script
### By Chris McCormick <chris@mccormick.cx>
### This has worked with pygame and wx
### This script is public domain

from setuptools import setup
from sys import platform, argv
import os
from shutil import rmtree, copytree
import zipfile

# NOTE: you may want to change these next few lines to set these values manuall
# get the current bzr version number of this build
from bzrlib.branch import Branch
revno = Branch.open(".").revno()
# get the name of the project/app from the name of the current directory
app = os.path.basename(os.getcwd())

# remove the build and dist directories
def clean():
    print "Removing build and dist directories"
    for d in ["build", "dist"]:
        if os.path.isdir(d):
            rmtree(d)

clean()

# the default os string and extension for each platform
platforms = {
    "darwin": ("osx", ".app", "dist/" + app + ".app/Contents/Resources"),
    "win32": ("windows", "", "dist"),
}

# more convenient representation of the platform config
config = {
    "os": platforms[platform][0],
    "extension": platforms[platform][1],
    "resources": platforms[platform][2],
    }

# NOTE: this is optional, you might want to remove this bit
# output the correct VERSION file for this build
print "Writing VERSION file"
version_file = file(os.path.join("resources", "VERSION"), "w")
version_file.write("%s\n%s\n%s\n" % (revno, config["os"], config["extension"] + ".zip"))
version_file.close()

### PLATFORM SPECIFIC SECTION ###

# mac osx
if platform == "darwin":
    # add mac specific options
    options = {
        # NOTE: you may want to put other libraries in here, such as wx for wxWindows apps
        # some libraries need forcing
        'includes': ['simplejson', 'pygame'],
        'resources': ['resources',],
        'argv_emulation': True,
        'iconfile': 'resources/icon.icns',
        'semi_standalone': False,
    }

    # force the py2app build
    argv.insert(1, "py2app")

    # setup for mac .app (does the actual build)
    setup(
        setup_requires=['py2app'],
        app=[app + ".py"],
        options={'py2app': options},
    )
elif platform == "win32":
    import py2exe

    # hack to include simplejson egg in the build
    import pkg_resources
    # NOTE: this bit is manually copying the simplejson egg into the current directory
    # you may want to manually import other libraries here
    # some libraries need forcing like this
    eggs = pkg_resources.require("simplejson")
    from setuptools.archive_util import unpack_archive
    for egg in eggs:
        if os.path.isdir(egg.location):
            copytree(egg.location, ".")
        else:
            unpack_archive(egg.location, ".")
            rmtree("EGG-INFO")

    # windows specific options
    options = {
        "script": app + ".py",
        # NOTE: assumes your icon is in a folder called resources and is called 'main.ico'
        "icon_resources": [(1, os.path.join("resources", "main.ico"))],
    }   
    resources = ['resources',]

    # force the py2exe build
    argv.insert(1, "py2exe")

    # setup for windows .exe (does the actual build)
    setup(
        setup_requires = ['py2exe'],
        windows=[options],
    )

    # manually copy resources as I couldn't get it to happen with py2exe
    for r in resources:
        print 'Copying resource "%s"' % r
        copytree(r, os.path.join("dist", r))

    # get rid of simplejson directory
    # NOTE: if you manually forced other libraries above you'll probably want to remove them here
    rmtree("simplejson")

### PLATFORM SECTION DONE ###

# zip up our app to the correctly named zipfile
def recursive_zip(zipf, directory, root=None):
    if not root:
        root = os.path.basename(directory)
    list = os.listdir(directory)
    for file in list:
        realpath = os.path.join(directory, file)
        arcpath = os.path.join(root, file)
        print "Zipping:", arcpath
        if os.path.isfile(realpath):
            zipf.write(realpath, arcpath)
        elif os.path.isdir(realpath):
            recursive_zip(zipf, realpath, arcpath)

outfilename = "%s-%d-%s%s.zip" % (app, revno, config["os"], config["extension"])
zipout = zipfile.ZipFile(outfilename, "w")
recursive_zip(zipout, os.path.join("dist", platform == "darwin" and app + config["extension"] or ""))
zipout.close()

# clean up afterwards
clean()

# output the build-finished message
print "--- done ---"
print "Created %s" % outfilename

You should probably use Esky instead of this script.

July 31, 2010

I am ridiculously behind on blogging because of the amount of contract work I have going on at the moment (working Saturdays and weeknights until 2am - not fun!) Anyway, I'll stop whining now.

Below is a video of the talk I gave at PyCon AU at the end of June. In it I talk about my time working for London based "reactive music" company, RjDj, and also about my video game Infinite8BitPlatformer.

I haven't posted an Infinite8BitPlatformer update for ages, and I have been meaning to do so since a lot of progress has been made since my last post, but here's a quick update:

  • Multiplayer code: this is going really well. It's almost at the point of beta release.
  • Contributors: another person has started contributing to the codebase. I am hopefully going to be merging his code this weekend. Julian has put basic chat into the multiplayer code, among other tweaks and bugfixes, and a huge amount of very useful information for other people looking to contribute. He's been very patient about my lack of time!

Anyway, back to work.

April 24, 2010

I am taking part in the Ludum Dare #17 48 hour game challenge this weekend, and hence taking a bit of a break from Infinite8BitPlatformer programming this weekend. Follow me on the competition blog if you're interested! I will be releasing all of the sourcecode from my game at the end of the competition.

Incidentally, I have fixed up many of the Infinite8BitPlatformer bugs that were reported during the pre-alpha, and had some more great contributions from Crispin, such as a spray-can tool for in-game editing and some fun levels. Also last week I finished a bunch of tweaks, features, and bug fixes on the PodSixNet code, so next on the agenda is the multi-player code. Hopefully I'll be able to fit that in around the contract work I have on next week. Exciting stuff!

Anyway, back to the competition.