Announcing PYGJS (PyGame in your Browser/NodeWebkit)

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 The Clasheerian Order, 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…

Before I became familiar with PyGame (before I even taught my nephew), I had been reading up on HTML5 game creation using JavaScript and the latest browsers.  I thought these were pretty neat because theoretically you could then run a game on anything that supported a browser, such as well, a browser, or you can embed them into desktop apps using things like NodeWebkit, or even embed them into downloadable apps for your phone.  I learned JavaScript from the definitive guide on my Kindle reader.  But the thing about JavaScript is that it… well, it never captured my imagination or sense of aesthetic like Python or PyGame did.  I mean, you can do some pretty neat stuff with JavaScript, but the hoops you have to leap through for all sorts of other things is weird.  The callback heavy nature of it, even with stuff like RequireJS, just kind of turned me off. I mean I loved the ideas of Closures, but, nothing seemed as clean as Python.

So at this point in the post you now know I can program in C, C++, Python, and Javascript (I had also programmed in many other things, but that’s what I covered here.)  Then something magical happened.

Then I discovered this cool thing called Brython (By Pierre Quentel) were I could run Python in the browser!  Really it was a Python 3 compatible interpreter written in JavaScript.  I thought that was pretty cool, as I like Python better than JavaScript (as noted). The best thing about it, in my opinion, was that you could interact with JavaScript objects in Python code easily, calling and passing basic arguments (I never tried objects) to their functions and it would automatically translate the necessary JavaScript.  Calling a Brython function from JavaScript is not impossible, but not necessarily AS straightforward (as far as I know).

So I had an odd idea.  What if I could execute PyGame using Brython in the browser?  I began looking around for 2D game engines written in JavaScript to see what I might be able to use that could translate PyGame constructions into JavaScript calls.  Well, unfortunately, many JavaScript 2D game engines come with all sorts of fancy bells and whistles, which is great, but I didn’t want to do a lot of work translating PyGame.Surface for instance to a totally alien SceneGraph construction.  That’s cause I’m lazy, like all good programmers (I say tongue-in-cheek).

Then I discovered GameJS.  This library actually had a section in its examples that compared the code you’d write in JavaScript using GameJS to what you might write in equivalent PyGame.  This is because GameJS virtually maps to PyGame construction in the most beautiful way.  It had Surfaces, just like PyGame, and Rects, a display module, events, and so on.  This seemed to be the answer I was looking for.

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

I also modified and augmented GameJS with my own code so that I can provide some functionality in JavaScript in the context of GameJS that is available in the C files of PyGame.  There are a number of methods, particularly in SurfArray or Mask that are direct ports of C functions from the pygame repository.  (This is where knowing C was handy!)  By porting the C to JavaScript, and modifying GameJS, as well as using the additional libraries I was able to implement MOST of PyGame up until about 1.8 release.  There ARE functions that are not supported, but it isn’t necessarily IMPOSSIBLE to plug those in if you have the know how.

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.

My personal reason for doing this besides the coolness of it was such: I want to make game ‘editors’ for my projects.  That is, I want to create programs that create the data necessary for a given game engine to run a game.  So for instance, I’ve been interested in porting something like WinterMute to PyGame so that I could create point-and-click adventure games (or my partner could create some) that ran on the PyGame engine.  Unfortunately, PyGame is not that great at user interfaces, and although you CAN combine PyGame and tkinter, it’s a huge pain.  I also didn’t like the idea of having to learn a whole new library such as tkinter for desktop user interface programming.  As well, I wasn’t sure how well it’d translate to other platforms.  I decided I’d rather design user interfaces with tools I already know: HTML, CSS, and JavaScript.  PYGJS now allows me to run a “PyGame” game inside a browser where I can use such tools to complete my game editor interface.  I also get the benefits that browsers bring including the ability to use other JavaScript libraries and browser functionality.

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.  Also, if you *ahem* like my programming endeavors be sure to check out how you can support me so that I can make further developments at my Patreon.  If you don’t feel like a monthly investment, then buy me some coffee as a one shot (heeheehee).

You can also follow the project on devpost.

photo credit: axn99912 100_0702 via photopin (license)

Liked it? Take a second to support kadar on Patreon!

kadar

I'm just a wunk, trying to enjoy life. I am a cofounder of http//originalpursuitssoc.com/ and I like computers, code, creativity, and friends.

You may also like...

Leave a Reply

%d bloggers like this: