Sunday, January 21, 2007

Visualizing Sorting Rules

So, the sorting rules for the sprite graphic (which includes such lovely permutations as the Pachyrat, Bunnysaur, and Llamacorn (do you ever get tired of writing L's? I think not)) were getting unwieldy and as a result were largely incorrect. However, I was having some trouble convincing my topo sort algorithm to report cycles, and even then it would have been problematic to figure out where they needed to be broken. What does this mean? Vaguely, it means that my rules would occasionally say that the bunny ears were in front of the bunny rider, and occasionally the bunny ears would be behind the bunny rider. Of course it would be much more complicated. Here's an example cycle: the bunny ears are behind the mount head which is behind the llama fur, which is behind the saddle, which is behind the dinosaur head, which is behind the bunny ears. Since the rules file uses a lot of regular expressions and sandwiching techniques, these cycles are hard to find. I needed a way to visualize the problem.

Enter Graphviz. Graphviz is a tool that takes data describing a graph and produces an image of the graph. A picture is worth a thousand words. I spruced up the Cixar Python library's graphkit module (which uses Graphviz) and wrote a tool that produces graphs of layer sorting rules files. This is what I beheld. (old rules)

So, there are a few cycles in there. Ok, maybe a lot. They're easiest to spot by looking for arrows pointing up instead of down. Ooops. Clearly this isn't manageable. So, I started rewriting the layer sorting rules one set of layers at a time. I added a feature that lets me make "virtual layers" like "rider_face_bottom" and "rider_face_top" so I could organize the layers into boxes and sandwich the boxes. This is the result. In addition, the layer rules are all correct now, and I will be able to show off some demo graphics that include the mount rider tomorrow. (new rules)

Friday, January 19, 2007

Panda Assassin

Before I go watch the remains of Battlestar Gallactica season 2.5, I threw this together. I present, Panda Assassin.

Thursday, January 18, 2007

Plesiosaur

I bend a lot of ears, especially at work, about the Tale project, and some novel ideas come out of these conversations. I do not wish to implicate the innocent, so I'll spare the burden of names, for now. One thing led to another. It started with gathering ideas for siege weapons, like alternate names for "Trebuchet". Out of that conversation came the idea of a ballista ballista ballista, which would send monkeys into orbit. Some felt that this was too ridiculous, so we came up with the idea to "warm up" our audience by starting simple: Signal Monkeys. It's not so absurd a notion. Once we've gotten you accustomed to the idea that well trained monkeys with signal mirrors, telescopes, and semaphores might reliably relay data on enemy positions for ballista artillery fire, we introduce weather monkeys (monkeys hanging from weather balloons), and then the Ballista Ballista: a long range ballista that fires a monkey and a crossbow into enemy territory. From there it's a small step to accepting the notion of a Ballista Ballista Ballista, equipped to send a signal monkey into geosynchronous orbit with a paper cup and a lot of dental floss. This evening I synced up with my partner in crime:

    Ryan: EVIL MONKEYS

    Kris: oh, there are plans. let me tell you.

    Ryan: hahaha

    Kris: signal monkeys

    Kris: monkeys with crossbows on backs of ballistae. weather monkeys. spy monkeys. kamikaze monkeys. you name, we've got it.

    Ryan: hehehe

    Kris: if it couldn't get better, penguins with clubs, penguins with rockets, penguin submersible re-con, penguins launching penguins, kamikaze penguins. you name it, we've got it.

    Ryan: insidious!

    Kris: oh, it gets better.

    Kris: PANDAS! pandas riding pandas, pandas with rifles, panda blimps, sniper pandas, pandas with wire guided missiles. you name it we've got it.

    Ryan: :-D

    Kris: it gets better.

    Kris: sub-nautical mounts. sea-rats, otters with gills, elephants with snorkels, plesiosaurs with snorkels, you name it, we've got it.

    Kris: ironically, ducks will not be seafaring

    Kris: they have good union representation

Again, using the recently created svg-atomize and the sprite merge script, I threw together additional layers for a plesiosaur.

Plesiosaur

Wednesday, January 17, 2007

Bloody and Athsmatic

Tale, like all well designed programs, has no design. You probably wouldn't be able to tell if you looked at the code, but when it comes down to it, it is what it is, and that's the only explanation for how it got to be that way. On the flip side, you probably could easily tell that the program has no design because it also doesn't have a release date. This, I know, is a dubious design philosophy, but I like surprises and emergences.

I was quite surprised to find that Tale was turning out to have a lot in common with a card game, in the sense that the artwork would be static, and effects would be applied by stacking and transforming graphics. This would be analogous to blood and poison counters, "tapping" and discarding. I find this both convenient (as a developer with limited resources) and endearing.

Today, I drafted three effects for the game. One of which is the blood counter graphic. It's a 20 layer image with sets of blood splatters that Tale will liberally apply as a creature takes damage. I imagine that you won't have a chance to heal during combat, but you will be able to apply bandages. With any luck, this will stop the bleeding until you have a chance to rest. I also drew up a posion cloud and spore cloud. The graphics are shown on the EffectList on the Tale wiki.

Tuesday, January 16, 2007

Llamacorn

A couple days ago I was charged by Ryan Paul to produce a graphic for a llamacorn. Since then, it has become an eagerly anticipated phenomenon, with a teething crowd of at least three awaiting its release. Several celestial bodies had to arrange themselves to make its debut possible, but at last, I give you the llamacorn. Technical details follow.

In the vein that I loosed with svg-sort, svg-filter and the hitherto unmentioned svg-select, I postponed creation of the llamacorn until I had svg-cat. What does it do? svg-cat is a tool for "concatonating" SVG files, such that the layers of each successively supplied SVG file stack to form a unified image. This is analogous to the command line tool cat which concatonates a list of files and renders them to standard output. Now armed with a complete suite of SVG command line manipulation tools, I wrote two scripts for working with the now unwieldy sprite.svg: anomize and merge. atomize takes the sprite.svg file and creates an individual SVG file for each layer, a la svg-select and svg-layers. merge takes these layer files, sorts them with the sprite topological sort rules, and reconstitutes them into a single graphic, a la svg-cat. This enables efficient augmentation and editing of the sprite graphic, because now I can pare out the layers that I want to work with (for example, heads if I want to add wigs), add the layers I want, atomize that graphic, then merge, and buildall. Now I don't have to do tedious manual sorting or tedious manual hiding of irrelevant layers. Also, I can now do spot checks of numerous layer configurations by automatically generating graphics from the newly constructed master image and making sure that the layer sorting rules are doing their job correctly. All of these scripts are in the Tale repository in https://cixar.com/svns/tale/bin and https://cixar.com/svns/tale/art/sprite.

In the process of developing this utility, I spent 90% of my time hunting and killing a single bug, propagated by Inkscape. Inkscape decided that it wouldn't render randomly selected cells if the loaded file was saved by a previous version of Inkscape, which hadn't the courtesy of adding an inkscape:version attribute to the SVG file. This problem had to be fixed in a text editor (gvim) since Inkscape wouldn't migrate the file properly. Furthermore, the problem had to be found by a binary search by selective replacement between a "corrected" and "flawed" version of the same graphic. I think I might file a bug report.

Llamacorn

Sunday, January 14, 2007

Tale Rides Continued

Today I fleshed out some more graphics for vehicles and rides. In particular, I applied the same filtering mechanism that I used for mallards to produce some graphics for various permutations of the rodent mount from the general purpose sprite graphic. After I got that done, I moved on to constructing some graphics for land vehicles like SiegePlatypus, TrojanBadger, SteamCastle.

Mallards

For the last couple weeks, I've been working on artwork for Tale, the MUD, you know. That is, two weekends ago, I got back from visiting the family down south and had an itch to make something, so I've spent all of my off-time since scratching my brain and mouse-pad with fervor. The first thing I drew was a multi-layer sea and sky vessel graphic, the Mallard. The Mallard is one of the seminal concepts for Tale, a Norse style galley with steam and blimp upgrades. It's the focal point for blending a mediaeval theme with a fantasy theme with a Victorian sci-fi (steam-punk) theme. I finished it, cranked out some permutations, called it amazing, and moved on. Since then, I've populated a wiki with bunches of monsters, items, and game design memes.

Today's project was to finish writing the automation for generating permuations (sail plans) of the Mallard. To that end I did a bunch of technial stuff. Skip to the next paragraph if you don't care about technical stuff. The mallard graphic proper is a single SVG file with something like 120 layers. These layers include such wonders as "mizzen-top-gallant-yard", "bow-jib-outer-sail", and "sweeps". Constructing a mallard graphic is a two step process replete with danger. The first step is to filter the graphic for the desired layers. I've constructed several layers files which include all of the necessary layers for a particular sail plan. The second process is sorting those layers to preserve the three dimensional illusion. To this end, I have several sets of "rules" for sorting the layers, rules like "the yard arm is behind the mast", employed exhaustively and brutally. There's one set of common rules, one set of rules for ships that appear to be sailing away from the observer, and one for vessels that appear to be sailing toward the observer. Using these rules, I construct a "digraph", merely a set of layer names associated with layers that are known to be behind them, and then perform a "topological sort" on those layers. I do this all with the command line, so constructing boat-100.png looks like: cat mallard.svg | svg-filter boat.layers | svg-sort rules boat.rules | rsvg -w 100 - boat-100.png. That process applied iteratively renders our 29 (so far) selected sail plans. I can't wait to play a game where these vessels are set in bitter competition and players scramble to arrange their sails to catch the wind and their prey or their daring escape.

So, here, in all their glory, selected permutations of a mallard.

Mallard Ship