Introduction to pyprocgame
Gerry Stellenberg’s P-ROC became available today and I thought this would be a good time to write about the open source software that’s written to work with it. First, though, I want to talk about what P-ROC is and what makes it so cool.
What’s P-ROC (and Why)?
P-ROC is a circuit board that allows you to control a pinball machine using software on your computer. It’s basically a big digital I/O board with an FPGA at the center that connects to your computer (Mac, Windows, Linux) over USB. P-ROC replaces the CPU board in your pinball machine (or, if you’re making one from scratch, is the CPU board, in a sense) and connects to the switch matrix, the driver board and the DMD itself to provide complete control.
Before P-ROC, if you wanted to create your own pinball game with your own rules, you had to either:
- Learn to write assembly or rig up a C compiler to generate the requisite machine code and burn your own ROMs (essentially what the FreeWPC project is doing).
- Write code in a custom high level language designed for use on pre-DMD era 80’s solid state pinball games (such as Ni-Wumph). Or,
- Design your own architecture from scratch.
Frankly, none of those approaches sounded good to me. I don’t know enough about digital design (much less analog) to create my own hardware, I want to program DMD games, and I’m too big of a fan of higher level languages like Python and Ruby to want to spend all of my time worrying about managing code pages – plus it would be fun to have the option to fiddle with a functional language like Scheme or Erlang for pinball development.
Luckily for me, P-ROC fits the bill. You can imagine that I was pretty excited to find out about it several months ago. Having a few strong ideas about APIs and development tools, and coming from the perspective of someone who knew how he wanted to interact with this board, I made it my business to share my opinions on how the software should be organized. Several months later we have libpinproc, the C interface to P-ROC, and pyprocgame, a set of Python classes built on top of libpinproc that provides a very nice – if I do say so myself – framework for programming a pinball machine.
What pyprocgame Code Looks Like
Let’s just get right to some overly simplistic demo code:
class AttractMode(Mode): def sw_startButton_active(sw): self.game.coils.troughEject.pulse(20) def mode_started(): self.game.lamps.startButton.schedule(schedule=0xff00ff00, cycle_seconds=0, now=False) def mode_stopped(): self.game.lamps.startButton.disable()
You wouldn’t actually write code like this in a real game, but it demonstrates a few of the unique properties of pyprocgame:
- Mode class-based architecture. Essentially stackable state machines running in your game. A mode can be as simple as managing state for one shot, or as complex as an entire multiball mode. We leave it up to you.
- Easy handling of switch events. Define your switches in a common configuration file, then just add appropriately named methods to your Mode subclass. No need to define a constant, register a handler, etc. pyprocgame even makes more sophisticated switch events, like responding to a switch only after it has been in a certain state for a period of time, really simple:
sw_startButton_inactive_for_500ms(sw):. pyprocgame handles the busywork of this kind of stuff for you.
- Easy access to game hardware elements like coils, lamps, and switches. The game-specific configuration file you load sets everything up.
The reason you wouldn’t write code like the above in a real game is that in reality modern pinball machines are pretty sophisticated systems. The trough eject call, for example, would likely be much more complicated in a real game (Is there a ball in the trough to eject? Is there already a ball in the shooter lane?). That’s why pyprocgame includes several generic mode classes to help out. Ball search and ball trough helpers, drop targets, service mode, DMD score displays, high score entry, and so on. We’ve also coded up a nice set of support classes for working with the DMD: fonts, animated layers, etc. There’s even great support for setting up your own lamp shows.
You can learn about the details of programming pinball machines with pyprocgame here: pyprocgame Overview. It’s a work in progress, but a lot is there already. And of course, also on GitHub, is the entire source of libpinproc and pyprocgame.
As for example game code, start with Creature to get a taste for how a game is built. There’s also the sprawling Judge Dredd-based demonstration game which is frankly not a great reference. There’s a lot going on and it wasn’t written with the best practices in mind.
It’s been a very rewarding project to work on with Gerry; now that the P-ROC board is available for purchase (and some are already shipping) I’m excited to see what people come up with. It’s been a thrill for me to see what he’s been able to build off of (and add onto) pyprocgame. If you’ll pardon my back-patting one last time, it’s really remarkable how quickly the framework enables you to add useful components to your game. I don’t want to imply that pyprocgame makes pinball development easy, but I think it’s probably the easiest solution out there that gives you the flexibility to do whatever kind of game you want to do.
A number of homebrew pinball hobbyists out there seem to be looking for something fully self-contained and not requiring a full computer. They may be turned off by P-ROC initially, but I think that this is still a great platform if that’s your goal. There are a number of reasonably priced single-board computers available now (such as BeagleBoard) that would probably make an excellent platform for running pyprocgame. Developing the software for a pinball machine is a big job (much less building one). I want to make it easy on myself during development and work on a desktop/laptop, then move to a more embedded platform when the project is ready for that.
Finally, I’m very interested to see if there are developers out there who have their own ideas about what a pinball development framework should look like. That’s why we provided the C libpinproc API: a basic toolkit that’s very close to the hardware, giving the framework developer a clean interface (without any assumptions) on which to build something bigger (and cooler).
Updated 2014/12/7: Fixed dead links.