Pygame Zero, a zero-boilerplate game framework for education

Pygame Zero (docs) is a library I'm releasing today. It's a remastering of Pygame's APIs, intended first and foremost for use in education. It gives teachers a way to teach programming concepts without having to explain things like game loops and event queues (until later).

Pygame Zero was inspired by conversations with teachers at the Pycon UK Education Track. Teachers told us that they need to be able to break course material down into tiny steps that can be spoon-fed to their students: our simplest working Pygame programs might be too complicated for their weakest students to grasp in a single lesson.

They also told us to make it Python 3 - so this is Python 3 only. Pygame on Python 3 works [1] already, though there has been no official release as yet.

A Quick Tour

The idea is that rather than asking kids to write a complete Pygame program including an event loop and resource loading, we give them a runtime (pgzrun) that is the game framework, and let them plug handlers into it.

So your first program might be:

def draw():
    screen.fill('pink')

That's the complete program: screen is a built-in and doesn't have to be imported from anywhere. Then you run it with:

pgzrun my_script.py

Image loading is similarly boilerplate-free; there are a couple of ways to do it but the one we recommend:

# Load images/panda.png (or .jpg) and position its center at (300, 200)
panda = Actor('panda', pos=(300, 200))

def draw():
    screen.clear()
    panda.draw()

More appropriate to sounds and static images, the images/ and sounds/ directories appear as built in "resource package" objects:

def draw():
    screen.blit(images.background, (0, 0))

def on_mouse_down():
    sounds.meow.play()

We use introspection magic to call the event handlers in the script with whatever arguments they are defined to take. Each of the following will "do the right thing":

def on_mouse_down(pos):
    print("You clicked at", pos)
def on_mouse_down(button):
    print("You clicked the", button.name, "mouse button")
def on_mouse_down(button, pos):
    print("You clicked", button, "at", pos)

Batteries Included

Pygame Zero is also useful for more seasoned developers. Though the APIs have been designed to be friendly to novices, they also help you get up-and-running faster with a larger project. The framework includes a weakreffing clock, a property interpolation system, and a built-in integration of Christopher Night's pygame-text. These are the kinds of things you want in your toolkit no matter how expert you are.

It's not hard to "reach behind the curtain" into Pygame proper, when you outgrow the training wheels offered by Pygame Zero.

Portable and distributable

I've discovered in previous Pyweeks that sticking to Pygame as a single dependency is just the simplest way to distribute Python games. OpenGL may offer better performance but users frequently encounter platform and driver bugs. The AVBin used by Pyglet has been buggy in recent Ubuntu versions. So Pygame gives much better confidence that others will be able to play your game exactly as intended.

Pygame Zero has been built to constrain where users store their images, sounds and fonts. It also disallows them being named in a way that will cause platform portability problems (eg. case sensitivity).

Hopefully this will help schoolkids share their Pygame Zero games easily. I'd be interested in pursuing this to make it even easier, for example for users without Python installed, or with a hosting system like a simplified pip/PyPI.

Contributing

I'd welcome your feedback if you are able to install Pygame Zero and try it out. It is, of course, on my Bitbucket if you would like to submit pull requests. If you would like to get involved in the project, writing easy-to-understand demos and tutorials would be much appreciated; or there's a short feature wishlist in the issue tracker.

[1] There's a bit of a showstopper bug in Pygame for Python 3 on some Macs - but not reproducable on the Mac I have to hand right now. If anyone can help get this fixed it would be enormously appreciated.

Comments

Comments powered by Disqus