Phil Hassey - game dev blog
Phil Hassey as Syndrome
"Look, stores don't sell
costumes like this to just anyone."

Archive for December, 2007

64k “tinypy” keeps plugging along …

Friday, December 28th, 2007

So .. I had a hard time resisting working on my 64k version of “python”. I’ve been able to get quite a few features into it and I’ve gotten my julia demo up to near-C speed as well as tamed the crazy memory problems I was having.
I suppose the question I ponder is “why bother”? Well:

  • It’s fun 🙂
  • I’m learning the basics of parsing, code generation.
  • It might even be somewhat useful!

The first two don’t require much explanation, the third (usefulness?):

  • By keeping the codebase < 64k, it will be readable by mortals
  • By generating C code, it can build self-contained binaries easily
  • It has a really simple “FFI” which auto-generates many of the “FFI” wrappers for you
  • It’s sort of fast now (no promises for anything real)

It, of course, isn’t python, it just looks a bit like it. Notable differences are:

  • Access to members is like lua / javascript. x[“y”] and x.y mean the same thing.
  • Most infix operators only work with numbers. “x”+”y” won’t work. (Rational: makes numerical math fast)
  • It’s missing (and will never have) a bunch of really nice features. Syntax checking is notably weak. Maybe I should scrap my parser, etc and just use python’s.
  • No exception handling. Incorrect use of anything will result in a seg fault.

Notable similarities:

  • Language contains separate list and dict types. I thought about doing like lua / javascript / php and having a single type, but it just didn’t feel right.
  • It’s indented (duh)
  • Garbage collection via libgc

Well .. that’s about it. I expect before I’m done I’ll make a game with it, to see how it works in the real world. I’ve got a few more things on my TODO list to get done first. If you are brave, check out svn://www.imitationpickles.org/tinypy/trunk and run ./run_julia (linux) to see the julia demo.

Oh, and for all you “test first” folks, I’ve (more or less) been doing that. It’s made development considerably easier. See the bottom of “pylang.py” “dumbparse.py” and “dumpout.py” for all the testing fun.

64k version of python is 4234x faster* than c-python!

Saturday, December 22nd, 2007

To satisfy some sick curiosity of mine, I decided to write a miniature version of python in less than 64k of code. The code includes a tokenizer (which works rather well) a parser (which sort of works ) a translator (which does the job). All of those bits are written in python. The last bit is the C library I wrote to handle all the grit. That part isn’t so good.

To sum up, my implementation does very little, and what it does, it does very slowly. Most of the speed is spent up in memory allocation (my best guess). I wish I had a julia screenshot to show you, but I don’t think I have the patience, nor the RAM, to provide you with the pleasure.

If you wish to witness the horrors, feel free to check out svn://www.imitationpickles.org/tinypy/trunk … Please don’t look too closely. I think if I really want to work on this sort of stuff my time would be better spent either:

  • Learning the python C API or ctypes so I can do stuff without SWIG. (I’ve liked SWIG, but all the magic makes me nervous.)
  • Contribute to shed-skin, and add some features I’d like to it
  • Contribute to PyPy-Rpython, and add some features I’d like to it
  • Wait for py3k, where hopefully someone will write some magic code that uses the swell function annotation features to make fast things happen.

Of my options, learning the C-Python API (or maybe ctypes) is probably the easiest answer – I’d get all the fun of python, and I’d get my C speed. Between working on shed-skin and PyPy — my feeling is that I really wish shed-skin generated C code or that PyPy-Rpython wasn’t so huge and scary. All that said, I’ll probably just wait for py3k and hope 😉

*today is opposite day!

Ludum Dare Website Post-Mortem

Tuesday, December 18th, 2007

I’ve been a bit quiet the last couple weeks .. after my spree of “python->c” converter posts I got pretty busy working on the Ludum Dare 10 website.  Ludum Dare is a 48 hour game development competition.

I used WordPress as the basis for this project and I think it was a pretty good choice.  Generally anything I needed to do, there was a hook in the API to let me do it.  I was able to keep all my compo code (theme voting, trophies, rating of entries,  tag clouds, screenshot grids, security tweaks) all within a module I wrote without having to modify any of the core WordPress files 🙂

There were around 150 signups on the site and 50 people completed entries.  The theme was “Chain Reaction” which won even in the first round of voting .. and still won after the 2nd and 3rd rounds.  I spent most of the competition sitting around on IRC doing nothing and occasionally working on my game.

The one notable glitch in the compo was the announcement of the theme ceremony.  I switched the voting to closed so we could see the results and it showed several themes with almost nobody voting for them.  Turns out those were two themes which I initially had in the final round but removed (because they didn’t make the cut).  The results of a few people voting was stored in the database so they still showed up.  Anyway, that was easily fixed.

At the end of the compo it took me an hour or so to get the entry rating system set up.  I also added the ability to leave a comment along with your rating to encourage more people to leave comments.  (They could use the WordPress blog commenting system, but that would take a few extra clicks and thinking.)  This way seems much nicer.

I think the funnest feature I added to the site was the Trophy feature.  This feature lets users award each-other 64×64 pixel trophies at any time.  It’s a nice community feature because it lets people recognize cool things that people did out-side of the pre-set rating categories in the contest.  (For example, one entrant recorded a tuba solo for their game.  Although the compo has a sound category, several people felt that the tuba playing merited special tuba trophies.)

I don’t know if I’ll be running the Ludum Dare competition again or not, but I’m sure I’ll be hosting some others now that I’ve got this swell compo system written 🙂

BRAWNDO: IT’S LIKE SHAVING YOUR CHEST WITH A LAWNMOWER!!!

Thursday, December 6th, 2007

ARRRRRRRRGGH!

BRAWNDO THE THIRST MUTILATOR

Yeah, it’s arrived.  Check it out at www.brawndo.com!!!  In the meantime, maybe you should SHAVE YOUR CHEST WITH A LAWNMOWER!

Pyrex – from confusion to enlightenment

Wednesday, December 5th, 2007

My last post explained my frustration trying to get pyrex to do *anything*. Since then, several people posted solutions and e-mailed me with more ideas (thanks allefant and Filip Wasilewski). My review was focused on the usability of pyrex as a python->C translator, since that’s what I was working on with both shed-skin and pypy/rpython. It didn’t hold up so well. This is because … pyrex ISN’T a python->C translator.

pyrex is its own special language that contains both python and C stuff. pyrex does not do type inference. What pyrex provides is a way to mix both python and python-like C code together in the same files. The trick to understanding pyrex is to know where the line between python and C is in pyrex.

Here are some of the gotchas I experienced. I wasn’t able to detail them in my previous post because I didn’t really “get it”. Now I think I do, so I’ll explain some stuff so you can try out pyrex without getting confused the way I did:

Gotcha #1: float() is a python function

cdef int a
cdef float b
a = 3
b = float(a)

Solution: use pyrex’s casting to avoid massive object-conversion speed penalties

b = <float>a

Gotcha #2: pyrex doesn’t do type inference

def set_video(int w, int h):
    s = Surface()
    s.surf = SDL_SetVideoMode(w,h,32,0)
    return s
pyrex: Cannot convert 'SDL_Surface *' to Python object

Solution: to access your C-members you must declare the variable’s type first

def set_video(int w, int h):
    cdef Surface s
    s = Surface()
    s.surf = SDL_SetVideoMode(w,h,32,0)
    return s

Gotcha #3: def makes python functions – which are slow

def set_pixel(self,int x, int y, int color)

Solution: To be able to access a fast version of a method in C and be able to access the same method in python you must define two versions of it

cdef _set_pixel(self,int x, int y, int color):
    pass # do this really fast
def set_pixel(self,int x, int y, int color):
    return self._set_pixel(x,y,color)

All that said, I think pyrex is really neat for writing extensions!  One of the best features it has is properties (which are like descriptors, only easier).  Just be careful if you use it to not mistake it for python.  Lastly, by using those tips I was able to get my julia example to be full speed.

Struggling with pyrex

Monday, December 3rd, 2007

In my last blog post, someone said I should check out pyrex. So I did.

pyrex-julia.png

Okay .. I must say, I found it extremely difficult to use and rather slow – 700 ms per frame (my pure C implementation is around 65 ms per frame). I had quite a bit of trouble figuring out the magic of getting anything to work, a few things seem pretty inconsistent. Thankfully I found someone (allefant – thanks) who helped me get some stuff working, but even he was rather baffled by some of the stuff we had to do to get it going.

Unfortunately, even after all our efforts, it was still slow. pyrex does so many magic things, that even with everything defined out to be C-ish, it still wraps ’em up so we don’t get the C-speed we want. I think the largest confusion is that pyrex marries both python and a magic brand of c-python code together in the same place – making it hard to know what “context” you are in at any point. To be kind, it does have some *really* cool features that Shed-Skin and PyPy/Rpython don’t have (such as properties). But the feeling of inconsistency and confusion I got while working with it just took the fun out of it for me.