Tuesday
May222012

Switching away from Google Tasks: task context

I tried to abandon Google Tasks, going instead with todotxt, but eventually ended up on Wunderlist. Here's my story.

I've used Google Tasks and the tasks pop-up inside of GMail for years. It's been pretty good, and solves my basic problem: keep a unified list of "to-dos" and allow me to sort them by due date. It's been fine, except for one little thing: task context - the ability to see tasks by my physical location, and any other arbitrary context I want.

At first, todotxt seemed like the way to go, for a number of reasons. First, it's just a plain text file, and therefore "future proof" as it claims. While I can't deny the appeal of such pure simplicity, and the ease with which you can organize things into projects and contexts, I found that "future proof" didn't matter to me all that much. I don't have any fear that "to-do" applications are going to go away, and the other features (such as a historic report of tasks completed) just didn't matter to me. I also don't have a DropBox account, and while I know it would be dead-simple to set one up, it just seemed like extra work. However, I persevered and decided to give todotxt a real chance, because it's a command line tool, it syncs everywhere, and I develop on both Mac OS X and Ubuntu so I knew my list would easily port between platforms.

So, I installed it. I then spent the next hour playing around with my config file to setup colors and such, adding tasks, marking tasks as complete, and exploring all the features it had to offer. I even moved the entire list of my current to-do's into todotxt so I could get a feel for the real workflow on actual tasks I needed to complete.

Well, something didn't feel quite right. I didn't think that todotxt's operators and sets of commands were all that natural. They certainly fit well into the command line world, I just didn't care for all that typing to manage a list, and it didn't seem perfectly natural to me.

Enter Wunderlist

Wunderlist had all the things I loved about todotxt - keybaord shortcuts, easy context setting and searching, the ability to mark things as complete, without reverting to my mouse - except, I feel that Wunderlist does things just a little bit more smoothly.

First of all, I'm pretty much always in a place where I have a data connection (even when mobile, I tether to my phone), so it's trivial for me to manage tasks on my laptop most of the time.

Second, even when I'm on the go, the Wunderlist app for Android more than suits my needs, and so I don't actually need to be on a computer in order to access/manage my list. I realize todotxt has an app as well, so they're pretty equal here.

Third, while todotxt's use of special operators (+ and @) to mark things with context is fine, I didn't want to be limited by the operators that todotxt thinks are appropriate. Wunderlist already has awesome search (also accessible via keyboard shortcut), so it's trivial to search for things like "@work", and get all the tasks that I've tagged as "@work". The fact that I'm using the @ symbol is arbitrary and flexible should I ever want to use a different symbol because it's just plain text search, nothing complicated.

A single, unified list for everything I do...finally

This is incredibly important to me, because I don't like managing multiple lists - my to-do list is mine, meaning it's everything that I have to do. Why do I need more than one list - I'm just one person. That means a single, unified list of everything I need to remember to do. All I was missing with Google Tasks was the ability to filter based on my current location/context, in order to keep my tasks relevant to where I was and what I was doing. Wunderlist totally solved this for me.

Not only did Wunderlist finally solve my context problem, it took a lot less time to setup. I spent a couple of hours playing with todotxt in order to get a feel for it, but I was up and running with Wunderlist in a few minutes.

Saturday
May122012

Lessons from @torvalds/GitHub commits discussion

The heated conversation that occurred around @torvalds' comments (that GitHub commit messages ruin this format) was lost on many. To the casual reader it might have even appeared as a pure rant. However, there are several jewels in this discussion that hit at the heart of why Linus feels the way he does (not to mention, he thinks that GitHub is doing lots of other things fabulously well).
Before I start, let me be clear that what I'm writing here isn't about the tone of the conversation. My conclusions come from trying to examine the points presented throughout the conversation, while trying to strip out the rhetoric.
So, here's my lessons leared from that discussion, and why I'm convinced that I'm going to start conforming my commit messages to that format.
The premise for formatting in the first place:
  • The formatting of commit messages matters all the time, but especially when you're working with the tools that come with git (git log, shortlog gitk)
  • One of the most important things these tools (and commit messages in general) can do is communicate what is changing in code.
  • The commit message should be considered (and composed) as a highly efficient communication. The efficientcy (not just brevity) of the message, helps you effectively communicate with developers, whether that be other people or your future self.

So, given that commit messages are about communicating effectively and efficiently:

  • It follows that a formatting standard can result in many efficiency gains in collaborative software simple because we're all aware of what happens to readability when we don't follow the standard.
  • Formatting (50 character title, 72 characters for each line in the body) keeps things readable, no matter where the message is viewed, in GitHub, or the tools that come with git.

So, the problem with GitHub pull requests is:

  • Especially when they are created via the web UI, the standard formatting isn't enforced, or even encouraged. Readability (and therefore efficiency of communication) suffers as a result.
  • The sheer volume of commit messages one must deal with on any popular project (the kernel, in this case) really demands that a simple, easy to follow format be conformed to. To draw an analogy, if you've ever been in a role where you have to handle hundreds of emails a day while maintaining inbox zero (maybe you're getting a lot of alerts/monitoring messages from servers you manage), it sure does help to have all of those emails conform to a common format so you can deal with them incredibly quickly, efficiently, and therefore be able to easily divide the signal from noise.
  • The formatting standards provide efficiency gains to all projects, regardless of their size. As your project (and collaborators, and the volume of your commit messages) increase, the amount of time you save by conforming to the standard far outweighs the time it takes to write good commit messages.

The reason I'm going to start writing commit messages that conform to the standard:

  • It's doesn't hurt, and really, it's an easy format to follow.
  • It's going to save me time in the long run (even if I don't care about other people for some reason).
  • Given Linus' experience, and since he's probably one of the most experience git users around, I trust that this format isn't something that's developed because he thinks it's cool - it simply gets the job done in an incredibly fast and efficient manner.
  • I'm not a Linus acolyte - in fact I know little about him other than what pretty much everyone knows about him. I've decided to make the change because I can see the value in following the format.
  • I work on a team of other developers, and I want to make their lives easier, and encourage us all to adopt practices that help us do our jobs with less overhead.

 I'm really glad that I read through the bulk of this discussion - it made me reconsider how I do one of the most common tasks I do every day when writing software.

Wednesday
Apr042012

Starter 2D games with Slick2D: drawing the screen view

This information is available in a number of places, but I thought I would do a series on basic 2D games concepts.

If all you're doing is drawing sprites in a 2D world, then there's basically two things you need to keep track of to decide which sprites to draw on the screen, and where on the screen to draw them. You have to think of your sprites as existing at a certain location in the world, and what you see on the screen as just one view of the world, focusing on an area.

The two things you need to keep track of are:

  1. Each sprite needs to have its location within the world
  2. Your "camera" needs to track its location relative to the world.

So, let's say you have a big, big world, with a 2D coordinate (x, y) space of 1,000,000 x 1,000,000 pixels (I'm using pixels as the unit of measure here, but that's an arbitrary choice, and the size of the world doesn't matter, I've just chosen a big one). Then, let's say you have a "camera" that's pointed at that world, and the view of that camera is what is displayed on your screen. In our example, the display that camera gives you is going to be 1024x768 pixels in size.

Let's also say that you use the arrow keys to move that camera around the world.

So, your world's coordinate space maps to your screen as such:

(0, 0)        +x
      +------------------>
      |
   +y |
      |      *  <= example sprite in your world @ coordinates (x=200, y=200)
      |
     \ /

When your sprites move "right" they increase their x coordinate. When they move "left" they decrease their x coordinate. When moving "up" they decrease their y coordinate (because y increases downward, on monitor displays), and when moving "down" sprites increase their y coordinate.

Now, again, what you see in our screen is just the camera's view of the world. So, let's set that the camera's upper-left corner is at (x=500, y=500). That would look something like:

(0, 0)        +x
      +---------------------------------->
      |
   +y |
      |      *  <= example sprite in your world @ coordinates (x=200, y=200)
      |
      |
      |         +===================+
      |         |     the area      |
      |         |  that the camera  |
      |         |    "sees" and     |
      |         |   shows on your   |
      |         |       screen      |
      |         +===================+
     \ /

With that setup, let's say that the camera is at (500, 500) (that is, the upper-left corner of the camera's view, as shown in this example, is at the world coordinates (500, 500). And because the camera shows you an area that is 1024x768 is size, then the opposite, lower-right corner is (500+1024, 500+768) = (x=1524, y=1268).

Note that the sprite in our world is not inside that camera's view area. That means, when we render the camera's view on the screen, we won't see the sprite.

If, instead, the camera moved to (200, 200), then the view area of the camera would cover the world coordinates from upper-left @ (200, 200) to lower-right @ (1224, 968), and look something like this:

(0, 0)        +x
      +---------------------------------->
      |   
   +y |  +===================+
      |  |                   |
      |  |   * <= sprite     |
      |  |                   |
      |  |                   | <= camera's view of the world
      |  +===================+
      |
      |
      |
      |
     \ /

When the camera is in this position, the sprite is visible. If the sprite is @ (500, 500), and the camera is at (200, 200), then when we draw the sprite on the screen, the sprite will appear, on our screen at coordinates 300, 300.

Why?

Because, and this is really the answer to your question, where you draw things on the screen is sprite's world location (500, 500), minus the camera's location (200, 200), which equals (300, 300).

So, to review:

You move the camera's position around the world using the arrow keys (or the mouse, or whatever other control scheme you want), and you render the sprites location relative to the camera position, by taking the sprite's position and subtracting the camera's position, and what you get are the screen coordinates where the sprite should appear.

But there's one more thing...

It's really inefficient to draw every sprite in the world. You only need to draw the sprites that are within the camera's view, otherwise you're drawing things that you won't see on your screen, and therefore, wasting rendering/CPU/GPU time.

So, when you're rendering the camera's view, you need to iterate through your sprites, checking to see if they are "on camera" (that is, whether or not they're within the view of the camera), and only drawing them if they are within this view.

In order to do that, you have to take the dimensions of your camera (1024x768, in our example), and check to see if the sprite's position is inside the rectangle of the camera's view - which is the position of the camera's upper-left corner, plus the camera's width and height.

So, if our camera shows us a view that's 1024x768 pixels in size, and it's upper-left corner is at (200, 200), then the view rectangle is:

(200, 200)                      (1224, 200)
           +===================+
           |                   |
           |    *              |
           |                   |
           |                   |
           +===================+
(200, 968)                      (1224, 968)

The sprite's position @ (500, 500) is within the camera's view, in this case.

If you need more examples, I have a working Slick2D tech demo, called Pedestrians, that has code you can look at. For details on how I calculate the area of the world that should be rendered, look at the render method inside this file, and pay special attention to the startX, startY, stopX, stopY variables, which for me control the area of sprites I'm going to draw. It should also be noted that my sprites (or "pedestrians") exist on a TileMap, so they aren't 1 pixel is size - they have a width and height of their own. This adds a small bit of complexity to how to decide what to draw, but it basically comes down to, "draw what's within the camera's view, plus a little extra around the edges."

Only through practice and study will you get all the little ins/outs of how this works. The good news is that once you figure out how to do rendering with this basic 2D world vs. camera method, you'll pretty much know how to render graphics for all 2D apps, because the concepts translate to all languages.

I also have various videos of Pedestrians being run on my YouTube channel (the most relevant video is probably this one, which shows my basic pedestrians being rendered, and the camera moving around), so you can see what this all looks like without having to build the project first.

Wednesday
Feb222012

Slicehost, AWS, and Heroku: Looking back at two years of deploying independent Rails apps

I started writing independent Rails apps on my own two years ago this month. One of the key decisions I needed to make early on was where to deploy my apps. After two years using three of the biggest players (Slicehost - now part of Rackspace Cloud Hosting, Amazon Web Services, and Heroku) I give you my take on the experience and toolsets available.

Slicehost - my first Rails deployment environment

Slicehost has a bit of a cult following. I came onto their service after they'd already been acquired by Rackspace, but despite that I felt very connected to the developers and sysadmins that ran it. You could literally jump into an IRC chat with the sysadmins on duty if there was a problem, and get help from the experts immediately.

I ran an application on a VPS from them for 18 months, had only a single service issue (which was handled quickly and professionally), and I basically didn't have to do anything to fix it other than wait for the sysadmins to do their thing. I also spun up several differently sized slices during that time (some for just a day or two for testing), and also seamlessly migrated slices between various sizes. The last time I had a VPS with Slicehost was June 2011, but the experience was great, and I'd recommend them to anyone who wants to run their own server in the cloud without a lot of frills. It's just the developer, and their server: a simple partnership.

Heroku - the slickest app environment around

Heroku. It is by far the easiest way to deploy a Rails app without thinking about infrastructure. Their suite of plugins (and how ridiculously easy it is to add/remove them on the fly) has no match. They also after completely free hosting for small apps with simple needs: a basic database, and a single dyno (web server instance).

It took me a while to try Heroku, but when I did, I found their support documentation to be up to date, detailed, and straight forward. I had no trouble at all getting my first app running on Heroku in less than an hour.I currently run a small app (rpglogger.com) on Heroku, and basically haven't had any issues. That being said, one thing that new developers run into with Heroku is the occasional gem incompatibility or obscure application error. I haven't had too much trouble along these lines, but I have, once or twice, had to do a quick Google search on an application error that only happened after deploying to Heroku, only to find that the solution was very simple: change a config setting, or update a gem. There's a big community of developers on StackOverflow that deploy to Heroku, and pretty much any problem you might have on their platform is documented by someone else who already ran into said problem.

Amazon Web Services - ultimate control

I do quite a few small apps in my spare time, and I find that AWS reserved instances are perfect for this. Since I already had experience running my own server on Slicehost, it was a pretty easy decision to pay only $60 to get a reserved server instance for an entire year (I was paying $25/mo on Slicehost at the time for the smallest slice). Just one micro server on AWS is enough to run 2-4 small apps on the same machine, with multiple web server instances (vs. Heroku's one free dyno), and still have a little memory left over. It's also hard to beat the availability and global deployment footprint of AWS. Since you can get any size server, AWS works equally well for any number of systems, including the independent app on a single server.

On top of the initial cost for the reserved instance, I only have to pay for bandwidth and other AWS usage (S3 storage, for example). This makes AWS an amazing mix of ultimate scalability, great costs, and ultimate control.

Rackspace Cloud Hosting provides similar services, and they're probably comparable for most things. But if what you want is the Swiss army knife of cloud services (servers, load balancing, storage, database, VPN, and even NoSQL options), I think AWS is still way ahead of everyone else.

Conclusions - right tool, right job (no surprise)

So, I started on Slicehost, then tried AWS, then Heroku, and today I'm back on AWS for most of my work. I can't really say too many bad things about any of these services. I think they serve different priorities very well, and that all of these services deliver on what they say they can do:

  • Slicehost for really simple VPS
  • Heroku for the slickest app deployment in town
  • AWS for all the power and flexibility you could want
Thursday
Feb162012

Continuous Delivery reading and resource list

This is a re-post of an article I wrote for NUBIC:

My technical project for the year, I've decided, is to build a continuous delivery system inside the NUBIC dev team.

Here's a quick reading list of source materials that I'm using to learn how to do it (blog posts to follow as I document the process of building the system internally):

These things couple very well with additional practices that NUBIC embraces as part of its software development process, including:

Finally, ThoughtWorks Studios has a commercial product called Go for automated release management. A couple of people from ThoughtWorks also happen to be the authors of the book on continuous delivery.