Announcing PYGJS (PyGame in your Browser/NodeWebkit)
This is part of a larger series known as “PYGJS“
When I started down my Python programming adventure it was more an attempt to master Python so that I could teach it fully to my nephew. My nephew is, rightfully so, very result oriented, in the sense that he’d like to see something “happening” while he learned how to program as opposed to just abstract esoteric bits and bytes flying around. That was when I was introduced to the PyGame library. I knew of PyGame vaguely from such projects as Ren’Py (the visual novel maker) which I knew were based on the library (or some such, last time I checked…). However, I hadn’t ever really dived too deep into the PyGame library in terms of making anything with it. I always assumed it was quite complex, actually, which is kind of funny.
Fast-forward to teaching my nephew Python, and kablam, we’re using PyGame to create computer games on his fancy Windows laptop (much faster than mine). The first game he created was two tanks rotating around on the map (viewed from above) that shot bullets at each other. I, of course in my usual style, reviewed PyGame for a week and a half, and found the library actually to be quite simple! It was so easy to get images from files and onto the screen, and even scale or rotate them. Event handling was pretty simple as well, PyGame abstracted what could be quite a lot of fangling around with various devices into a simple Python list. I was impressed!
I actually bought my nephew a book on developing arcade games with Python and PyGame (you can view it here), and we started using it to go over parts of Python in text, as opposed to the completely verbal way I was delivering it. On that note, here are the books I used to learn Python, and to learn how to program with Python. (Yes, each of those was about 1500 pages, and yes, each of those I read all the way through.) With this book and accompanying website we developed a simple side-scroller. He had a little Mega Man guy jumping around and walking on platforms, collecting gems and blasting robots within, really overall days (though the lessons were (a) week(s) apart). I was impressed.
In fact, I was almost envious. Back when I first was learning how to program on my TRS-80 Color Computer II 16k, making something as complex and demanding as a side-scroller would’ve required assembly level hacking… but my manuals only explained BASIC. Although there were the peek() and poke() functions, I had no idea about hardware or processors, and the school elementary library you can imagine was quite lacking on books on how to program your personal computer. (After visiting the University Library in the city I live in now, I wished I could’ve had access to it when I was little, it’s full of EVERYTHING! My libraries I had access to when I was little pale by comparison.)
Later on, I graduated to a Macintosh IIsi with the QuickBASIC compiler on it. Yes, I was still programming in BASIC, but, it was a more powerful BASIC! However, attempting to make anything like a side-scroller on it, ala Super Mario Bros. for the NES, was impossible… and believe me I tried. It was just too demanding processor wise, graphically, and QuickBASIC wasn’t really set up to do anything quite like that.
Then I bought my own computer, a Quadra I believe, and had CodeWarrior Professional on it. Yes, when I was in eighth grade I got my hands on my oldest brother’s university textbook on C and C++ and devoured it. From then on, forget this BASIC stuff, we’re going full on C++ man! And I did, to varying degrees of success. I first started porting what dinky games I HAD made in QuickBASIC to C and C++, which was interesting.
Eventually I discovered that it’d be neat if I could program all the intensive graphical necessities in C++, but script them together using QuickBASIC. The QuickBASIC manual was unfortunately incredibly sparse on how to create linkable libraries for your programs in languages such as C, though it was doable. Because of this sparseness (and no internet) I was never able to fully realize my dream of programming hardcore functions in C and scripting them all together in a beautiful symphony of a game in QuickBASIC.
All in all, I never really successfully compiled a working side-scroller. Alas. Then I got interested in programming other things and ideas, such as my old high school club, and game programming took a bit of a backseat. But that was okay, that’s when I really honed my abilities of being a programmer. Did you know I’ve never had a formal programming class in my life, but I worked as a professional programmer in a financial statement printing plant? I wrote C programs that accessed an Oracle database with SQL, and output PostScript (yes, I learned PostScript) to a printer spool, all in the confines of a Linux dummy terminal using Vi and GCC. I tell you what, after using the debugger on the command-line you get to really love IDE’s and their visual debuggers.
However, I digress.
I realized, teaching PyGame (and Python) to my nephew that here was a library that abstracted out all the hardcore C stuff I wanted, and plugged it into a friendly high-level programming language. It wasn’t QuickBASIC, it was Python, but really… that’s better! (Who wants to program in QuickBASIC these days?) Here, as a teacher, we had implemented what I never actually fulfilled as a young man, a working side-scroller. Every time I left a tutoring session with him I felt like I could go home and in a matter of days have all sorts of Pygame powered games whizzing about on my desktop.
Of course, the creative cramps kicked in, and… I haven’t made a pygame game yet. But that hasn’t stopped me from exercising my programming skillz. I loved the idea that with a little Python you could create basic games that would run on your computer like an old game console. I did more research and gradually got more and more familiar with PyGame as a library (as well as the Python programming language). The only gripe I had about PyGame was the packaging. If I program a game in PyGame, in order to package it as an executable I had to basically “compile” the game for whatever platform I chose. And it’d only run on platforms that supported PyGame, which is fine for desktops, but what about phone apps? Using various tools I could encapsulate a pygame into an executable that contained a python interpreter in it and so on, but that wasn’t ideal for mobile…
So I downloaded the latest copy of NodeWebkit (so I could test in a desktop environment as well as a browser one) and got to work. First I included Brython and Brython’s standard library. From there, I needed to be able to access the gamejs module, so I browserify’d it using a bridge file that set the result of the module import onto a global property available on window. Then… I started writing Python modules that mimicked PyGame modules but really wrapped around GameJS functionality. A week and a half, and 17,000+ lines of code later (according to GitHub, though that seems like a high number), I had PYGJS (github).
Now, I used more than GameJS to accomplish some of my purposes. There were times GameJS just offered too basic of functionality, or no functionality. I was pleasantly surprised to learn about many APIs available to the latest browsers these days including Joystick APIs, and Web Audio APIs. For sound, I bypassed gamejs.audio and instead used the excellent Howler.js library (with slight modification). For talking to gamepads, like my PS3 controller, since PyGame has a joystick module, I used Priit Kallas’ gamepad.js (forked here). And for fonts, since PyGame loaded TrueType fonts from files, I decided I needed something more formidable than the simple canvas functions wrapped by GameJS and used the excellent opentype.js
All in all, it’s a rough draft. The code isn’t fully documented because really, it’s ported from other places where there IS documentation (pygame, gamejs, etc.) Anywhere where the functions/classes don’t QUITE act like their pygame equivalent I make a note of though, so that you aren’t tripped up.
I’m hoping this can kickstart some interest in running PyGame in the browser/nodewebkit, and further game development in the browser with an additional library for those already familiar with PyGame. Packaging then becomes a matter of packaging a NodeWebkit project for the desktop, or what have you for a phone app.
Anyways, I have set up a new page dedicated to PYGJS in my Programming Projects section of my site. Right now it just has a link to this post and the README of the github project, but I hope to elaborate on it as time goes on.
You can also follow the project on devpost.
This is part of a larger series known as “PYGJS“
If you appreciate this article you might consider supporting my Patreon.
But if a monthly commitment is a bit much, I get it, you might consider buying me a coffee.