Packaging a Python game for distribution on Windows — py2exe and cx_Freeze

I do my game development on Ubuntu Linux. In case you hadn’t noticed, unlike pretty much every Linux distro, Windows does not come with Python installed by default. For distributing games written in Python on Windows, it’s nice to create a compiled executable version (using py2exe or cx_Freeze, for example) that can unzipped or installed with two or three clicks, without requiring a separate Python installation. Gamers will typically give up if they have to go on a wild goose chase to install Python, Pygame and maybe something else just to get your lame game to run. (Hey, that gives me an idea for a great game – “Software Dependency Wild-goose Chase”. Actually, it would probably be un-fun. Scrap that idea.)

Obviously, the first thing to do is install Python and all the required dependencies (eg Pygame, etc) on a Windows box (or Virtual Machine) and make sure your game will actually run. If it won’t run, you may need to tweak your Python to be more cross-platform. For simple games this mostly boils down to making sure all the sys and os module calls that use file paths use os.path to manipulate the path strings, rather than string concatenation. Paths in Linux use a forward slash “/”, paths in Windows use a backslash “\”, and some other platform may do something else; os.path deals with all this for you. I went through this process withshoodar (v0.11) and got it running under Windows with all the dependencies installed (eg Pygame, PyOpenGL, Rabbyt 0.81).

Now comes the ‘fun’ part – building the executable (and collecting associated dll’s and data files) for your game. There are a few tools for doing this on Windows:

Freeze

Comes with Python, but I didn’t test it.

cx_Freeze

cx_Freeze — I got this working to create a Windows distribution of shoodar after a bit of playing around. One advantage is that it doesn’t require a dedicated distutils script like py2exe. A downside is that it seems to generate lots of files in addition to the executable, and doesn’t automatically know to copy over data directories containing sprites & sounds, etc. You need to remember to do that part manually.

I downloaded the Windows installer for cx_Freeze (cx_Freeze-4.0b1.win32-py2.5.exe) and installed it. I unzipped the shoodar source into a folder called shoodar. In the shoodar source directory, I created a folder called dist. Then, at the Windows command prompt, in the shoodar folder, I typed:

c:\Python25\Scripts\freeze --install-dir dist shoodar.py

I then copied the shoodar\data folder into the dist folder.

The brand spanking new shoodar.exe executable was in the dist folder. It ran, and appears to function correctly.

py2exe, with PyMikes PySetup.py

py2exe — seems to be the most popular choice among Pygamers. There are a few wrapper scripts floating around at pygame.org.

The py2exe tutorial gives a nice example of how it’s done using a simple distutils setup.py script. I used py2exe with PyMike’s PySetup.py script. The PySetup.py script is a distutils setup.py script on steroids, tailored for packaging up Pygame games. It also worked for packaging shoodar, which also uses Rabbyt 0.81 (and hence PyOpenGL) without any special tricks.

I edited the obvious stuff at the top of the PySetup.py script in the shoodar directory (This included adding data, the directory which contains shoodars sprite files, to the extra_data list. I set dest_folder to the empty directory dist. I also added pygame.locals to the extra_modules list, but I probably didn’t need to. I left icon_file empty, since I don’t have an icon yet).

In the shoodar folder at the command prompt, running:

c:\Python25\python.exe PySetup.py

did the trick. Py2exe doesn’t generate nearly as many files as cx_Freeze … not that it’s really a big deal, but it looks less overwhelming in the file manager.

I had one problem with some (apparently) Linux specific code .. the use of os.path.dirname(__file__) which I changed to os.getcwd(). It’s worth noting that even after fixing this bug, py2exe builds failed until I removed the build (generated by py2exe) and dist directories and started with a clean slate. So, I’d suggest removing the build directory and the dest_folder between py2exe build attempts.

Next episode: Wrapping up the distribution in an executable Windows installer package (or How to make an evil “next”->”next”->”next”->”Finish” Windows installer for a Python game).

10 Responses to “Packaging a Python game for distribution on Windows — py2exe and cx_Freeze”

  1. One thing I’d really like is to be able to generate a Windows binary without actually using Windows … eg running under Wine or some other solution.

    It sounds like a few people have tried to get py2exe going under Wine without success, although I heard a few Ludum Dare participants mention a tool called PyInstaller ( http://pyinstaller.python-hosting.com/ ) which apparently will work running under Wine. I’m yet to try it myself, but it looks promising.

    Reply
  2. Nicolas

    This may be irrelevant but I bought a compaq computer in about 2006-2007 (I think) and it actually came with python preinstalled. I think it was version 2.3.

    Reply
  3. Yeh, it is sort of irrelevant, since that is very rare to find an OEM Windows install with Python :) Can’t really rely on that if you want more than 0.01 % of people to actually play your game.

    Still, it’s cool to see that Python has been preinstalled occasionally … sounds like Compaq could have been using it for something interesting in their bundled software ?

    Reply

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>