Phil Hassey - game dev blog
Phil Hassey as Rambo
".. I've been there,
I know what it's like,
and I'll do it again if I have to."

Archive for the 'python' Category

Comparing python to C …

Wednesday, August 6th, 2008

Well, I’m about 1/2 done with adding multi-players to Galcon-iphone.  I figured I’d stop for five minutes and note down some things I noticed during my porting experience.  Obviously, C and python are different, but here are a few of the ways I’ve FELT the difference.

  • C doesn’t have garbage collection.  I’ve managed to avoid doing much manual GC by having everything in a single big struct that keeps the entire state.  The only place I use malloc/free is when I’m downloading web data.  So it hasn’t been a big deal for this project.
  • Speaking of web data, C doesn’t have a built in urllib.  I wrote my own awful HTTP 1.0 page fetcher.  On the plus side, I was able to make it work *exactly* how I wanted it.  No threads, non-blocking 🙂
  • Although not “built in” I found enet, which was a thin layer above UDP for networking.  I found this incredibly much easier to use than python sockets were.  (Yes, I could have used some other python lib, but I didn’t.)
  • C is really fast.  Thankfully, since I originally dev’d Galcon in python, I was “forced” to get my algorithms pretty good to keep the speed reasonable.  By porting everything to C, I’ve now got amazing speed.  I think I could host 100+ servers on a single CPU easily.
  • Managing strings in C is an ordeal.  It’s just not pretty, so I try to avoid doing much with them.
  • OpenGL seems pretty painless in C.  I haven’t done any notable OpenGL stuff in python, so I can’t really compare the two.
  • No exception handling makes me have to code things more carefully.  In python, I could parse an incoming networking packet, and just wrap it in a “try: (parse stuff) except: pass” block.  If something was bad about the packet, it would just move on.  In C, I have to check everything carefully so that I don’t create some kind of segfault by accident.
  • In my case, serializing data is easy in C.  I can just save a structure to a file (or send it in a net packet) and load it back later.  In python this is much more complicated.  (Especially since Galcon-shareware isn’t pure-python.)
  • By using C, I don’t have to deal with some awful FFI.  That is a HUGE time-saver.
  • I must admit, I LOVE python’s indents.  But I also must admit, now that I’m back into C coding, I don’t miss them as much as I thought I would.
  • I still dislike header files.  I wish C magically generated them or something instead of making me write them.
  • I learned about writing tests in python.  I’m doing that in C for my networking code.  I run the tests as part of my build process, and it saves loads of time by catching all the bugs for me 🙂
  • Automatic type checking is sort of nice.  Having the compiler tell me I didn’t do anything incredibly stupid is sort of nice.  (Although in some cases, it can get a bit annoying.)

Well, that’s about all I can think of for now.  Draw your own conclusions.

Galcon + iPhone = AWESOME

Friday, July 18th, 2008

Hey, I’ve just finished porting Galcon to the iPhone and it’s now in the App Store!  You can read about it here!

I don’t *really* have anything super pythonic to say about the porting experience, other than .. I probably wouldn’t have bothered to do it if I hadn’t been hanging out at pycon and having people show me their iPhones and telling me how I should totally port Galcon to it.  So thanks to those people for getting me started!

The link above is where all the fun is, but just so this post isn’t all boring text, here’s a screenshot:

And if you want to know more about the porting experience, I’ve been blogging about it.

iGalcon – port of Galcon to the iphone – part 1

Saturday, June 14th, 2008

I’m going to blog a bit about my experience porting Galcon to the iphone.  It’s not overly python related, so I won’t send all these posts to the python planets.  Maybe just a couple.  Anyway, if you’re interested, keep an eye on my blog.

There is a chance I’ll use tinypy in iGalcon, but I haven’t really decided on that yet.  There isn’t a large need for scripting at this point, but if one comes up, I might just do that.  To start, I’ve takened the main flocking engine in Galcon, re-factored it a bit, and built a 100% C / SDL mini version of Galcon at the res I will be rendering it on the iphone.  I decided to do this, so I could be sure that the core engine was working perfectly in C before I complicated the matter by trying to run it using the apple tools.

So far so good 🙂  It took me about 6 hours to get this mini version of Galcon up and running in SDL.  Most of the code I was able to grab from the original Galcon.  I did a small amount of reorganizing to make things cleaner.

One of the requirements for iphone development is for your app to be able to be closed and opened and have the app recover to its previous state.  At least, that’s the ideal.  I adjusted my C structures so that they include no pointers, only ID numbers, so I should be able to write the game state to a file and reload it and have everything back.  The full game state is around 32k, so I think that will work.

On the iphone side of things, it took me several hours to get all my certs set up so I could work with the dev environment.  I was able to build their example app this morning.  Here’s to hoping the rest goes smoothly 🙂

Learning python by reinventing wheels …

Wednesday, June 11th, 2008

I’ve learned a lot about python by implementing tinypy. Today I was thinking over my re-work of classes, objects, and inheritance in tinypy (not in trunk yet). I noted how in tinypy, I will be able to change the class of an object via a function call (a-la lua):

class A: pass
class B: pass
x = A() # x is an instance of A
setmeta(x,B) # x is now an instance of B !!!

So I thought to myself, I wonder if python can do that. Well, it can, and as per usual, its solution is quite elegant:

class A: pass
class B: pass
x = A() # x is an instance of A
x.__class__ = B # x is now an instance of B !!!

So, lesson of the day — you can dynamically change the class of an object in bigpy. Which, actually, I’ve sometimes wanted to do, I just didn’t realize I *could* do it.

Dear lazyweb: tell me about python telephony ..

Tuesday, May 27th, 2008

I’m looking at doing some telephony work in the next half year.  I’ve read a bit about asterisk and it looks like it has come a long way in the past few years.  I notice that there are quite a few ways to integrate it with python AGI, etc.

Anyone care to spout some opinions?  How good is python support?  Is one of these packages way better?  Got any tips on how to get started playing with this stuff as quickly as possible?  Any dire warnings you care to pass on?  Are there any alternatives to asterisk I should also be considering?  Are there any reasons why I would want to use a language other than python for my telephony work?  Tell me everything!

Thanks lazyweb!
-Phil

meta-methods: python vs tinypy

Tuesday, May 27th, 2008

Man, could I have even thought of a title that sounds dustier? It just screams “Get ready for the boring lecture of the year folks.” I should totally re-name this post to something like “putting your brain through a blender .. FOR FUN!” Or maybe I should have gone the pretentious route and named it something like “Analysis of modern programming meta-method paradigms.” Actually, that sounds even dustier than my original title. At least my original one falsely implies that there is some competition going on in this post by my use of the “vs”.

Here’s how python does it:

class X:
    def __get__(self,k): return “OK”

Here’s how tinypy does it:

class MetaX:
    def __get__(self,k): return “OK”
class X:
    def __init__(self): setmeta(self,MetaX)

Okay .. so .. the python way is WAY more readable. Nice 🙂 So let me remember if there was a good reason for doing it a different way in tinypy … I think the answer is “maybe” ? Here’s what I can come up with:

  • In tinypy dict == object, which means a.x == a[‘x’]. (I’m not sure how that’s relevant, but it does mean that I have no need for a __getattr__.)
  • lua does it that way! (I have copied many other lua design decisions, so why not copy another!)
  • It’s faster? (In a sort of, if only tinypy were as fast as python is to begin with kind of way.)
  • It was easier to hack together in an afternoon! (Well, actually .. looking at the python code, I think the python way might have been easier.)

So what did I gain by going the lua route instead of the python route? I’m not entirely sure .. but it sure seemed like a good idea at the time.

A few days later …

With a bit of effort, I’ve come up with a few more reasons why I did this in tinypy:

  • Not only are dicts objects but they can also be classes. This is done by having a __call__ meta, so if you have class X: .. X() calls getmeta(X).__call__. This is relevant because if the class itself had a __call__ method, how would you define your class so that it knows to create your object with a __call__ method? (Probably by having a __new__ method that isn’t copied to the object.)
  • The one way the previous point is relevant, is that the object __new__ would probably have to be smarter than how I create objects currently. It would have to realize that __new__ methods don’t get copied into objects.
  • Also, I would probably have to internally track what is a class vs what is an object. So I know when I do something like X.test(self) .. and my class X has the unbound method of __get__, it knows not to try any meta magic.

Okay .. those aren’t great reasons. The nice thing about tinypy being .. tinypy .. is that if this continues to bother me for the rest of the day, I can probably try out the implementation in a couple hours. If you want to see the current meta implementation, it’s in subversion.

Anyone care to comment on the whole lua vs python style meta-methods stuff? I’m pretty sure I’m not sure at all what I think about them!

Phil’s pyGame Utilities (pgu) project up for grabs!

Wednesday, May 21st, 2008

Well, I developed pgu several years ago .. and I’ve sort of moved onto other things.  And now I really feel like I’m not doing a great job maintaining pgu anymore.  I get occasional contributions which I don’t handle and I don’t really have any direction I want to take pgu, so I think it’s time for me to step down as maintainer of that project.

I’ve got a project page on pygame.org that has a pretty good description of what it does.  I’ve also got a project page on sourceforge that has the mailing list.  Really, it would probably do better all hosted with google code and google groups.   (tinypy has been doing *great* with those!)

Anyway, it’s been fun, but it’s time for me to let someone else take the torch!  Good luck to whoever that ends up being!  I guess I’m sort of taking applications here, so .. tell me why you’d be the best maintainer for pgu 🙂

How to run an open source project?

Thursday, April 24th, 2008

If I were going to OSCON, I’d certainly go to this talk. But I’m not planning on it, so …

… So I’ve got that tinypy project sort of taking off. It’s got a SOC student (thanks google & PSF) and a bit of interest. So far most of the open source projects I’ve done haven’t generated more than a couple patches — in their lifetime. With that in mind, I’m not entirely sure what is a good way to accept patches and run a project, since I don’t have loads of experience in it. I’m a “solo” dev in my day job as well. I want to do a decent job of managing the tinypy community without having to work too hard.

Do I take whatever people give me and patch it as-is and just figure, well, someone else will fix it?
Obviously not. Especially not for tinypy where “good” and “concise code” is of such large value to the project. And with the SOC coming up, “secure code” is also very important, as well as testing.

Do I be really strict and keep rejecting a patch until it’s “perfect”?
Maybe? I remember submitting a patch to one project ages ago, and it got rejected without much good explanation. I’ve also submitted others successfully. Not quite sure what the balance is.

Do I take the patch and apply it and then fix things up myself?
Maybe? If it is easy to fix … but then again, why should I have to do all the work? I don’t really have that much spare time (all evidence to the contrary.)

How do I grow the project (in general) without it turning into a monster?
Stick to my guns on the 64k code limit*? Maybe not, since things like VC support, security, etc, are going to take up *some* bytes. Not to mention, tinypy could use a few batteries … At the same time, I’ve gotta draw the line somewhere.

Obviously some common sense is needed here, but sometimes I run a bit short on that. Advice / links to good articles would be swell at this point. I could google this sort of stuff, but I think having the context of responses from a community I know would be much more valuable here.

-Phil

* on that point, I think having the 1.0 source always in the “featured downloads” might be a good idea. Even if the project gets bigger, people can still check out the “classic version.”

tinypy: did i mention metaprogramming?

Monday, April 21st, 2008

For the sake of this post, I’m going to pretend to know what metaprogramming* is.  Yeah, so tinypy** totally has that.  At least, since the parser and compiler in tinypy is written in tinypy, you are able to modify those modules on-the-fly and add new features into the tinypy language.  (Not that you’d want to, but certain other languages get so uppity about being able to do that, I figured I’d plug for tinypy here.)

For example, (at present) tinypy doesn’t have support for decorators.  I’ve always liked decorators, so I made this code (a zip of main.py, deco.py***, and test.py) so that if you have a main.py:

import deco
import test

When the deco module is loaded, it cleanly**** adds decorator support into the tokenize, parse, and encode modules of tinypy.  Then when the test module is loaded, it is able to use decorator syntax.  Yay!  This mostly thanks to the top down operator precedence implementation in tinypy.

So now, if say, you have some crazy idea for how the $ operator should be used in bigpy, you can go ahead and use metaprogramming to add it into tinypy and show all your friends how awful your new syntax looks and have a working proof-of-concept!  Yay!

* feel free to enlighten me
** it’s got a mailing list now, join in on all the fun!!
*** only 611 bytes :)  They were pretty simple to implement, since they really just mean: “given ‘@a \n def b …’ do ‘def b … \n b=a(b)'”
**** Since all the language features are stored in dictionaries, it’s “pretty easy” to add new symbols / operators.  (Or remove features, or whatever!)

not wanting to be left out …

Friday, April 11th, 2008

$ history|awk ‘{a[$2]++} END{for(i in a){printf “%5d\t%s\n”,a[i],i}}’|sort -rn|head
269   ls
253   cd
182   kate
50   cp
48   svn
43   mkdir
23   mv
21   grep
16   gqview
13   python