Saturday, February 28, 2009

Local vs. Global

In my quest to remain informed about the world around me, I've subscribed to a great many blogs, newsgroups, news sites, etc. I've found that I'm a little too plugged in with too much to read. When culling said sources, what metric do I use to favor one over another?

A quick thought is that I look at these sources as local vs. global. I don't really care what happens over in Massachusetts (I can't even spell it right without computer assistance). They have their own state to do with as they please. But hey, the new light rail in Phoenix? That's actually affected me as far as traffic goes. On the flip side, I might be really concerned and pissed about a recent bank bail-out (and others), but has it really done a lot to affect me? I'd say no. It doesn't effect my day-to-day routine.

In an attempt to keep things more relevant, I've tried shifting my feeds away from the global sites that make like 5-6 long posts a day to local sources that update their feeds 2-3 times a month. Now I can skim through things much faster and even have time to delve into interesting topics.

I do think global events still matter, but there's so much going on that it's impossible to track. I'm best off getting a gist and moving on, instead of seeing every step of the way as the stimulus bill becomes law. I already knew the outcome, why am I still watching what it's doing?

Just to top this off with something lighthearted:
If you don't read the newspaper, you are uninformed; if you do read the newspaper, you are misinformed. - Samuel Clemens

Mythology - Free Stuff

Last night I sent a lot of time helping James Britt solve some issues with the Monkeybars app JotBot. It took a long time, and we finally got it sorted out. James was really appreciative for my help. Being the greedy, entrepreneurial individual I am, I felt like I had spent a lot more time than I wanted to on the problem. After all, I was now further behind on other tasks I had set out to do. James wasn't wrong to ask for my help, nor was I in giving it to him.

Then it sprang to me. Wouldn't it be nice if nobody had to worry about this again? As payment for Jame's sins help, I had him do three hail Marys write some documentation on Monkeybar's wiki page that details our struggles.

This is a huge help to me, because I spend a lot of time helping our users for Monkeybars and Rawr, but I don't get a lot of time to go back and document what went on. If I ask them to help me out by leaving a note for others, it can make life a lot easier for everyone, and furthers along these open source projects.

It may seem pretty simple, but I urge anyone with an open source project to request documentation/specs in return for the help. You helped the user, let them help you a little. It's not a lot of work to document something, and it helps ensure you won't have to help on the same topic again (just hand them a link). Others will just see the docs and come to help with more unique and important problems. In the end, everyone wins, and nothing is free (:

Ambition

Once I feel like I'm taking on way too much, my first thought is to look at how many things I'm trying to juggle. This time, I'm just going to list some of the things I've been wanting to do, and why I'd like to do them:
  • Rewrite Da Good Bitz - Good opportunity to learn more Rails, Glassflish, and have a web based army building app for Warhammer 40K
  • Is it JRuby? - I wanted to see what it would take to throw up a look-a-like for Is It Ruby 1.9? as per Martin Sadler's suggestion, where we'd have a list of working gems on JRuby, and perhaps a fun hall-of-shame to help pressure native gem writers to use FFI
  • Berzerk clone - Hash out collision detection in Gemini, and add another fun game to the list
  • Find a job - This can be a project in and of itself
  • Finish up obligitory work for Happy Camper client - Always keeping a promise implies we live in a world of absolutes, but we should keep'em when we can
  • Doc Browser - A Monkeybars app that allows for quick indexing and browsing of RDocs and JavaDocs, which would eliminate one more reason to have a web browser up in the workplace
  • JRuby specs - This will help the JRuby team fix my load of bugs that affect just me
  • Fix Rawr bugs/make Rawr improvements - Rawr needs love, and if not from me, then who?
  • Fix Monkeybars bugs/make Monkeybars improvements - Ditto
  • Paint all of my miniatures - They just look a lot better that way!
  • Be a good husband - As much as I'd like it to, this doesn't come automatic
  • Be a good father - Ditto
I should have this wrapped up tomorrow in several generations. No wonder I feel like I have a lot on my plate!

Writing these things down allows me to forget them at least temporarily, and then my load feels easier. I also can rest easy knowing that I won't lose a great idea (and all of my ideas are great!).

What's on your plate?

Wednesday, February 25, 2009

Rawr and build times

Rawr 1.3.x introduces a feature where the JRuby jar used in the project is the same jar that's used to compile the app. This way your projects can use different JRuby versions, and your environment's JRuby may also differ.

Unfortunately, the feature was mostly a hack because it needed to be fixed immediately for some of our production projects. It cleverly invokes the JRuby jar's jrubyc script to compile the files... one at a time. This can make compilation take 30 minutes (at least it feels that long) when compiling something with ActiveSupport and friends from a clean slate. I decided that I had traded some speed for stability, and the speed I could fix later. This became too painful once I started testing out some build bugs I was getting on Windows, so I fixed it.

Rawr now makes the same build in about 30 seconds from a clean state. That's a drastic improvement! I'd like to also visit some of the Java compiling to see what I can do to speed that up, since I know we compile one Java class at a time.

I'm not ready to publish these features yet, since I actually have regressed on a few of our other features.

Tuesday, February 24, 2009

Standard Miller deck

So far, this is what I have for my standard mill deck:

Island x 24
Millstone x 4
Swans of Bryn Argoll x 4
Plumeveil x 4
Memory Erosion x 4
Sanity Grinding x 4
Dream Fracture x 4
Jace Beleren x 4
Memory Sluice x 4
Ambassador Laquatus x 4

I first was trying to make a Merfolk deck that milled, but it hinged too much on having out Merfolk that individually didn't do much, and then I had to tap them with Drowner of Secrets.

Plumeveil and Swans of Bryn Argoll are great defenses. Both are very strong and relatively cheap. Plumeveil is a surprise defense, which usually means you can kill a creature with it when it comes out. The Swans are very hard to kill, and even are tempting targets because it allows a damager to draw when it takes damage. In a way, this is milling, because it reduces the library. It also isn't bad for winning the old fashioned way (doing damage).

You can't have enough Memory Erosions. When two are out, the player is losing 4 cards per card he plays. Memory Sluice is good for it's 1 mana for 4 cards, but even more sweet if you can Conspire. Unfortunately, I don't run many creatures (and I don't want them tapped) to use the Conspire, so I feel like Memory Sluice is less effective than it could be. Sanity Grinding tends to mill about 10 cards. For 3 mana, that's not bad. I haven't had a chance to really use Jace, but his discard 20 is pretty rough, and both players drawing cards just speeds my deck up, and serves to mill my opponent while making him think he's doing better. Ambassador Laquatus is great in that he doesn't need to tap to use his ability, and keeps everything in that magic 3 mana range that just about everything in here costs. He's a 1/3, so he's a decent blocker, and also Infest resistant. I like that if I have 6 mana on the table, I can mill for 6 at my opponents end of turn. My worst performer so far for milling has been Millstone. I can only use it once per turn, and while it's cheap, I feel like I could have a better, more threatening card out. Grimoire Thief is very good if you can get her to tap without attacking as a mill card. I think I might swap her for the Millstones I have, and then rely on Memory Sluice to tap her. She can also work as an odd counter.

Finally, Dream Fracture serves as a counter and a small mill as a side effect. I'd prefer a two-mana counter from the good old days, but those days are gone.

Monday, February 23, 2009

Happy Camper and Rising Tide

For a long time, I had wanted to get into my own business. When the opportunity appeared to partner into one at Rising Tide Software, I jumped on it. It was rough. I worked some of the hardest hours I'd ever worked. Running a business is a masochist's job, and the amount of responsibility that it brings to you will certainly turn you into the masochist you need to be.

When reading around about business and such, you may come across some thing that says "90% of businesses fail in the first 5 years", or something to that effect. Without additional context, a statement like that is really discouraging and not very helpful to anyone. I think there's a lot of truth the statement, but how many jobs have you had that lasted 5 full years without you leaving because you went for greener pastures, you needed to move, you got fired, etc? With that in mind, 90% of all work probably fails/ends in some manner in the first 5 years.

This brings me into the news I must break about the companies I co-own. Happy Camper Studios and Rising Tide Software are ships that can no longer remain afloat. You might blame the economy. You might blame various political administrations. You might blame mismanagement. I can't rest fault on any single factor, although I have some ideas on what would have really helped, and what I would do differently given the chance. As a disclaimer, all of the principles of the companies are on good terms with each other, and there will be no finger pointing here.

If you're a partner in a business, you need to have a hand in the finances. Taking on the role of accountant during the final hours of the businesses was a daunting task to add onto my growing list of other tasks. It also leaves you in a position to better assess risk to the business and your own personal finances. If you cannot be involved in the finances directly, then you are not truly a partner. Even investors get to see the financial status of their investments.

Can you really trust people with their hand in the pot like that? Probably not. You don't want to get in the blame game for who expensed what against the business, and whether or not that was a good idea. Among other things, you can get into problems about control, responsibility, and then you have people you can't easily fire (or threaten to fire) when they are out of line or aren't pulling their weight. As many people have advised me (and myself advising others), I'd say don't ever get partners. I'm referring to business partners. I think partnerships are fine on a per-job or task basis. In other words, if I partner up with a school teacher because I want to make educational games, that might be a good idea, but I don't want that partnership extending out into my primary source of income, or into my other business ventures. Before I move on, let's be clear that I have no angst towards my particular partners I had during the lifetime of the business. I've simply yet to see partnerships work out great for any business that I've seen thus far.

Without a marketing-money pipeline, your business is an accident, not a a business. For the longest time, our business thrived off of word of mouth. It's like trees that live off of rainfall. That's great if there's lots of rain, but in the real word, the weather waxes and wanes. Your business needs to be able to control the rate at which it aquires work and turns said work into money. I've heard programmers joke about how they are a machine which turns caffine into code. An image comes to mind of pouring coffee, the dark poison, into a funnel. The contraption that the funnel is connected to coughs and sputters, and then vomits out the code. Your business must be such a contraption. A certain mixture of time and money in the form of marketting is poured into your machine (the business), and the business turns that into more money. There must be some reasonable expectation of how much time and money you must put into the business, and how much money that turns out to be. Without such a formula, your business will wilt once the accidental work dries up.

Packing up the office and dividing who gets the pens and puffing the last of our fat capitalist cigars is a somewhat sad moment. At some point I may try a business out again, but only after getting a lot of my debts squared off and a large savings is built up. At that point, a business might just be a monetary investment to me more so than a place for me to spend all of my time.

Until then, I'm going to rejoin the work force as programmer. I'd like to stay away from risk for a while and go back to just trying to enjoy things, and work myself out of the idea that work and enjoyment are exclusive things. I've got a real family now, and that moves your priorities around a bit.

It'll be nice to do some production Rails work (which I'm applying for). I think any Ruby developer should know Rails, and does himself a disservice by not being at least familiar with it. The Ruby community knows Rails, and Rails, in many ways, is production Ruby. I'm not saying Rails is always the right choice (I'm still going to maintain Monkeybars, and keep using it), but these tools are the some of the reasons that make Ruby so awesome as both a language and a development environment. If you're in fast-food, you want to be able to make fries AND burgers.

Sunday, February 22, 2009

Two for one games

Dawn of War II is out, and a day early from their announcement (the 20th announced, the 19th delivered). I zipped to Best Buy to nab my version with the pre-order, and then like a giddy nerd, proceeded to the hobby/gaming store to get some paint for my minis. Dawn of War II departs from the RTS formula a bit, but I was surprised they would do even more so with the campaign.

The campaign, or single-player, is typically the RTS game with one player pitted against one or more computer players with the difficulty and upgrades graduated as the game moves forward. Also, there are cinematics and a story. The levels usually have an objective in mind, but sometimes even have a special game mode. Based on what I've played so far, the campaign has squads who are led by special characters who remain with you for the entire game. I'm under the impression that later on you run out of slots for whom you can bring, so you have to start picking favorites. These fixed squads appear to be all you get in terms of units. In other words, no base, and no construction. When I played missions like these in Starcraft and Warcraft, these were the most fun. Instead of a base and an economy, you have a jail break. No reinforcements here! I'm pleasantly surprised that Relic made things this way. They've pretty much garanteed that I'll buy all of their campaign content as they release it.

On top of the fixed squads, they have limited uses of things like med-packs and grenades. Normally, this would be something that costed 'energy'. So now you're looking for the spoils of war as you crusade through the galaxy, cleansing your foes. Unit upgrades and abilities (including the equipment) are something that's just not there in the multiplayer for good reason, but is lots of fun in the campaign.

A while ago, game makers learned that if you want your game to have a nice, long life, you add a social aspect to your game. I don't mean that in-game characters talk a lot. I mean that somehow you're involved with human beings. We are social creatures, and having our play-time as a social activity just helps boost the fun. While I could talk about the cool stuff in multiplayer (or the competitive mode), this isn't particularly new other than the fact that the multiplayer is optimized for 3v3 (two teams of three members against each other). In context of the campaign, there is a co-op mode, and the game actually tracks your various co-op progresses with different players (Epic/Gears of War, I'm talking to you). This is also the first time I've seen this with an RTS. I like that the campaign doesn't give you two forces that are mirrors of each other when playing co-op. Instead, the game round-robins who gets which new squad, and the two players control their forces separately (and they are colored a bit different so it's easy to pick out.

With these aspects, it's like I bought two games for the price of one (actually less, games are running $60 now, instead of the $50 I got Dawn of War II for). The campaign feels pretty close to the Dawn of War/40k franchise, but is ever so slightly a different game. Relic, please make lots of these for different races and such, and my heart will always belong to you.

Saturday, February 21, 2009

Gun Control - The Politics

I started to write a multi-part post titled "My Stance on Guns", where the disclaimer alone was worth a blog post. For the sanity of readers and writers of this blog, that was scrapped.

I'm going to pace my 'stance' posts to be about one a week, which is far from neurotic on my part. I think firearms in citizen hands help more than they hurt, and that our goal should be to maximize the good effects they bring, while minimizing the bad.

The goal for a society should be to strive to meet an acceptable level of security, legitimacy, and freedom - whatever acceptable is for that particular society. I gather than folks siding with gun-control don't want people getting shot/killed, and don't want to live in a society that promotes violence. Humorously, pro-gun folks want the same thing. The difference is in the means. I sincerely understand the good intentions of gun control folks (except their politicians). I simply disagree on their means.

One example of gun legislation gone wrong is the Ammunition Accountability Act, introduced to various states as a law that would require that ammunition would be encoded, taxed extra (more than doubling the price of common ammunition [.22] used for practice and small game/varmints), and produce a bunch of other silly things that this Democrat gun-owner rightly makes fun of (and he lets you know what he thinks about the NRA and Republicans in less than flattering terms).

A few things I don't think are mentioned was the ammo tax as I mentioned above. Another is the fact that it would end reloading (legitimately, although such a law is unenforceable because reloading presses aren't registered). Reloading is the act of re-using the brass that most guns eject as they cycle in the next cartridge. It means all that brass can be resold or re-used instead of going to the dump. Thus, reloading is better for the environment. I'm not inferring that environmentalists are gun-grabbers inherently, but we should all know where things like that effect our stances.

Lots of dumb laws get pushed all the time. What's the big deal here? Well, if your stance is to ban guns outright, or exert heavy control, you should know that such acts tend to spur on purchases for these things before they are banned (even if the threat isn't super-serious).

Even dumb things make sense when money is put into context - A company called Ravensforge created the ammo coding system. The company then hired some lawyers to push this as law [1]. Man, wouldn't it be awesome if we could pass a law saying that all consultants working hourly had to use JotBot? That's what these guys did. When gun owners see this stuff (and this isn't the only one), they correctly see politicians supporting an insincere move to prevent violence. I'd say a great many of the owners also see liberals/Democrats/etc this way too, but I believe (and hope) this is incorrect.

In all of this, I have a point - at best many attempts at gun control are misguided. At worst - corruption of some kind. To reiterate: Our goal should be to maximize the good effects guns bring while minimizing the bad, not bans or silly restrictions.

Just for fun, pictures of the Tec-9 before and during the Brady Law/Assault Weapons Ban.[2]
Tec-9 (left) and AB-10 (right), notice the 'now with less scary' difference.


A reporter confronts a law-maker about a weapons ban that includes barrel shrouds. Barrel shrouds dissipate heat from the barrel, and possibly double as a handle. They have no impact on how lethal a gun can be.
[1] To this end, Ammunition Coding hired Briahna Taylor, a lobbyist with Gordon, Thomas, Honeywell's Tacoma-based government affairs office. With Taylor's help, they began pushing for ammunition coding legislation on the state level. Taylor quickly launched a Web site, ammunitionaccountability.com, and bills were introduced in 12 states, including Washington.

[2] When the 1994 federal assault weapons ban also named the gun, Navegar made more modifications and renamed the gun the AB-10, for "after ban."

Thursday, February 19, 2009

Todo List

Months ago, I recorded everything I wanted to do in a To Do list. At first it was great. I could record all of the crazy things I wanted to do, and I would never forget that I wanted to do them. I ran into a great deal of problems though.

One problem was that I tended to record a lot of items. I probably had about ten pages full of check-boxes. The list grew faster than I could knock things down. This built up stress when I flipped through the pages of my paper-based PDA. The satisfying check you get when marking a task as complete can be double edged when you have a massive number of empty check-boxes staring back at you.

As you progress through life, you find that priorities constantly change. This was pretty apparent with a check list that grows as fast as the U.S. government spends money. Over the months, items on the check-list became stale, or they just weren't needed anymore.

Another thing missing from this picture was that my items were pretty difficult to finish up on short notice.
Items like "Save two months worth of income" just wasn't going to get done in a few minutes. While it's important to have long term goals written down where you can revisit them to make sure your life is still oriented towards achieving those goals, these tasks aren't helpful when laced between your day-to-day tasks.

Stay with me here - I've had political conversations with a few people, where the idea is submitted that new laws cannot be introduced without others eliminated. The general thought is that you keep government size from getting too out of control by limiting the laws it can legislate, and provides a means of removing laws that aren't needed anymore. I'm not saying I full endorse this idea. I'm trying to give an idea of what four or so things are looping in my mind at once.

This recipe was the inspiration for my latest fifteen-minute Monkeybars app - TinyTodo. TinyTodo allows ten items! That's it. Clicking an item immediately removes it. Changes are saved as they are made.

Once at the item capacity, no more can be added!

Oh yeah, I think this shows off JRuby's unicode support. But wait! I'm not using 1.9! JRuby - It's the Ruby of the future.

Webservices

A few days ago I attended my local Rails User Group meeting. The talk was about consuming Rails web services from an iPhone. My general feeling is that people were pretty surprised and impressed about the kinds of things that a web service could consume. It may be that there's just a lot of iPhone curiosity among a dominantly Mac-using Railsian community. I'm going off of sincere interest in the concept presented, however.

iPhones and other mobile devices aren't the only thing that can consume a web service. Anything that can send its own HTTP packet and receive a response is in the realm of possible consumers. I'm currently writing a desktop app for a friend that imports data using Shopify's web services. In the past, I've written web services that talked to other web services! There's possibility for some very creative apps here, as well as lots of reusable logic that various kinds of applications can share. There's even some buzz about SaaS that I'm just recently hearing about (although it's been done for some time through various mapping/geocoding applications I've seen, just not with a name).

I do like that the Ruby environment supports SOAP through various libraries, but appears to prefer a simpler XML structure. That said, I've had some frustrations with getting things to work with Shopify. They seem to be pretty new in terms of web service support, so I have to cut them some slack. They have a few examples, but nothing that documents the actual XML structure. My experience with using net/http to send a request has been pretty frustrating too (although I can't blame Shopify for all of that). Once I can overcome the hurdles of Shopify's technical support system, I'm sure I'll back on track in no time.

Wednesday, February 18, 2009

The Direction of Monkeybars

I've pretty much taken the reigns in terms of Monkeybars maintenance. I've been adding in the cool new View Bindings (many more have been added since that post). However, I realized that Monkeybars has a small following, and that I should listen to what they feel is missing from Monkeybars. I didn't get many responses. Perhaps this is great. No news is good news!

My users said two things: more documentation and automatic builds (to make Ruby debugging easier). Can do.

We have a wiki up, and our users have been filling it nicely. As a maintainer who is much more intimiate with the project, I should be doing a lot of those docs as well. I shall commit to doing one wiki page a week. I think that's fairly reasonable.

Automated builds is very interesting. It should would make doing the occasional rawr:jar even faster if there was a background process that compiled stuff as you changed it. It'll need some work in Rawr. The big advantage with doing this is that you can create your Monkeybars project as a Ruby Project (right now we recommend a Java project). Ruby projects can be debugged as Ruby. Netbeans, as I understand, has a pretty decent debugger for Ruby, but that's something that's sorely lacking in other projects.

If you have something you'd like to see on Monkeybars, this thread should be open as long as the mailing list is open.

Tuesday, February 17, 2009

Web design

I attended the Web Designers meetup group yesterday. I don't think I'll ever get over the fact that they refer to HTML as 'code'. It makes conversation very difficult to follow. Wait, why are you writing code for your CSS? Oh, that's because you call CSS 'code'...

That aside, I really get the impression that these folks live like kings, and have to beat off clients with a stick because they have so much work. Is there no demand for custom development? When we announced we were software developers, only one or two people seemed to think we had something they needed.

I think I'm going to look at what some of those designers are doing in terms of exposure (one guy just said to use social media, I guess that means blogs and Twitter?).

Monday, February 16, 2009

Alara Block Mono Red

I have many weaknesses. One of them is Magic, a card game. I was recently reintroduced to it (I used to play it a lot as a kid), and I've found a bit more depth to it than I had originally experienced. Most importantly, it's still fun.

Warhammer 40K drains my fun-money pretty quickly, and Magic would too if I allowed it. Thankfully, I have card table applications like LackeyCCG to help me out. It lets me quickly browse cards and slap together decks and play them I normally couldn't because I just don't have the money to buy every card that comes out in sets of four. Probably the most important aspect is that I can play with my friends overstates and overseas.

After playing what seems to be countless games against Aaron Johnson, I finally made what seems to be a deck I can be proud of. We've been limiting our decks to Alara block, to help us learn the new set and keep things somewhat simple. Not knowing what's out there really can hurt your ability to play, even if you know all of the rules and are ok at playing and strategy of the game.

Here's the deck in it's full glory:
mountains x 25
Flameblast Dragon x 3
Hell's Thunder x 4
Hellspark Elemental x 4
Goblin Razerunners x 4
Fiery Fall x 4
Magma Spray x 4
Resounding Thunder x 4
Volcanic Fallout x 4
Banefire x 4

Sideboard (work in progress):
Ignite Disorder x 4
Molton Flame x 4
Quenchable Fire x 4

It's hard to make a mono red deck that's not a burn deck, so this is what it's evolved into. Volcanic Fallout is really good (better than Infest, since it can't be countered and does player damage). Bane's Fire is a good burn card, and with that and Volcanic Fallout, I think people's counters will mostly go to waste. Magma Spray is nice for killing some key cards for good with it's Remove From Game (RFG) element. Hell's Thunder and Hellspark Elemental are really good in my mind. They let you do good damage very early, and most players don't want to block a creature that's going to die at the end of the turn anyways (let alone run control on it). The unearth ability on them makes them double the punch for a single card. I love it. Fiery Fall I'm not super crazy about, but it made its way in because it's a decent burn card, and if my hand is full of too many expensive cards or I'm just short on mana, I can have it landcycle. The Goblin Razerunners are interesting. First, they survive Infest and friends, so that's good. Second, with a mono deck and 25 lands, mana isn't a problem in the late game. True, my banefire could do two more damage, but I could sacrifice two lands and do two damage a turn for free. It's something that needs to be balanced, because any control on the goblins will cause them to take the lands I sacrificed with them. Flameblast Dragon is just good. They are a potential Banefire a turn.

It might need some more tweaking, but it feels pretty strong. It's also a very responsive deck, which I often have trouble with. Something like Lifelink may be its weakness, but we're playing block, and there's not a lot of Lifelink I can't deal with pretty easily. Overall, it's pretty fun to use.

Sunday, February 15, 2009

Catching up

I'd been trying to write a blog post a day since I started this blog. Up until Thursday, this was the case. On Friday, I wrote two posts instead of one. Writing two posts means I have less time in my day to do the other things I'm supposed to do. Even when borrowing time, it becomes a debt that must be paid back. Looking at debt money and debt time in the same light may help better understand what it means to fall behind.

When I skipped a blog post, I had to pay it back with another - lest I lose a post and break my streak. In the grand scheme, not a big deal. If I miss a week of work, I'm expected to work more hours to make up for it, miss some pay, or take a lower wage to offset expected days off. In the end, you're going pay it back somehow, either by compromising your main goal or other goals. In money's case, you're compromising income vs. savings.

I see lots of advice on debt usually amounts to "don't get into debt". Well, this is great advice if nothing ever happens in your life. For those of us living in the real world, the advice of entirely avoiding debt is extremely poor. If my car breaks down, I simply must fix it. I've gone without a car many times and took the bus. My entire quality of life significantly drops, and it ruins my ability to seize opportunities. I get sick almost constantly. Everything somehow costs more, because I can't go to far away stores to get the goods I need at decent prices. I lose time I could be spending doing small amounts of work here and there because the travel time significantly increases. There's certain legal restrictions with getting on a bus for me. The list goes on. Simply going without a car isn't really viable for me, so I go into debt to keep it running. What about savings? Shouldn't I have some money set aside for fixing the car when it has problems? Sure. Unfortunately, I didn't have that money. It was spent solving problems elsewhere. Unless I can be given a time machine, I can't change the situation I'm in.

So what's the real world solution here? Granted, I should build up a savings for car repairs and other fecal-matter-colliding-with-the-oscillating-unit moments, but I need something to fix the problem I'm in now. In comes the Principle of Least Ambition. If you set your goals pretty low, you can better handle the problems that make the goals harder to achieve than you initially prepared for. One of my goals (which I don't think I'm doing to well at) is now to cut back on the size of my daily blog posts. If I ensure that only 15 minutes are spent every day writing up some article, it should be easier to fit into a busy day more so than a 30 minute blog post.

I can apply this to my car problems by focusing on repairing one car rather than two. I'd also save a lot more money on car insurance. Big win! If only I'd made this decision before I put the money in to get it repaired.

Saturday, February 14, 2009

Bookmarks

Continuing on the topic of web browsers being unproductive (maybe not in a net worth, but there's certainly loads of fat), I'm addressing bookmarks today. Most browsers I've used have a bookmark feature that stores the title of the site (which you can override) and the link. This way you don't have to dedicate a browser/tab for something you want to read later, or save as notes for some project that you'll work on later.

I think the idea for this is pretty useful, but it's difficult to manage in large amounts. Titles aren't adequate for some things. You can usually sort these into folders, but then you have to know to navigate to the links. A friend introduced me to Delicious, a site for bookmarking stuff.

Delicious makes bookmarking very easy by having you assign tags.
Unfortunately, you have to make up your own tags, and sometimes remember what tags you used in the past. Was the tag UsefulStuff or useful_stuff? That may not seem like a huge problem, but I've had a really hard time finding things with multiple tags after the fact. Maybe it's just the Firefox plugin that I use. Even browsing the site for links is pretty difficult for me. I bookmark a lot of stuff, so it's not like I have twenty bookmarks that I could just browse through.

My last gripe about Delicious and similar sites is privacy. The web is full of data (information, to me, implies facts and correctness, which is misleading). I love to read up on all sorts of ideas and thoughts, even drastic or extreme ones. It doesn't sit well with me that someone can just check out my bookmarks and think that I subscribe to these ideas, even though I'm only trying to extend my awareness. You can mark certain links as private, so others can't easily peer at your account, but Delicious will still have the link and your notes/tags on it on record.

My solution (although perhaps not permenant) was to make an Excel spreadsheet (Numbers on Mac). I can create my own categories with folders, color code certain fields or links, and still have a clickable link. This may evolve into a Monkeybars app after I sort out all of the kinks. For now, it works great for me, and I'm not inclined to clutter it up with lots of links since there's a certain amount of pain for entering links in the system. Not everything needs to be remembered. This way the list remains rather terse and only links to the richest content.

Friday, February 13, 2009

Testing Monkeybars - Controllers

Let's start with the code:
The Controller

class MyController < ApplicationController
  set_view ...
  set_model ...

  def load
    ...
  end

  def my_button_action_performed
    transfer[:result] = 2 + 4
    update_view
  end
end


The Test


require 'my_controller'

describe MyController do
  before :each do
    @controller = MyController.create_instance
  end

  it "calculates the result and sends it off to the view" do
    @controller.should_receive(:update_view)
    @controller.my_button_action_performed
    @controller.send(:transfer)[:result].should == 6
  end
end


Let's start off with the quirks. Notice that I used create_instance. This will keep my tests from bumping into each other since every controller I get is a new one. With .instance, that may not be the case. Also notice that I never called open on the controller. This keeps me from needing to close it once I'm done, but also keeps it from firing off MyController#load, which might do a lot of work. If you need to have your test kick off load because you want your test to match the actual runtime execution better, be sure to stub out anything that's not the focus of your test. I can do things like grab the model and check it's state (or transfer, in my case). Finally, I just call the button event handler directly. Signals to the view are also pretty easy to mock/stub.

I realize in my test I'm testing implementation. If you wanted to check results, you could reach into the Controller's @__view (ONLY BECAUSE YOU ARE TESTING) and check to see if the view did indeed get the results you were hoping for. However, that means the mappings in your view just became part of your controller test. Maybe that's what you want. If you want to 'unitize' your test a little more, just make those mapping tests separate. I've detailed how to write some view tests here and here.

Crossroads for Ruby

Ruby is coming to a crossroads, and I'll explain why.

1.9 is coming out. It has lots of performance enhancements and some crazy new features. Unfortunately, it can't be backwards compatible with 1.8.6. An annoying thing is that 1.9 doesn't address a lot of the odd quirks in Ruby that don't need to be there. Fine. Everyone wants to go where Ruby is going, so people attend the 1.9 talks, get other materials for 1.9, etc. People are preparing for the switch.

The crazy thing is that now the Ruby Core developers (the guys who write Ruby) are making transition versions of Ruby. These have been dubbed 1.8.7 and 1.8.8. It's a halfway version to 1.9, with some of the new features supported, but not all. Meanwhile, the rest of us are still back on 1.8.6, still getting ready to make a painful but necessary jump to 1.9.

What's so bad about these transition versions? Isn't it better to have smooth transitions rather than a sudden jump? Well, yes, if all you do is write Ruby scripts that don't depend on libraries, and you start fresh every day. There's a large amount of Ruby developers who make their living off of Ruby and it's libraries. These libraries are by no means small, and would take some work to support 1.9. Again, not a problem, but it'll take time. Now these library supporters need to support not a new version of Ruby, but several versions at once.

To add to the problem, distribution packagers (think Linux distros) just grab the latest stable version of Ruby out there. That version is no longer 1.8.6. It's now 1.8.7 or 1.8.8, both of which aren't 100% compatible with 1.8.6. The current library base is written against 1.8.6. So now new users are encountering more headaches with getting started in Ruby. The library maintainers can't make that switch overnight, so the answer is to not use the library (ugh), or downgrade to 1.8.6 (which may not be possible since the Ruby runtime might be on the host that you can't change).

To add to the fire, Ruby 1.9 doesn't offer a ton to the Ruby 'production' community. We've seen the crazy argument lists and other features that have changed, but I haven't seen raves about that. What's of interest that 1.9 brings to the board is a faster runtime and native threads (but I repeat myself). We want faster, right? Sure, but Ruby's performance is a solved problem. JRuby outperforms even the faster 1.9, and JRuby is still implementing 1.9 features!

For this reason, I believe Ruby is coming to a crossroads here. The Ruby Core folks seem to be very distant from the professional Rubyists that pay their bills with the language and libraries. I can't fault anyone, as there's a language barrier in the way. One possibility is that these two groups will meet in the middle, and go forward as a user-driven language instead of a experiment driven language. The other possiblity is that Ruby is forked, so you then have fun-Ruby and production-Ruby.

Wednesday, February 11, 2009

Testing Monkeybars - Mappings on the view

There's currently no formal mechanism to test mappings made with the View's map method. raw_mappings and signals should be easy enough to test, but how does one test property and using mappings? I showed how to test the :using methods, but there's other links in the chain that could break (such as actually assigning the value returned to the text field itself).

My fellow Monkeybars maintainer, David Koontz, has argued that such tests aren't necessary, and that you'll find these issues immediately when you fire up the app. To some extent I agree. It's like testing to see if your ActiveRecord model has the line 'belongs_to :wallet'. However, I have found sneaky bugs crop up that my test was able to catch right away. Since the test itself is incredibly easy, you could have it implemented long before the argument came to the one heart of the disagreement.

Here's a sample, in it's full glory:


describe MyView do
before :each do
@model = MyModel.new
@view = MyView.new
end

after :each do
@view.dispose
end

it "maps the model without errors" do
@view.update(@model, {}).should_not raise_error
end
end


Let's break this down. On each test, we create a view directly, and a model directly. After each test, we dispose the view (this helps keep your test from hanging because you shouldn't have a Swing thread keeping it alive). @view.update takes a model and a transfer. In this case, we have a vanilla model without any changes, which is pretty typical for, a Monkeybars tuple on the first update as the controller is opened. This will quickly catch common errors, such as your :dollar_amount accessor being nil, but dollar_amount_text_field.text wants a String (and breaks with nil/null). We also have an empty transfer.

One of the flaws with this test is that it runs all of your mappings, not one of them. If you wanted to test particular values or mappings, in some ways you'll be testing others whether you like it or not.

You can create variations on this test pretty easily, and try to assign potential problem-values in the model, and seeing if the mapping breaks. You can also take a look at the view's fields to see if it caught the values you expected.


logans_bank_account_text_field.text.should be_a_lot
capitalist_pig_check_box.selected.should be_true

Tuesday, February 10, 2009

Testing Monkeybars - Using Methods on the View

In a conversation with another Ruby developer, it occurred to me that Monkeybars doesn't have a lot of documentation for testing, and how to test. I've spoken before about my thoughts on BDD, so I won't have to hash that out again.

Using methods are incredibly functional, and functional methods are the ideal test subjects, especially if they don't call other methods! Using methods take an argument, which is either the value coming from the model or the view (in this example, let's say it's the model's percent value). The value returned will be the value applied to the view's attribute.

With this label that shows some percent, and a Float from the model, I will need to do some work to convert it for the label to display. The label's text attribute takes a String, not a Float, so there's going to be some conversion needed there. I also don't want some of my math that I do with the numbers to make some large looking numbers (like a repeating 3). For all the test-first folks, here's the test:

it "formats percents with the % sign and only shows two decimal places" do
  begin
    view = MyView.new
    view.to_percent_string(1.9921321).should == "%1.99"
  ensure
    view.dispose
  end
end

This test gets a lot lighter when you properly use the set-up and tear-down mechanisms of your test framework (before and after blocks for RSpec). When you apply that, the code is really this simple:

it "formats percents with the % sign and only shows two decimal places" do
  view.to_percent_string(1.9921321).should == "%1.99"
end


And here's the implementation:

def to_percent_string(percent)
  "%%%.2f" % percent.to_s
end


It doesn't get easier than that!

Monday, February 9, 2009

Discouraging News - Is there any other kind?

Early Monday morning is a great day for me to start off and catch up with all of my news feeds. I like to stay informed. News sources have their bills to pay, and their leanings. I get that. You can't really know everything about anything, but that's no reason to just not care or remain ignorant. We recently had stories about Scully's Hudson landing. Everyone is happy. Everyone got out OK because this guy made a landing that was really hard to do, and the folks in ferries jumped in right away. That cheers you up. It gives you hope.

Stuff like this makes me pet my guns in the dark, referring to them as 'my precious'
However, it doesn't take long for the news to start talking about doom and gloom. Everyone is talking about where the bail-out money should go, and how fast we should do it. I'm not hearing a whole lot of whether or not we should be doing this. When has this behavior historically worked?

Despite the volley of horrible news I'm hit with, I am actually pretty happy with my 'local' news. Tweets, discussions with friends, and tidbits of IRC chats reveal to me that even those who supported The One are disenfranchised. They realize that this isn't what they wanted. They are beginning to understand that you can't trust a politician, no matter how 'in touch' or good willed he seems. This gives me hope. I don't want my kid growing up in Europe. I would have moved there if that were the case. With news like this - the real news - I can rest assured that European Socialism may visit us, but probably won't stay.

Sunday, February 8, 2009

Gemini - Behaviors

I may wind up repeating myself on a few things from my Gravitor post I made last month, but I wanted to go over the Behavior system in Gemini a bit.

Gemini's behavior system is mostly in place to make a better module in Ruby. Modules have the sad problem of being permanent on an object, you can add them in at runtime, but you cannot remove them. Enter Behaviors. Behaviors are simply objects that inherit from the Behavior base class, and they declare some 'public' methods through the declared_methods directive. These methods are never directly added to the game object. Instead, method_missing crawls through the behaviors seeing if any of them will take that call. If it doesn't happen now, the game object should memoize the call (no more method missing hits for future calls). Also, if it doesn't happen now, name collisions between behaviors will raise an error as the behavior is being added. A lot of this is iffy because A) I haven't worked on Gemini for a few months, and B) Gemini is very new and immature.

Behaviors can depend on other behaviors. Dependant behaviors are loaded before the depending behavior is loaded. This makes it super easy to re-use behaviors, and we don't get the inheritance problem.

Through Behaviors' declare_methods directive, methods can be publicly exposed to the game object. This makes it really easy to keep internal methods from colliding with internal methods from other behaviors. The same applies for instance variables. Unlike a module, the instance variables for a behavior live on the behavior, not the game object the behavior is applied to.

Behaviors will be able to see dependent behaviors directly. This isn't implemented yet, but I feel that a behavior should be able to see the behaviors it depends on. This will make it easy to have quick internal communication between these behaviors without polluting the game object's method space.

Finally, Behaviors have automatic callback registration and handling. Using the wrap_with_callbacks method, you can take any of your methods and Gemini will add on_before_foo and on_after_foo to your method. These will store callbacks. Gemini also adds in some callback removal in case you want to stop listening. On top of that, whenever you call this foo method, the callbacks for before and after will be executed automatically. This is because Gemini shadows your provided method, and sandwiches the original call in between the before and after callback handling.

It seems like a bit of magic, but I feel like this will really help out with making games quickly. Behavior code isn't designed to be super pretty, but super re-usable. This is the place a programmer would spend most of his time if he had a game designer in his time. The game designer would be writing code in the states and possibly wiring up game objects, but the programmer's place is writing behavior code that the designer can use at will. I believe that particular setup will cause Gemini to be a success down the road.

Saturday, February 7, 2009

Brushed Metal

I've had some users complain that Swing applications just don't look like native mac apps, even when using the native look and feel. My counter argument is, what does a native mac app look like? Does iTunes look like a native app? Because it looks nothing like System Preferences. Some folks say 'it just doesn't look right'. Ok, fine, you can't just put your finger on it.

System Preferences, an app on every Mac out there. Exhibit A for 'native'.

I really believe most users don't care so long as the app looks and feels decent (but esthetically and functionally), and it does what they need it to do. Hardcore vim/emacs users don't use it because it looks 'native'. People are somehow able to stomach sites that don't look like Google even though they probably visit Google (or whatever search engine they use) more than any other site out there, so there's clearly some forgiveness on how 'consistent' an app needs to be.

Exhibit B: iTunes - Another Apple made and pre-packaged app for Macs. It doesn't quite look like System Preferences, does it?
This is now rendered a lot less relevant due to the fact that I've stumbled upon a Brushed Metal look and feel. Now apps that look like this:
...can look like this:

Finally, the code (before anything Swing related is touched):

Java::java::lang::System.set_property("apple.awt.brushMetalLook", "true") if Config::CONFIG['host_os'] =~ /darwin/i

This could be done by hitting the UIManager directly with an object instead of this stringy stuff you see above, but I haven't learned if there's a big difference or not. It would be super cool to provide a default and deliberate look and feel setting, but also allow your users to just apply their own by modifying the shortcut for the app to set the look and feel system property, but that's a post for another day.

Friday, February 6, 2009

Monkeybars Store

One thing I felt was a real drag on JotBot was the packaging and distribution. While Rawr does a great job taking us quite a way, that just doesn't include things that are specific to an app that's released with copy protection and trial key tracking.

It came to our realization that anyone writing a Monkeybars app as a commercial product would encounter this problem. James Britt and myself began kicking around the idea of a Monkeybars store, which would sell Monkeybars apps, and handle the payment processing, copy protection, etc. The incentive for us is that we could place our own hair-brained apps up there and possibly make some money, but also by allowing our other Monkeybars users to send up their apps to sell, and we take a reasonable cut off of each transaction.

I drew a lot of inspiration from apps like Steam, which tied products to your account so you can re-download them regardless of what machine you are on.

When talking to one of our Monkeybars users, the question came up on whether or not the code had to be released with the app. The answer is no way. It's your product, we'd just handle payment and distribution (to some degree, we're not even going to sell it for you).

It might be some time before we at Happy Camper Studios can take off on this venture, since work is a little slow, but I thought this would encouraging for other potential users who have their eye on making a desktop app and selling it via the store.

Thursday, February 5, 2009

What's different about the new Dawn of War

Both of my gaming buddies have mentioned that Dawn of War 2 doesn't have a lot of depth to one degree or another. Initially, this was really surprising to me, because in many ways it felt like there was lots of depth. Of course, comparisons get drawn between Dawn of War 2 and Warcraft 3. I'm not entirely sure if such a comparison is fair, because sometimes some of the key arguments break down to "This game wasn't made by Blizzard". However, we have to start somewhere. Also, as a disclaimer: All that really matters is that we enjoy it.

In Warcraft 3, you can make a grunt. That grunt has a certain cost, time to build, etc. Once you have the grunt, you can upgrade him, perhaps use a spell (if the unit has a spell), and you can send him to attack. Grunts are somewhat effective against squishy, light armored foes. They are slightly weak against magic attacks, so you have some counters available. There's a myriad of other units with their own attributes and spells. This makes the game very complex.

However, grunts get no benefits for attacking ranged units. They gain no protection by fighting side-by-side with other grunts, and they gain no benefit from fighting side by side. A grunt on top of a hill is just as effective as a grunt in a valley. The economic complexity of the grunt is great, but the actual usage of the grunt isn't. You can basically attack, run away, and use his spell.

This is where Dawn of War 2 makes its departure. The economy, upgrades, and unit variety just aren't there. However, the usage of each unit is vast. Squads jump behind cover, which greatly reduces damage from ranged attacks. When melee units attack ranged units, the ranged units must fight back with their weaker melee attack. Vehicles are really tender when attacked from the rear. A heavy weapons squad can cover a large area with deadly and suppressive fire.

There's a lot of other things that make these games different, but I thought this was the one that needed elaboration. Through the lens of the hardcore RTS player, the unit usage doesn't seem to be understood or as appreciated as it does for a player like myself, who doesn't know when to tier up, or when it's good to upgrade vs. building more units.

I wish they'd just remove the unit building aspect completely, but I'll take what I can get, and this is a great step in the right direction. I've seen on their community forum that there's already a mod out (impressive in week 2 of a beta). However, the mod system is very weak. Hasn't Relic learned that game longevity is directly tied to the community's ability to mold the game as it sees fit? I guess I'm just saying I want auto-downloaded custom maps/mods ala Warcraft 3.

Wednesday, February 4, 2009

Age of Accountability

When common subjects such as you and me fail to pay taxes, especially in significant amounts, we face big penalties and possibly even jail time. Federal politicians don't get that same treatment. "Oops, I forgot about that" does work for us, so why's it work for them? Sure, they paid it back, but without penalty.
This double standard helps enforce the growing number of folks that look at things through a Marxian lens, where capitalism is a deliberate construct that only favors the rich, and society is easily broken down into a rigid class system. Most of us don't believe the United States is really really like that, but when stuff like this happens, it gets harder and harder to argue against it.
Granted, politicians will always be involved in politics. At any level of influence, you have people trying to hand out favors so they can move toward some greater goal in the future. I understand it's part of the business, and it's a human element that isn't going away. Sometimes that goal is noble and sometimes it isn't. When we catch these guys breaking the law, we need to punish them at least as bad as we would punish one of our own. You can't take that increased level of scrutiny? Don't get into the public spotlight.

I'm not asking for perfection. I'm asking for legal. If we can't enforce the laws we write on the people who write them and the people who enforce them, then we are no longer a society with rights, liberties, and law. A law is a rule that everyone must abide by, not only when it serves to generate State revenue or when someone we don't like breaks it.

We should string these guys up whenever they cross the line, regardless of whether they are Republican, Democrat, Libertarian, etc.

Tuesday, February 3, 2009

Icons using Rawr

The JotBot icon is a clock for time tracking

Rawr, the build tool of choice for doing deployable JRuby work (see Warbler for Rails). Rawr can make .exe and .app files, which are much more native for the OSes that they will be deployed to, and let you hide VM args so your user doesn't have to think about it. The app is just a program they double-click on. One of the things we can do with these native launchers is include an icon. Icons add a lot of polish to your app, and help people build a friendly mental image to associate with your app.

To indicate an icon, look inside of build_configuration.rb. You can just add these two lines in the config block:
c.windows_icon_path = File.expand_path('icons/my-app-icon.ico')
c.mac_icon_path = File.expand_path('icons/my-app-icon.icns')

The Twittest icon is a dunce cap to play on the word 'twit' rather than 'tweet'
I prefer to keep these out of the data jars that I typically make, but there's nothing to stop you from reaching into the data dir for these jars. Be aware that you will have a copy of the icon files (one in the jar and one embedded in the native launcher) if you do decide to share a media location.

My Snippet tool is for cutting and pasting code, so it gets a scissor icon
These icons are in specific formats, so it's handy to know what you can use to work with them. I used SeaShore as a free-substitute for Photoshop on the Mac. It's not on the same level of Photoshop, but at least it has layers. For other platforms, the GIMP is probably the best free way to go. Pixen is a per-pixel editor for the Mac, and the only Mac image editor I've seen that supports the .ico format, and numerous ico apps for Windows, and maybe just this for Linux. For Mac Icons (.icns), I've been using Icon Composer, which is buried in the developer tools.

Gravitor's icon focuses on the repeating black hole theme
There's some things to consider about the different formats, other than the editors. On Mac, icons may be cached, and won't appear in Finder for the app all of the time. Best bet is to open the app instead of hoping Finder refreshes when you rebuild the app. .ico can be as large as 128x128. .icns can be as large as 512x512. I recommend starting at 512x512 and down sampling from there.

By the way, I updated Gravitor's icon during the blog post, so you can re-download the game if you want it just a tad bit snazzier.

Sunday, February 1, 2009

Fight Night

It looks like I might be participating in Fight Night again. Most of the folks there call it Fighter Practice, but I seem to get a better understanding of what goes on when I use the term Fight Night. This typically takes place at a park during the later hours.

Shinai are the lighter, faster, and more painful weapons
So what exactly is it? It's best termed as sword fighting. You can't call it fencing. Fencing is a particular specialty that uses lots of specialized equipment. Just for example, the swords are designed to be held with only one hand, and they are more pokey and stabby than slicey and dicey. Fencing also doesn't include spears or other non-sword weapons (other than a kind of dagger) that I'm aware of. This also isn't the SCA, although it's pretty close. The SCA, in my mind, is a lot more hard-core in some degrees, and focuses a bit more on the reinactment aspect of medieval warfare.

Easier on the skull and the wallet, the boffers can be made for many shapes and sizes
We use boffers mostly, and sometimes bamboo swords called shinai. The boffers are typically made out of PVC insulation and gray PVC pipe (the white variety tends to shatter). They are also wrapped in loads of duct tape or electrical tape. The cost for making one of these is maybe $4 in material. Getting everything from scratch to get started is maybe $20-30. Shinai are typically 4 slats of bamboo, and hollow in the middle. The boffers allow for a wide variety of weapons, such as spears, parrying blades, cross guards on swords, etc. The shinai are pretty expensive (about $40 for a good sword), lighter than the boffers, and hurt an order of magnitude more. I'm trying to get shinai out of my local group for that reason, but some folks are pretty attached to their weapons.

Sportsmanship with this particular event is like nothing I've ever seen. Everyone gives each other big sweaty hugs at the end of the day. Some folks tend to take the game personally more so than others, but in the end everyone leaves cordially.

I recently got an HD video camera for Christmas (Kodak Zi6). Maybe I can post some videos of the events from time to time.

Overall, it's very fun, and a great workout. Exercise is a lot easier to do when you're not trying to make your umpteenth push up, but trying to fend off the guy who thinks he can take you now that you're exhausted.

I hope to start this soon. My gear is ready to go, and so am I. It might even be tonight!

Waking Up

Getting up when you intend to is important. Getting some timing wrong at the start of your day can really mess up the whole thing. This makes getting up on time a skill, especially if you're self employed like your's truly, and you don't have to worry about the axe if you don't show up between the hours of 8AM and 10AM.

For me, getting out of bed early is a challenge
. Having a kid turned it into a downright struggle, but others folks can do it - I must be able to as well. I've certainly tried a lot in terms of getting up on time. An obvious one is to go to bed early, but that's not sure-fire enough.

Alarms help, but there's the snooze factor. For a while, it worked to have the alarm on the other side of the room. This way, I'd have to get up and go across the room to hit the snooze, which ideally would wake me up. Over the last couple of years, I've gotten really good about falling back into bed. The problem there is that I get an hour of really broken sleep this way. This is an hour lost, and I'm even more prone to falling out of bed rather than actually getting up.

My friend Dan Willis (Dan The Copier Man) and his wife do something different. Christina tuned their alarm clock into the local NPR station, and set the alarm clock to play the radio instead of ringing. Dan, being a conservative fella like myself, gets frustrated when our we hear what our tax dollars are buying us. In minutes, instead of sleeping like a baby, he's screaming bloody murder at the radio. Although the scenario is a bit humorous, this wakes him up pretty well.

Now, if you're thinking NPR is unbiased, what's wrong with NPR? I first disagree with you, but most importantly, you're missing the point. If listening to conservatives spout stuff puts a fire in your belly, then you might try tuning into that in the morning (550AM and 92.3 FM if you're in the Hottest Place On Earth). Hate Polka music? Tune into KPOLK (ok, I made that up).

If I little Solomon Barnett out of the bedroom, I think I'll give this a shot.