Wednesday, February 18, 2009

Project Report: BookMaker




Okay, this is a quick little project that I started on yesterday, and finished today.

As many of you know, I've taken to doing a lot of my original writing in Google Docs. It's convenient because I've got easy access anywhere that I have internet access, and I don't have to keep track of which version of my document is the current version.

The drawback is that nobody really wants to read a book on Google Docs, so if I want any feedback I've got to print it out. And as you probably already know, Google Docs is not friendly for printing.

Of course, my ultimate goal is publication, and while friends and family can probably live with the endless scroll of a Google Docs print job, I need something more polished for editors and agents.

What I've been doing is maintaining two copies of the document. When I finished the book, I copied everything from my working copy online into a Word Document as a reading copy. Since then, whenever I wanted to make changes (adding conversations to clarify plot points, or just fixing typos), I had to make sure to make the changes in both documents, and that's a pain. My other choice was to just keep updating my working copy, and then every time someone asks for a reading copy, I have to copy everything back into the Word Document and clean it up all over again.

To my delight, Google provides a Python library that makes it easy to login, access all my Google Docs, and even download and modify the contents of them from within Python. To simplify the maintenance process (and for future convenience), I wrote a program that would fetch a document by filename, then parse the HTML and feed it into a Word template. To maintain text formatting I had to do a little cleanup afterward (removing HTML italics tags and using Word's Selection object to italicize the contained text, that sort of thing), but mostly the template and the HTML parser handled everything.

To make this work, I had to use two special libraries -- Google's gdata, and win32com, a library that lets me control Windows applications from within Python (in this case, Microsoft Word). I learned a lot about both libraries over the last couple days, and I'm excited about how much they can do.

Right now, the program is capable of formatting the document into any of three templates: a Reading Copy with narrow margins and small font to keep printing prices down, a Markup with wide margins and double-spaced lines for easier feedback, and a Submission in Proper Manuscript Format which is pretty ugly to people accustomed to typeset pages, but apparently it's popular with the editors. It's nice to be able to quickly generate any of those looks, without having to separately maintain the content.

There's a limit on the size of Google Docs, and I've bumped into it with a couple books, so I'll eventually want to add multi-file support. I could also make a GUI client so it would be easier to enter a username, password, and document title (right now you just edit the script directly). None of that is necessary, though. Even the multi-file stuf can be handled with a quick copy-paste in Word.

So I'm calling this one finished at version 1.0.

Status: Stable, v. 1.0

Thursday, February 12, 2009

Project Report: My Constant (iPhone App)

Last night, while talking nonsense on our trip to Best Buy, D-- and I came up with an idea for an iPhone app that would probably make millions.

Specifically, I was complaining about everyone on Lostpedia going on and on about the need for the characters (until last night, at least, unstuck in time) to have Constants to keep them from dying of time sickness. (If you don't watch "Lost," none of this post will make any more sense than that sentence did.)

Anyway, the only life-saving Constant that we've seen in the show so far has been a loved one, specifically Desmond's girlfriend Penny, who was present in his life both before and after he became unstuck in time.

So with the obsession (among the most obsessed fans of the show, I guess I should say) over the concept of Constants, we decided it would be a good idea to write an app that allows people to mark somebody they know (or something precious to them) as their Constant.

Of course, it wouldn't actually do anything, but for a lark, I think it could be fun. I'm also working on ideas for some support documentation to include with it that could make it a pretty funny toy (like a checklist for what to do if you think you've become unstuck in time, or instructions on how to charge your iPhone if you find yourself in the Middle Ages -- stuff like that).

Status: In Design

Project Report: Ghost Targets: Expectation

As I said in my Gods Tomorrow post, the Ghost Targets books are sequels to Gods Tomorrow, and anything I say about them could certainly qualify as spoiler material for the first book. So if you plan on reading it but haven't yet, don't read the Ghost Targets project reports.

Anyway, I've done some good work on Ghost Targets: Expectation this week (the first sequel). I already had an opening scene, much like the one in Gods Tomorrow, in which we see the moments after the crime that sets the novel in motion, from the criminal's viewpoint. It's less than two pages, but introduces the storyline.

This week I finally wrote up a scene that's been pretty clear in my head for nearly a month now -- Katie's return to the Ghost Targets office, and the reaction of her coworkers there (as well as her assignment to this new case).

Basically, that's the first chapter. Carlos just finished reading Gods Tomorrow a couple weeks ago, and he's been giving me phenomenal feedback. I offered to let him read the first chapter of the sequel as a sort of teaser (with the clear warning that it could easily take me until next November to actually finish it), and he was anxious to do so.

So I have that done. If anyone else is interested in seeing it (with the same understanding), let me know and I'll get you access.

Status: Writing, First Draft

Friday, February 6, 2009

Project Report: Midas


So that just leaves Midas, my most recent project.

Okay, some of you have read Gods Tomorrow already, and you're not allowed to snicker. I needed a name, I had just finished writing the book, and it was an easy grab. I don't have delusions of grandeur or anything, I just had to call it something.

Anyway, starting...I don't know, two or three years ago -- maybe even four -- I discovered our family's finances were too complicated for me to keep track of them in my head (or even just online) and finally started for the first time trying to keep a balanced checkbook.

We didn't bother trying to do it in a checkbook, though, because we've never really paid for much of anything with checks. Instead, I pulled up an Excel spreadsheet, stuck Sunday in the far left column and Saturday in the far right, and made a copy of that tab for each week in the month. Then, on the first one, I plugged in our starting bank balance on the first page, and on each tab after that (and each new spreadsheet, as month rolled into month) I would import the ending balance from the end of the previous tab.

So I had two columns for each day of the week, and I would put dollar amounts in the first column (positive for deposits and negative for debits), and then a brief description of the transaction in the second column ("Groceries at Wal-Mart" or "Cash at ATM" or whatever).

Then every six months or so we'd hit a financial crisis, and after the dust cleared I would go back and try to figure out where all our money had been going, so I would open up six months worth of spreadsheets, and manually find and add all of the Grocery entries from the spreadsheets to a column in a new one, so I could do a report, and the same for all the allowance expenses, and bills, and so on. It was always hours and hours of work, and I knew there should be a better way (which I assumed had to do with using Access instead of Excel), but I never felt like putting in the time to design a database -- and learn how to use it.

Well...that left me making a new spreadsheet every month, copying over an old one and going through manually to reposition dates and paydays and whatever might have changed, and then filling it out every couple days. In December of last year, I'd already worked ahead for a few months to get a financial prediction, so I probably had forty-five or so spreadsheets, spread across the years, tracking our financial history (and with predictions into the future so I could schedule credit card payments and budget long-term expenses like car repairs), and all of that was stolen when we were robbed.

Ugh.

I had a backup from November of 2007, but it wasn't much help. Our regular monthly expenses had changed enough since then, as well as some of my format, that I didn't much feel like putting in the work to revive a shambling, unpleasant system anyway.

I figured what I should do was learn Quicken or Microsoft Money or something, but in that first week after we were robbed, the not knowing about our finances kept getting under my skin.

So one day, during lunch, I decided to see what I could do. I threw together a quick GUI in Python's built-in GUI manager, and with less than twenty minutes I was able to make it look pretty much exactly like my Excel spreadsheets had. Then I grabbed some sample data -- we had closed out our old account as an aftermath of the robbery and started a new one, so there was a pretty small set of data to get me fully up-to-date, which was nice. I built a rough database, threw that information in there,, and within an hour total I had it navigating week-to-week, and displaying a Transactions database as though I had entered it all manually on one of my old Excel spreadsheets.

Of course, the real benefit was that it was no longer a spreadsheet, but a real, relational database. Even if it looked the same, I could easily write a one-line query to grab all of the "Groceries" entries in the database for the last month and give me the total we spent on it. What I used to do over the course of hours could be done in seconds now.

I worked with it more, polishing the GUI more than anything else, over the course of several weeks. I got lots of help from K--, who is a SQL master, and some from Toby without actually telling him what I was up to (not that I was deliberately keeping it a secret, but it never came up). Anyway, I completely redesigned the database a couple times, adding tables and replacing names with IDs and all the sorts of things a good SQL administrator does to optimize performance.

One cool thing I did was implement "virtual accounts" (I call them RollingBalances within the code), for things like allowances and those long-term car repair savings. Basically, every week I allot (as an example) $80 for groceries, $80 for entertainment, and $30 for gas. If some of that doesn't get used one week, it probably will the next. This is even more true for things like our allowances ($80 a month, each), which we sometimes save up for larger purchases, or car repairs (also $80 a month) which might accrue for months before it disappears all at once (and then some) as soon as we have to go to a mechanic.

We don't do the coffee jars or envelopes techniques for this money, and we certainly don't have multiple bank accounts. We just keep it all in one big balance in our checking account, and I would try in vain to track what was spent where, out of which balance.

My new software does all that for me. Every week I do a handful of cash transfers into our weekly RollingBalances (groceries, gas, entertainment) and on the first of every month I do the monthly ones (allowances, car repairs, and gifts), and as soon as I do that, my total balance shows that the money has been spent, so I won't budget it for anything else. Then any money spent out of the RollingBalances (as long as their total is still positive) comes out of them but not out of my total balance. If the RollingBalance goes negative, though, that extra is taken out of my total balance. It works really well.

It also lets me print out a report of the total in each of those RollingBalances, which I have as a separate frame at the bottom of my main GUI. It makes it easy to keep track of where our money is going, every time I open it up.

I also use something called Virtual Transactions. In my old spreadsheet days, I would mark future entries (like a guess on what next month's electric bill is going to be) with a yellow highlight, so I would know that entry still needed to be corrected. Then, once I got the bill, I could schedule a payment for the actual amount online, and then correct the entry in my spreadsheet and change it back to no highlight, or a white background.

I preserved that functionality in Midas, by putting a boolean flag on every transaction of Virtual. If a transaction is Virtual, it automatically shows up with a yellow background in the program. If it's not, it's got a white background.

That's helpful to me when I'm analyzing the report, but it gave me some other options, too. The biggest one is that I can print out a constant "Actual balance" which only takes into account non-virtual entries. That way I can look forward three week and see what our calculated balance will be if we make all of the virtual transactions I anticipate (including deductions for allowances and whatnot), but I can also check at a glance to see what our actual balance should be right now, and confirm that against my bank's website. It's very cool.

That's where the software is now, and I've been using it regularly since late December when I got it to that state. I've made a few small tweaks in the meantime, but nothing dramatic (apart, of course, from updating the database with our regular transactions).

Oh! I did make a big change this week. I automated so that whenever I browse forward to a week I haven't visited yet, it automatically asks me if I want to install some default transfers to my RollingBalances. Same thing when I visit a page that has the first day of a new month on it -- if there's no transfer into our allowances or car repairs on it, the program automatically asks me if I want it to fill them in. Very nice.

I'd like to add copy and paste, because there's some very common expenses that aren't quite common enough to automate that way. I'd also like to clean up the GUI some, including a major conversion to add the option of a ledger-style interface as opposed to the calendar-style I've been using. Something that would be really nice is cell-phone-friendly web reports, but I've been told it takes some complicated work to get a webserver running, so that might be beyond the scope of my interest.

I had a lunch with Toby early last month, and as I was briefly running through the list of all my programming projects, this was the one that caught my mind. So I sent him everything I had so far, and he immediately had some great suggestions, and even volunteered to get to work on one of them, but right after that he got sick for a week.

So I expect I'll continue to see some progress on this one, even though I don't really take it as seriously as I should. Still, K-- and Toby both continue to show interest in it, and they're precisely the kind of guys I expected to say, "There's already a thousand of those programs on the internet, just use one of them." So maybe this is worth my time after all.

Status: In Development

Project Report: OBDMultibox and WoWCast.ahk

Sometime in early 2008 I realized I wasn't really playing WoW anymore, so I canceled my accounts, and went a good six to eight months without playing at all. I didn't even really miss it, except as a coping mechanism for other unpleasantness (which I discussed at length, on several occasions, on this blog).

I did have high hopes for several other games (chief among them Spore) which all managed to disappoint, so that's part of what drove me back to WoW.

Another was just absence making the heart grow fonder, as it is often accused of doing. Over the course of the summer, news stories about WoW on Digg or Ars Technica often caught my attention, and more and more they made me think fondly on my experience with the game. Then, too, there was the content of those stories, which generally focused on the upcoming (at the time) Wrath of the Lich King expansion, and I'd just sort of always assumed I would reactivate my account when the expansion came out, if just to try it out.

So all of those were factors (and improvements brought with the expansion are actually the main reason I stayed in the game), but the number one thing that drove me to reactivate my account in the first place was multi-boxing.

Multi-boxing is a term used to describe playing a game with more than one computer (or "box") controlling more than one instance of the game. It's most popular in MMOs, because generally there is an advantage to having more than one character grouped together, but a given account can only have one character logged in at a time.

There's a similar process called "multi-instancing" where you play more than one instance of a game on a single box, and the only real difference is the complexity of the setup. What I do is actually "multi-instancing," but the former term is much more common, and often used as an umbrella. I will do so through the rest of this post.

(If you're already sick of hearing about multi-boxing -- and I wouldn't blame you if you were -- you're not going to like the rest of this post any better, so feel free to move right along.)

Anyway, over the summer while I was out of the game, my brother-in-law Graham ran my account briefly, genuinely multi-boxing, with one of my high-level healers running around with either his hunter or warrior, keeping them topped off with health while they did whatever it was they were doing. He had a lot of fun with that setup, and I must admit even then it sounded tempting.

Then later in the summer, maybe September, my brother-in-law Jeff got access to my parents' accounts (which were idle at the time) and some software designed to really make multi-boxing easy by providing full control for two characters within one game client. He was playing two Paladins together, and having a blast. The more I heard about it, the more I wanted to try it out.

So, for all these reasons, I reactivated my account about a week before the expansion came out, and three or four days later I also reactivated K--'s old account, which had long been in my possession, to give me a second character to team up with. The complexity of multi-instancing is trying to find some way to make sure some keystrokes control one of your characters, and other keystrokes get through to the other instance of the game and control that character. The most popular way to resolve this is to play two identical character types and and duplicate every keypress to go through to both games.

What I did instead was download and install a free program called AutoHotKey which gives you full control of all the user input, and lets you run commands and/or reroute any input before it reaches running programs. (To do this, I had to learn yet another scripting language, one designed just for AutoHotKey, but it's a much smaller language than Python or LUA, and I only need to know how to do a few simple things, so it wasn't such a big deal).

Anyway, I wrote a script that would identify any open instances of WoW (on the assumption that there would be two), and then capture any keypresses and send them to the first instance of WoW unless I was holding down Alt at the time, in which case it would send the keypress (without the Alt) to the second instance.

That was pretty effective, but tiring on the fingers.

One technique that's basically always used in multi-boxing is a /follow command. Basically, you almost always pick one character as your leader and another as your follower, and then you bind a keypress on the follower to automatically /follow the leader -- an in-game command that will make him try to follow wherever the leader goes (with some limitations). One problem is that the follower can easily get caught on objects (like steps up to a building, or logs mostly buried in the sand) that your leader steps right over while you're holding the Up arrow to walk.

So, to deal with that, and to manage the other necessary macros used by a follower, I created a WoW Addon which I called OBDMultibox. Originally it was OBD, but the short name was conflicting with some other process or Addon or something, so I added Multibox to make it clearer. OBD, by the way, is short for "Other Brother Darryl," which I find hilarious but T-- is the only other person I know who even gets it, and she doesn't find it very funny....

Anyway, I digress. This Addon started out as a very simple one: a single button, near the center of the screen that shows up on the leader's screen and, when pressed, activates the follower's /follow command. That saved me a spellbar spot, because I could use a mouseclick instead of a keyboard command, and so freed up the keyboard command for something more important (like a fireball). I also color-coded the button to show me constantly if the follower is still following, or if he had stopped (usually, as I said, because he got hung up on something).

Then I added some functionality so that, from the leader's game client, I could type a chat command and it would instantly send a group invite to the follower character, and then send a whispered message that would cause the follower character to automatically accept the invitation, and then the leader character would change the looting options to Free For All, all with only one mouse click from me. Awesome.

But, as I hinted above, I quickly got tired of the Alt-button trick, and decided I wanted something cleaner. I spent some time working on macros so I could clean up my spellbar, and then narrowed it down from 12 to 6 keys that I needed. Then I put those, on my leader character on the odd-number keys, and did the same thing with my follower and put them on the even-number keys. Then I rewrote my AutoHotKey macro to start repeating all twelve of the keys to both instances, so I don't have to hit Alt anymore. Instead, it sends odd and even numbers to both, but each instance only responds to one or the other.

And then I really got fancy with my Addon. I had it, on both ends, get a list of all the texture files on each button on the spellbar (the unique name that the game used to look up the pictures displayed there), and then the follower whispered a list of all his textures to the leader, and vice versa. Then, I drew smaller copies of each of those icons on the spellbar in the correct place for the other character, so when I'm looking at my spellbar for my leader, instead of having my normal spells on odd numbers and blank spaces on the even numbers, I have my normal spells on the odd numbers and my pet's normal spells (at 2/3 size, so they're obvious to spot) on the even numbers. So, at a glance, I can know exactly what I will cast if I press "4," even though it's actually casting the spell in a completely different instance of the game.

I started working on this in mid-November, but didn't really pick up speed until early December (because of NaNoWriMo). By mid-January it was working pretty stable, and I'm using it pretty much daily now.

I'm still having some problems with the timing, becaus the leader won't always auto-set the loot method (which is annoying). I'd also like to find a clean way to pass mouse clicks through to the follower client, but that has proven a real puzzler. Right now, as a workaround, I just Alt-Tab to the follower client whenever I need to use the mouse to loot an item or talk to a quest-giver. I hope to eventually revive the Alt tactic, passing Alt-clicks through to the follower client, but I haven't felt any real drive to wrestle with that in several weeks.

For the most part, this is a complete project that I'm pretty happy with. It makes my life a lot easier, and multi-boxing WoW has made it a lot of fun, for several months now.

Status: Stable, v. 1.0

Project Report: Travelocity Researcher


Travelocity Researcher is not quite so old, dating back to mid-2007, but it's still a dusting-off of a project I thought finished and forgotten.

B-- contacted me about almost two years ago, as I said, explaining that, as part of his work, he had to compare Avis's rental rates with their competitors every day. To do that, he used a simple Travelocity search, but even with the information available, he still had to record it somehow (and if you've ever tried to copy and paste a table off a web-page, you know how excruciating the next step (formatting) is.

So, with much help from K--, I put together a a script that would perform the three searches automatically, asking Travelocity for rates on an immediate short-term rental, an immediate long-term rental, and a long-term rental sometime in the future. It then parsed the info it got back from Travelocity (using regular expressions) and used tabs (and truncated strings in a lot of cases), to print out the information to a text file. If you opened the text file, it looked like a nearly-organized chart, with rows and columns.

At the time, B-- had asked me how hard it would be to get it converted so people at other locations could use it (currently it's hard-coded for the OKC airport), and I said, "A little bit hard," and that was the end of the conversation.

Then I guess a couple weeks ago B-- got an email from someone else in the organization saying, "Hey, I'd heard you were using this script, and I was wondering if your programmer guy could make it work at other locations," which is essentially the same question I got two years ago, but times have changed.

Specifically, with the economy as it is and travel-related businesses particularly hurting, employees at Avis need every edge they can get just to stay hired (or, as a completely outside observer, that's the impression I get). So I figured B-- handing over the keys to a major efficiency improvement for people company-wide would be a real feather in his cap.

And, to my surprise, when I opened up the script I wrote for B-- oh-so-long ago, I discovered it still worked. I hadn't even looked at it in the intervening time, but the design was pretty simple and straightforward, and mercifully Tavelocity hadn't done anything to break it.

When I started thinking through the best way to make it portable, though, I came to a certain realization. You guessed it: I needed to build a GUI (which, in case you don't know, is ASS). As I said, the old one you'd just double-click, and it would pop up an hourglass cursor for forty seconds or so, and then there was a text file there. That was the whole program.

This time, I went all-out. Running the program opens a window with three search panes (and the Travelocity logo for that polished look). You can open an old file and the program knows how to display it in the three search panels, or you can run a new search, and it will populate the panels with today's data. It also color-codes the data for an at-a-glance comparison to Avis's prices. Then you can save the data from the File menu (just like any other Windows program), and for an extra touch, I learned how to output to Microsoft Office products.

So instead of just writing out a text file with a faux table built out of tab spaces, You can now print out the three searches to an Excel file with separate worksheets for each of the three searches, which also gives you all of the extra functionality available in Excel.

Then I added a Preferences tab, which lets a user enter an airport code (for the location customization that was the only thing I actually needed to add), decide whether or not to include the color-coding when writing to Excel, adjust both the length and start date of each of the three searches, modify where it saves files and what types of files it saves by default, and control web access settings (specifically the timeout length and max number of retries).

And then I had to make all that work. It was no small task. Oh! And save these user settings from instance to instance.

And then I went in and added another script that, using the options stored in the user settings file, just pops up an hourglass for forty seconds or so, and then creates the output file (without ever opening a window), because ultimately that's all you'll want to do.

All of that is done. It's amazing. I'm now in the process of releasing it, which requires two things: user documentation and byte-compiling. For the documentation, I built my own Help system using dialog boxes and some faux hyperlinks, and now all I need to do is finish writing the content (which is about half done). It's the compiling that's giving me real troubles.

There's some software out there, py2exe, which is a free library for all versions of Python. What it does is read through your Python script, find out all of the modules you use when the script runs, and then package those up in a zip file and generate a Windows executable (.exe) file that can draw information out of the zip file. So instead of requiring everyone who uses my program to install Python, I can just have them download this executable and the library zip, drop them in a folder, and run the executable the way you would any other Windows program.

Nice and neat. Except that it doesn't work.

I'm encountering a bug right now that appears to have to do with Python 2.6 specifically (althoug a quick effort to use py2exe with Python 2.5 didn't yield any immediate fixes). What appears to be happening is that the executable works fine on my development machine, or any other computer that has Python 2.6 installed, but won't work at all on machines without it (which makes the whole process of compiling it a complete waste of time). We've used py2exe before with no problems, so I'm sure there's a solution, but it's going to take me some time and frustration to get it figured out.

Still...I'm at the tail end of this project. I could always add more functionality later, but this is a pretty polished package already, if I can just get it compiled and shipped off.

Status: In Development

Project Report: Movie Hoard

Movie Hoard is another old one, this one dating from June of 2006. It started out as the Streamload project and then was later renamed Syndicator. Streamload was a web-storage service that offered great rates on large datasets, so we got together and wrote a program to let us use it as an off-site source for all our media files. We wanted to keep things legal, though, while still having easy access, so we needed to encrypt everything we uploaded to keep the RIAA and MPAA off our asses, as it were. Once the files were up on the Streamload site pretty much anybody could download them, but we were the only ones with the decryption key necessary to turn them back into media files.

That probably sounds like a lot of hassle to watch a backup of The Waterboy while you're on travel for work, and it is. To clean things up, we wrote a massive program that would handle everything -- it tracked a database of everything we had uploaded, including extra information such as Artist and Album for songs, or a list of Actors and a Plot Synopsis for TV shows and movies, it scanned our computers for media that needed to be uploaded but wasn't yet, it handled the uploading, encrypting the files before sending, and then handled the downloading, decrypting them as it went. And, of course, we had to build a GUI so we could browse our database, pick the file we wanted, and then download it from Streamload.

Unfortunately, while we were busy buliding the most reliable and useful software project any of us had ever worked on, the Streamload service itself was busy undergoing a total breakdown. We got a good year out of it, but in the end it failed and we all stopped using the program.

Then, a couple months ago, K-- brought up the spectre of the old beast by commenting on what a useful tool the indexer was -- that's the bit that scans our computers, finds media files, and downloads all the extra info from a handful of internet sources like IMDB and TV.com. Even after Streamload died, K-- was still using our program just to index the media files on his own computer, and keep track of where everything was.

We spent an evening discussing it, I think in December, and decided it wouldn't be all that hard to prune out all the uploading and downloading and encryption stuff, and just make it a local media indexer. As part of that discussion (and the email threads that followed it in the next few days), I mentioned that nearly all modern media player software includes some type of indexer and lookup, and I was wondering if we could find one (whether it was mPlayer or Windows Media Player or even iTunes) with a plugin language we liked and learn how to just plug our data into the existing media player.

And then, like a bolt from the blue, I rediscovered XBMC. I went over this in a Journal post a day or two ago, but XBox Media Center was a homebrew application for modded XBoxes that allowed them to play pretty much any media format, and we've all been using it for years. Actually, most of the time we would download files using our Streamload client (back when it worked), then play them over the network on our modded XBoxen.

In the last four months, though, all my XBoxen have died or been stolen. I was busy lamenting that fact one day when I decided to check on the status of an old project to port XBox to Windows. They brought it to Linux first, and then Mac, but lo and behold, these days there's a functional (if not entirely stable) build for Windows. Not only that, but it now supports "Plugins" in addtion to the "Scripts" that I used to write.

Plugins, in this case, are Python script-driven menus within the main XBMC client. What that means is I can use Python to read our Streamload media database, use Python to format all of that into a list of movie files or songs on a local server, whatever, and then provide that list to XBMC to show just like it would a list of files if it were browsing my hard drive. The big benefit there is that I don't have to build a GUI. Building GUIs is ass, plain and simple. In this case, I just format my data however I want, then hand it off to XBMC to display.

While I was busy making that discovery, K-- and I were both trying to figure out how to get the old software working, because it was built on a Python GUI package (PyQT) that was obsolete and unavailable now, and none of us were still running machines with it installed. So, even though pruning out the downloading and encryption stuff was supposed to be a simple project, we had no way to actually show any of our results until we built a whole new GUI (which, as I just told you, is ass).

So the two discoveries merged, and Streamload became the Movie Hoard plugin for XBMC. So I started working through some tutorials to figure out how to format the plugin, and K-- started querying Google to figure out how to access a SQL database in XBMC, and as of last weekend, we have a plugin that will read our old Streamload database, display results based on whatever search parameters we want to use, give us access to all that additional data we have stored, and do it all with the same simplicity of use as browsing a local folder directory in XBMC (something we've all done thousands of times).

We haven't plugged in the last step yet (where pushing "OK" actually launches the file), but that should be a relatively trivial task. We also need to write some extra stuff to handle filters and sorting, but that's mostly a port of code we wrote for the old Python client. Then I have to undergo the major task of actually indexing all my data, because K-- has been doing it for over a year now, but I haven't been running the software at all, so it'll be no small feat to get my library imported into the database.

Still, it's all good. Every roadblock we've encountered so far, we've found an answer to. This, frankly, isn't my absolute top priority, or it would probably already be done. The next month will probably see some major progress, and I'll keep you posted.

Project Report: TourGuide

I started TourGuide in April of 2006, when we were all leveling our second and third (and in my case fourth and fifth) characters to 60 in WoW, and someone (I think it was K--) stumbled across a fantastic questing guide by Jame of WoW-Pro. It included a step-by-step process to get your character from 30 to 60, and made sure you visited every corner of the world and completed all the most interesting quests along the way. Not only did his guide encourage you to explore areas and participate in storylines you'd probably never experienced before, it did that in a much more efficient way than anything any of us had come up with on our own.

So we all started following the guide when leveling our alts, but it became something of a pain to Alt-Tab every time we needed to know where to go next (and something of an expense to print out so many pages), so I found a way to bring that information into WoW.

First, I converted every direction in the guide into distinct steps, then I narrowed those steps down into a small set of types ("Go to," "Get Quest from NPC," "Complete Quest," "Turn in Quest to NPC," "Turn in Quest and Get Follow-up" and a few more). I copied these into an Excel spreadsheet, going through the original guide line by line, and reformatting everything he said by hand into this spreadsheet.

Once that was done, I saved the spreadsheet to a CSV file (computer-readable text file, basically) and then used a Python script to read it in, and write it back out as a LUA file that just constructed a massive table containing all of the steps, in a form that a WoW Addon could use.

Python is the scripting language I use most, but WoW Addons use a different scripting language called LUA. So here, in this one project, I'm hand-coding an English web-page into a pseudocode spreadsheet, then using one scripting language to convert the contents of that spreadsheet into code for a different scripting language, which will be interpreted by WoW.

Oh, and then I had to display it in WoW somehow. For that, I wrote the actual Addon, using LUA and XML (for GUI elements and layout). I finally settled on a pretty simple frame in-game, that showed the current step you're on (with all the code translated back into English), as well as where the guide thinks you ought to be, where your hearthstone should be set, what level you should be, and some buttons so you can move forward or backward through the guide. And then the Addon had to save all of that information, separately for each character, so that when you log out and log back in you still know where to go and what to do.

As I said, I started on this back in 2006, and when the Burning Crusade expansion came out, it completely broke the Addon, as well as adding new zones so that the 30-60 guide wasn't really all that useful anymore (we all had a handful of 60s by then, and everyone wanted a guide to get them from 60-70). So I spent a couple months getting it working again and incorporating the new content.

Well, that's why I'm talking about a three-year-old project here in this post. In November, the second expansion to the game came out, Wrath of the Lich King, and it did the same things to my Addon all over again -- broke its functionality, and obsolescenced its content. So I spent some time getting it working again in November and December, including adding some new functionality. It now presents the most recent informational Note in addition to the text of the Step you're currently on, so your step might say, "Go to the Emerald Dragonshrine, Dragonblight (45, 27)" which is a long run to the northwest, but right below that is a copy of the recent step which said, "As you run to the northwest, kill all the Kobolds you see along the way." That's a more common scenario than you might imagine. (Also, I completely made up those coords for the Emerald Dragonshrine -- don't hold me to them).

I have currently updated the content up through the fourth out of seven or eight zones, but had to stop there because the guy who writes my guides hasn't gotten beyond that. It's kind of frustrating. Anyway, it's still an active project, as I'll start working on new spreadsheets as soon as he releases the next installment of his guide, but I'm pretty happy with the UI right now, so that's probably all I'll be doing. I haven't really done any new work on TourGuide since early January.

Status: Stable, v. 3.0

Project Report: Programming

Now, with the Gods Tomorrow sequels, I intend to do separate posts for each individual book in the future, but because I've been lax up to now, I wanted to do one bulk post to use as a starting point.

I intended to do the same thing with my programming projects, but somewhere around the end of the second project (out of five) I was probably already pushing fifteen pages, so I decided to break them up. So this is just an overview introduction.

The current programming projects I'm working on masquerade under these titles:
  • TourGuide is a WoW Addon that helps players level character faster by following ideal quest circuits in-game.
  • Movie Hoard is an XBMC Plugin that indexes all my various media files, downloads supplemental data wherever possible, and presents it all in a fast, easy client in XBox Media Center.
  • Travelocity Researcher is a web scraper the gathers rate comparisons for rental cars on Travelocity.com and saves them in an easy-to-use file format on the local hard drive.
  • OBDMultibox is a WoW Addon that facilitates "multi-boxing," which is the process of controlling two character in-game at the same time.
  • Midas is financial software that tracks my spending and helps me predict my future financial status, as well as monitoring "virtual rolling balances" such as allowances and car maintenance balances within my single bank balance.
I'll take them in that order with individual posts.

Thursday, February 5, 2009

Project Report: Gods Tomorrow

Last October, during a brief chat with D--, I came up with the idea for Gods Tomorrow, a near-future sci-fi murder mystery that I ended up writing as my NaNoWriMo project. It takes place in a world where we as a culture have traded our privacy for the convenience of a mega-database that tracks everything we do, and offers services based on the near-omnipotence that data provides.

Specifically, it's the story of a girl who joins an FBI task force dedicated to tracking down criminals who are able to exist off the grid, outside the database.

Since I finished it, five people have read it, and a couple more are currently in the process. Of those five, I've only heard positive reviews overall. (Naturally there has been some constructive criticism, but the general reception of the book has been overwhelmingly positive.) Based partly on the constructive criticism, and partly on my own opinions as the book evolved over time, I've gone back and done three small revisions, mostly adding conversations early in the book to lay sufficient groundwork for developments later.

There are two major changes I'm still considering making, which would change the...I don't know, feel of the book, without fundamentally changing the plot. They would also take a pretty significant investment (of time, as well as mental and emotional energy), and even though I'm confident that both of them would be improvements, I'm not yet sure that the benefit will offset the cost. So...meh, I dunno. I may do a big fancy rewrite, or I may leave it as-is.

That's Gods Tomorrow.

As I got into the project, though, I found myself thinking more and more that it felt like the pilot for a TV series, more even than the first novel in a series. For a while I seriously considered doing the research and trying to figure out how to pitch a TV series (and I still haven't wholly given up on that), but for now I'm actually just aiming to write a series of books that feels like a "Law & Order: Future Crimes" spinoff.

So, in that vein, I'm currently working on two sequels to Gods Tomorrow. The FBI task force I mentioned earlier is called "Ghost Targets" (because "ghosts" is the nickname for people who are invisible to the database, for reasons demonstrated in the book), so for now I'm toying with the idea of using that as the series name. Ghost Targets: Expectations will be the second book in the series, wherein the Ghost Targets team learns of a murder at the clinic where the miraculous anti-aging drug is under development (and where, for reasons of international competitiveness, the database is not allowed to record). Drama ensues.

That one I'm excited about. I've got a full plot synopsis (three to five pages) including all the key plot developments, the main characters, and their various motivations. In other words, I've got the groundwork for a whole novel there.

The third in the series, Ghost Targets: Momentum, is just a rough sketch by comparison. It's about football in the future. What more can I say? I have a page and a half done -- the opening scene -- and no prewriting. I don't really even have names for the characters. I've come up with a couple suspects and an actual killer, without even having a clear idea who the victim is. The writing process is a weird little beast.

I've also started kicking around ideas for one about video games, probably Ghost Targets: Diversions, but I haven't even gotten as far as the actual crime, let alone the players and plot of it. I know the mechanic by which the killer will be a ghost, though....

That's the tricky bit. I've established a world where there's virtually no way to get away with a crime, and then set up my series to follow the detective who investigate people who do get away with crimes. So I have to, at the same time, impress my readers with how cool and effective the system is, and find loopholes in it for my occasional thieves and murderers to slip through. Once I get to season two, it'll be a little easier because of the larger plot arc that drives season two, but the first five books are going to be kind of gimmicky. And I'm accepting that, but I'll have to find some way to keep them from feeling gimmicky to the reader.

It is my intention, in the next week, to get my promotional material for the first novel completed and mailed off to my agent, so that she can get started trying to sell the series while I get involved in the nitty-gritty of trying to sort out sequels.

That's the current state of things, when it comes to Gods Tomorrow and the various Ghost Targets books. I'll keep you posted as things develop.