Phil Hassey - game dev blog
Phil Hassey as Snidely Whiplash
"You can't buy awesomeness.
You're born that way."

Archive for February, 2008

tinypy 1.0 – MIT License and swell OpenGL demo :)

Thursday, February 28th, 2008

Its been a long two months getting this project to the 1.0 state. Here it is:

tinypy1.zip | tinypy.tgz | svn://www.imitationpickles.org/tinypy/tags/1.0.0

$ python build.py
$ ./tinypy-sdl julia.py *
$ ./tinypy your-program-goes-here.py

The win32.zip includes the tinypy.exe and tinypy-sdl.exe binaries, so you can skip the building process.

tp-mandel.png

Features include the ability to parse and compile to bytecode a pretty decent subset of python code. Its got a pretty simple API, incremental garbage collection, and a handful of builtin functions. The vm supports strings, dicts, lists, numbers, functions, methods, and custom data types. tinypy even has exotic features like list comprehensions, variable and named function arguments, inheritance, and exceptions with tracebacks. All this in just 64k** of code!!

ld105-philshot.png

I also had some fun this past weekend testing tinypy “in the field” making an OpenGL tetris knock-off. My apologies to Alexey Pajitnov for my misguided contribution of tinypy to the open source stack. win32.zip | svn://www.imitationpickles.org/ld105/trunk

I hope you enjoy checking out tinypy – I’ve had a pretty wild ride building it.

*julia.py included is a low-res “realtime” jula fractal demo. I felt like rendering a mandelbrot for this article.

**See README.txt for my definition of 64k. It’s close enough.

Retro-remake of Joe Snow!

Wednesday, February 20th, 2008

I never thought I’d see the day where someone would do a retro-remake of one of my games! Indeed, someone has – Joe Snow Test Demo Released!! Check it out and leave some feedback 🙂

(My original is here for comparison. The remake is much better!)

tinypy 64k – nearing 1.0 – and it really does fit in 64k!

Tuesday, February 19th, 2008

Updates – I’ve got it all fitting in 64k*. It’s amazing how many functions that don’t do anything you can come across if you look around long enough. Not to mention how many little things you can trim out that don’t actually do anything. I have no idea where all this cruft comes from, but having a nice suite of tests sure is helpful for re-working stuff. I also cut out a bunch of stupid features nobody would ever use**. I was able to reduce the number of native types from 9 to 7.

One of the challenges I faced was trying to fix up the incremental garbage collection. My initial implementation was rather inefficient and caused some odd problems with how I wanted to code things. I was using a dict to store all the “white” items, which caused loads of dict hash lookups.

So in my mind I crafted a grand vision on how to accomplish this goal. I would adjust all objects (sans numbers) to contain a pointer to some data which would have some header data for the GC to do some bookkeeping in. Great! However, when I implemented this, I found that a number of problems presented themselves: I had to perform a malloc for each and every string that I used, which killed performance, actually making things 2-3x slower. I also noticed that the weird struct I defined was maybe a bit less standards compliant. This attempt was a wash.

So I re-crafted my grand vision. This time I would do the same thing. Brilliant aren’t I? Anyway, the results were basically the same. Who’d’ve thunk? It was slower again, this time I was quite confused by it, since I had worked around some of the string issues. I also found that the API for creating new strings wasn’t quite as “clean” as my original simple one. This caused some issues in the exception handling mechanism. I had to toss this try as well.

At this point, having re-mangled the code twice and having poor results, I suspected something else might be wrong. My brain was turning into mush. Each time I had completely edited my “tp.h” with all my struct changes in one go. I decided to make a final attempt at reworking tinypy, this time *one* data type at a time. After each data type I added I was able to see if my changes caused any performance issues. I found that my function data type was the culprit. My hashing function (borrowed from lua) wasn’t getting enough entropy and was generating massive collision cases! A few tweaks later, this was resolved. I was able to also craft the string interface to be backwards compatible with the original string interface while also working with the new garbage collection. This “step by step” approach got me to my goal. All said and done, with a bit more tweaking, I was able to *double* the speed of tinypy 🙂

Lesson learned – even if it’s only 64k, it’s better to do changes step by step instead of in one big go. valgrind and callgrind are your friends. (Although I found that tinypy doesn’t entirely agree with callgrind … ideas anyone?)

To wrap up this excessively long post about me trying to get code to work — this weekend I’m hosting a Ludum Dare warmup compo. I’m going to give tinypy a run in the “real world”. Here’s to hoping! Next week I plan on releasing the 1.0 version of tinypy.

I’m also thinking about renaming some of my files. And although pylang, dumbparse, and dump2vm have a certain rustic charm, I wonder if I’d do better with names like goat, gorilla, and sausage. Or maybe more descriptive names like tokenator, parsalizer, and bytecodatron.

svn://www.imitationpickles.org/tinypy/trunk for the brave. If you want a zip or an exe, check back in a week. I’ll have all those and more (a game!) Note that I’ve split the SDL dependency out of the main tinypy code. tinypy-sdl.c lets you run my julia.py example. The bootstrapping process also has a final step of compiling with -O3, which I think might not work for everyone. It gives pretty good speed gains on my system, so if it works for you, great!

*python mk64k.py will do a bit of search-n-replace to cut it down to size. I’ve resisted doing anything really ghastly, the code is still indented and readable. See README.txt for more disgusting details on how I cheat to pretend this is 64k.

**Okay, I’ve used some of those features. But hey, this is a 64k implementation, I’ve got to trim the fat.

tinypy 64k – now with built in garbage collection

Tuesday, February 12th, 2008

Yay – I got incremental garbage collection added into tinypy. It took a good deal of troubleshooting, but thanks to valgrind (and thanks to the people who pointed me to it) after some work I got all the memory leaks and crashes worked out. This is a nice step forward, since it enabled me to eliminate the libgc dependency.

tinypy is slightly larger than 64k, but I have vague hopes that will be remedied* at some point. In the meantime, I’m going to take a bit of a break from it. On Feb. 23rd, the Ludum Dare community is having a “warm-up” compo, and I shall give tinypy a real try at that point. After that I will probably put out the 1.0 release.

All that said, its been quite a learning experience for me. I learned how to tokenize, parse, generate byte code, build a virtual machine, and do garbage collection. I’m hoping this will make looking at the innards of other languages seem less intimidating in the future.

* if you’re a clever C / python coder and feel like taking a look at the tinypy code and give me ideas on how to compact the code a bit, I’d sure appreciate it. It’s 4k too big right now, and I’d really like to fix that. I’m cool with any suggestions though I won’t implement anything unless it leaves the code just as (if not more) readable. Please examine the README.txt to find out how I calculate the code size first.

svn://www.imitationpickles.org/tinypy/trunk or tinypy.zip for the brave. I’ve managed to compile it under mingw32 (Minimalist GCC for windows) as well as using GCC under MacOSX. Perhaps for the 1.0 release I’ll include binaries 🙂

64k tinypy – garbage collection is tough

Tuesday, February 5th, 2008

For giggles I tried to write a garbage collector to replace libgc in tinypy. I tried doing a tri-color incremental collector. I couldn’t get it to work, so I ended up switching it to be more of a tri-color mark and sweep collector.

The result of my mark and sweep collector was a 40% reduction in speed. I’m guessing ol’ libgc was designed with a bit more cleverness than mine 😉 Anyway, for now I’ve moved my “tgc” development into a branch of tinypy svn://www.imitationpickles.org/tinypy/branches/tgc if you want to see it in action.

Stuff to read: Memory Management Reference and libgc.

BRAWNDO SHAVES ITS CHEST WITH A LAWNMOWER!!

Monday, February 4th, 2008

Needless to say, the Hairy Chestival is probably one of the most influential video games of all time.  Which is why, of course, BRAWNDO’s new commercial includes it!

brawndo-lawnmower.jpg

Not to mention, it includes the world’s most bzawesome goat, CUZCO!!

brawndo-cuzco.jpg

So if you’re still sitting here NOT watching the video, maybe you should start WATCHING IT!!