Monthly Archive for April, 2009

BASHing things

I’m getting really comfortable with the Linux shell. It took me a while, but I think I’m starting to get into the psychology of it. I totally cribbed that expression from Adam Savage.

For example. Let’s say you have a folder of hundreds of PNGs which you need to convert to JPEGs. What do you do?

On Windows, I would have found Python libraries and written a little script. Before I knew Python, I would have painstakingly done it by hand. So how do I do it with Linux?

ls *.png | sed 's/\(.*?\)\.png/convert "&" "\1.jpg"/' | sh

Yep, that’s it. Here’s what this does, step by step:

  1. ls *.png lists all the PNG files in the directory.
  2. sed is a stream editor. It takes what’s piped into it, does the replacement operation provided as a regular expression (s/\(.*\)\.png/convert "&" "\1.jpg/) and outputs it.
  3. sh is the shell, and it executes the lines which are fed into it. In this case, every "suchandsuch.png" line is being turned into 'convert "suchandsuch.png" "suchandsuch.jpg"', which tells the shell to execute the convert program, a handy little command line image manipulation tool.

Just thought I’d share.

My File Format: JAM

I have a new file format which I am using for Mirage. It is easy to edit by hand, generate programatically, and pretty easy to parse too. I decided I wanted a simple file format which could be trivially edited by someone without any programming knowledge, but which would also serve as a good network packet and config file format. What I came up with, I call JAM, for “just another markup.”

Here’s an example showing metadata for one of my first Mirage models, a simple tree:

Info:
    Name:         Example Tree
    Description:  This is a simple tree used to demonstrate the engine.
                  This field really only exists to show off multi-line
                  values, which get folded together during parsing.

                  # Email obscured from spambots
    Author:       Katie Molnar <fen...@gmail.com>

    CreatedOn:    2009-04-06
    LastModified: 2009-04-06
    Version:      0.0.1-rc0

DrawOffset:
    X: -100
    Y: -190

Animations:
    default:
        Loop: 1
        Frames:
            0:
                Sprite: sway_%d_c.png
                Duration: 0.2
            1:
                Sprite: sway_%d_r.png
                Duration: 0.2
            2:
                Sprite: sway_%d_c.png
                Duration: 0.2
            3:
                Sprite: sway_%d_l.png
                Duration: 0.2

The file format is pretty straightforward:

# comment
Key: Value
Group:
    Key: Indentation shows nesting.
    Note: Keys must be unique within a group.

This parses into a tree of nested str:str dicts. For example, the syntax example would parse into:

{'Key':   'Value',
 'Group': {'Key':  'Indentation shows nesting.',
           'Note': 'Keys must be unique within a group.'}}

Obviously, the idea is very different from XML. So instead of wasting time with a complicated XML parser just to reinvent a flat file inside it, and then making my users wrestle with its often overcomplicated syntax, I went for something way simpler, yet still capable of nesting to arbitrary depth.

For network communication, I wrote a pair of functions that send and receive packets in this format, wrapped with gzip (zlib) compression.

This file format provides a consistent syntax without making the user worry about types, whitespace, or escape sequences. It’s a tiny bit more work to parse than a more obtuse format might be, but it’s well worth it for the gains in consistency and simplicity.

Jam on!

if spring: break #SPRING BREAK WOO!

Spring break it here at last. I have been enjoying it for three days so far. Yesterday was my dad’s going-away party. We rocked the fucking casbah from 3:00 clear to midnight. There was karaoke, real music, lots of awesome food, and scultpres made from cheese wax. That last part was kind of odd.

You know those little Babybel cheeses(es)? My dad’s friend (Paul)’s daughter (Lorna) was sculpting the wax casings thereof into various strange things. She’s got quite the odd assortment of talents. Paul is convinced she’s gay, apparently. My gaydar wasn’t exactly kicking off the scale, but I definitely get that impression too. She’s definitely a huge tomboy, but so was my mom at her age. I dunno. It interested me, though, ’cause damn near everything interests me.

Anyway, where was I? Oh, right, so the party was a blast. My brother had a few too many and asked for a ride home. He’s only 20, so if he got pulled over with any measurable BAC it’d be a huge problem. 0.00 is the legal limit for people under 21, after all.

So yeah, we did that, so I gave him a ride back the next day (this morning) to collect his car, then we went to Western Bagel.

We had breakfast. We hung out with my dad a bit. I saw a cool job with Amnesty International in the paper and, like a ditz, left the paper on the table in the restaurant. Goddammit. Then we went to a park I hadn’t been to for a while and talked. Then my brother left and my dad and I went to the mall and walked around for a while before we each went home.

Okay, enough of that banal BS. In more material news, I’m working on Mirage again, as a basis for this Savant game. I’m changing it a lot – making it a framework for games, basically, rather than a sort of game browser, but most of the concepts are the same. I’m doing a complete rewrite using a proper object model since the old code is basically a precarious pile of hacks upon hacks.

I’m using Git now, as I wanted to try something different and heard it was better than SVN. So far, I’m mightily impressed. Some things seem more difficult, but everything I care about is significantly easier. And, more importantly, it’s done the right way.

It’s a different way of thinking. But once you get to thinking that way, everything starts making sense. I think nothing of the commit and push process that I use with my github repo. git add $fille; git commit -m “Message”; git push $remote $branch; makes just as much sense as anything else when you think of it the right way: The repository is always local, and pushing to a remote repo is simply a separate action. This is because, in Git, everything has equal privelege. There is no one central repository. Everyone has their own copy, and they can commit to it, pull from others, and merge all they want. It’s source control done right.

Anyway, yeah. Mirage is being ressurected again. Git is awesome. Spring break is fantastic.

Tonight (6:30) I have a date with my support group at IHOP in Ventura. Woo! I can’t wait. =3

And with that, I bid you adieu. Go read something more important!