A Brief Review of Code Complete (Really Brief)

Code Complete, 2nd Edition, by Steve McConnell

Code Complete is an enlightening book. Half of it is pure gold, and coming in at around 900 pages that means 450 pages of gold. It covers, in great detail, every part of the software construction process. I found out about it by looking at this list of top 100 best software engineering books. Coming in at #1 it seemed worth a read.

The most important point: “The primary goal of software engineering is to reduce complexity.” Things such as variable names, comments, live time of variables, cohesion of classes and methods, and coding conventions are all discussed. I don’t agree with all of the specific recommendations, but that’s the point: to consider what matters and decide what is best for the current situation of you and your team.

I also enjoyed what was said about programming in high level languages: “You save time when you don’t need to have an awards ceremony every time a C statement does what it’s supposed to do.”

Looking Towards Performance With YSlow

Recently during one of my trips down the internet rabbit hole I came across YSlow. This sweet little extension to Firebug blew me away. Firebug is already extremely excellent, I would say that it makes web development possible, but YSlow brings it all the way to your server and makes server optimization possible.

We all know that we should be worried about performance. That’s what everyone keeps telling us (but… will it scale?!?). And we’ve heard of all kinds of techniques that sound pretty cool which we should probably look into one day. And we always keep putting off performance optimization, after all it would be premature. Would my user even notice? But, thanks to YSlow I was able to easily identify at least a half a dozen things that I could do within minutes to improve my performance. All in all it took a couple of hours, mostly spent searching for how to enable the features in Rails an nginx that improve performance.

I won’t keep you waiting any longer, here’s how I turned my performance grade from a 48 to an 80:

1. Enable gzip compression

I’m using nginx, I know almost nothing about it (it’s Russian!), but because it is a well designed piece of software it was incredibly simple to accomplish a simple task. First: search google for nginx + gzip. Second: crack open your trusty ol’ nginx.conf. Third:

    gzip            on;
    gzip_comp_level 3;
    gzip_proxied    any;
    gzip_types      text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

Restart nginx and witness the savings.

2. Make Fewer HTTP Requests

I was serving something like 6 js files and 7 CSS files. Keeping them seperate sure makes it easy to navigate during development, but can really multiply your HTTP request count. Thanks to Rails this one is an easy fix too:

Before:

    = javascript_include_tag 'prototype', 'effects', 'dragdrop', 'application', :juggernaut
    = stylesheet_link_tag :all

After:
    = stylesheet_link_tag :all, :cache => true
    = javascript_include_tag 'prototype', 'effects', 'dragdrop', :juggernaut, :cache => 'base'
    = javascript_include_tag 'application'

Rails has caching enabled by default when running in production mode, but in order to take advantage of it you either need to read the docs or google that shit need to tell it what to cache. This gathers your multitude of files into one or two little happy files. They get even little-er when gzipped, though I am unsure what that does to their happiness. I also took this time to put my CSS above my JS. If possible the JS should be loaded nearer the bottom of the page (tell me more…). I’ll count that as a third and fourth thing I did to improve performance.

5. Add an Expires Header

If you’re like me you’re probably thinking: “What would Stevey do? Should I really become a wino? … and btw wtf is an expires header?” Step one. Step two:

        if ($request_uri ~* ".(ico|css|js|gif|jpe?g|png)?[0-9]+$") {
            expires max;
            break;
        }

Blast that into your nginx.conf. I’m not going to explain it. If you are still confused see step 1.

Well as you can see it was not quite half a dozen things, even with my creative counting. I hope this will help you get started on your road to glorious optimization using YSlow to tweak your Rails and nginx configurations. It’s tired in here… *honk-shu*

What a drag: cancelling with onStart

So in this awesome new web application that I am writing I’ve got this totally sweet window/widget/bazfoo system where users can drag stuff around and it will remember the positions. This is all with Ruby on Rails and Prototype and Scriptaculous, and although the specifics are pretty Scriptaculous specific the generalities can apply to you favorite framework, unless it is … well they could probably apply.

Generally the UI doesn’t care what users want to drag when, but sometimes it does care. Say for example players can move stuff around in other players’ houses (to make it look like a ghost was there or something). This is very cool. Problem: what about not dragging things when not in ‘move-stuff-around-like-a-ghost’ mode? Perhaps there should only be one mode and things can always be moved around like a ghost, but even then, based on context, it seems that you might just not want the player to move stuff sometimes. I didn’t. Even though ‘rampant-ghost’ was the only mode I had so far I could envision wanting to drag an area-of-effect-spell-deployment or power meter or anything else without worrying about dragging the furniture.

So I had to sometimes cancel dragging like some companies sometimes cancel bonuses, but unlike those companies I decided to cancel during the onStart callback, not the somewhereInTheMiddleGodKnowsWhy callback. Scriptaculous provides a convenient hook to onStart (but surprisingly lacks one to halfwayThereButSimultaneoslyCutYourPay. They don’t have it? I know, it’s silly!). So lets just throw some code down to keep it real:

function drag_start(draggable, event) {
  draggable.element.should_revert = true;

  if($current_action == null || $current_action.id != "ghost_party_action") {
    draggable.finishDrag(event, false);
  }
}

This is a pretty simple function, really standard, we have all our draggables sign it. First tell the element that it should revert unless it hears otherwise. Then check the $current_action (the $ lets me know I’m using it as a global, just like Ruby). If the current action doesn’t exist or it’s not the one where the ghosts party, then finish it off like Houchen. Great. Except, it still kind of drags and gets all weird. I could have sworn I was using the onStart callback, not the getWeirdAnyway callback… too bad.

So time to dive into Scriptaculous, source code that is! The file is dragdrop.js, the year 2008, film Noir has lost popularity in recent years but is still present in the minds of… The functions of interest are:

  updateDrag: function(event, pointer) {
    if(!this.dragging) this.startDrag(event);
    // ... Lots more omitted
  }

  startDrag: function(event) {
    this.dragging = true;
    // ... Lots of setup, initialization ...

    // Bingo!
    Draggables.notify('onStart', this, event);

    if(this.options.starteffect) this.options.starteffect(this.element);
  },

updateDrag gets called first when the user wiggles that mouse over the element. updateDrag then calls startDrag, which then calls your callback, which then ends the drag, but updateDrag is still in the dark, so let’s enlighten it:

  updateDrag: function(event, pointer) {
    if(!this.dragging) this.startDrag(event);
    // Added part
    if(!this.dragging) {
      Event.stop(event);
      return;
    }

    // Lots more stuff stays the same
  }

See what happened there? updateDrag wasn’t expecting the drag to end so soon after it got started! Now it knows, let that be a lesson. This keeps it from going all loosey goosey everywhere.

Now that is how you cancel a drag with onStart. Leave a comment, it will probably be at least as cool as the UK lottery comment. Also subscribe to my RSS and tell a friend, it’s like twice a month that I publish anything and then you can just scroll past it in Google Reader to get back to your 300 unread TechCrunch posts. Peace!

UK Lottery Victory!! … IP Defeat :*(

Account Account,
  You have been confirm a lucky winner of the Uk Lottery, Do
contact our fuduciary agent with your personal details for
further proceeding

Sincerely,
Smith Stanford

---------------------------------------

Dear Fuduciary Agent,
  This friscal windfall will be a joyous bounty for my
proud nation. I am a quiet and frugal people. I will
invest half of the money in gold and the other half in
gold-insurance. I pray you can refer me to an aurum
insurance specialist.

Following are my personal details:
  Name:
    Dr. Krumpenstein's Monster M.D.
  DOB:
    11-31-81
  Address:
    1048576 Manufacturing Way
    City of Industry, CA 90502

---------------------------------------
Giuseppe Mississippi
250 W Houston St,
San Antonio, TX
(Sent via CERTIFIED RETURN E-MAIL with RETURN RECEIPT)

Date: 2008-09-29
Sir or Madam
1048576 Manufacturing Way
City of Industry, CA 90502
Re: File #032154709 - Infringement Case #10024652519701 -
Dear Discreditor:
  Our Client, Dr. Krumpenstein's Monster, heretofore referred to as
Client, or DK'sM; DEMANDS that you immediately CEASE the use and
distribution of all infringing works derived from DK'sM, and all
copies of him, and that you deliver to me all unused, undistributed
copies of him, or DESTROY such copies IMMEDIATELY, and that you
desist from him or any other infringement of DK'sM (CLIENT's)
personage in the future.
 This will serve as your legal notice under provisions of
federal law, the Fair Practices Act (FPA), to CEASE
all communication. If you fail to heed this notice, I will file
a formal COMPLAINT against you with the Federal Krumping
Commission who is RESPONSIBLE for enforcement, the States
Attorney General office and/or the American Krumpists Association
or local State BAR Association.
 You are also notified that should any ADVERSE information be
placed against ME/(CLIENT/DK'sM) as a result of this notice that
appropriate actions will be taken. Give this very important
matter the ATTENTION it deserves.
Sincerely,
Giuseppe Mississippi

Get a piece of the STRd6 action!

We’re looking for new people to get in on some exciting game development action! If you’re passionate about game design, like to create eye-catching graphics, or want to be part of cutting-edge web development, this is your opportunity.

We need people who are interested in any or all of the following areas:

  • Web programming
  • Graphic design
  • Marketing
  • Business development

Experience is not necessary, but enthusiasm is essential.

Send a resume and a short letter describing yourself to internships@strd6.com and we’ll be in touch!

The magic of haml and sass

As this project has progressed we’ve began using haml and sass to mark up our pages. When I first heard and read about these gems they had me concerned that it was an unnecessary change to the relatively simple languages of html and css. “Why the hell would I want to use percent signs instead of angle brackets?” and “What’s so hard about closing your tags?” were just some of the wtf moments I had initially, not to mention the forced indentation and strict whitespace requirements. “I can format my code however the fuck I please!!” However I did see some immediate benefit with sass, especially in the addition of constants and ease of nesting tags. Even so it didn’t feel like the pros would outweigh the cons, and that having to “learn” a new syntax would be more frustrating than the benefits being gained.

Now that I’ve been using it for all of our pages I’ve realized that it does simplify a lot of the gnarlier aspects of html and css and most of my worries were bullshit. Learning a new syntax took pretty much no time at all, and not needing to remember to close my tags has become very handy. The “forced” whitespace I was so concerned with turned out to be a non-issue because I format my regular code the way they want anyway, which is the cleanest way to read it to begin with. The nesting features of sass were immediately beneficial, even for relatively simple/common nests like ‘div#id p img’. Additionally, I didn’t think much time would be saved from these technologies, even after I began using them the first few times. But the more I’ve exploited them the more I realize that I spend less time typing out code and more time accomplishing tasks. In the end a lot of the complaints I’ve had about html/css for years (and those that I’ve forgotten about, too) have been addressed by haml and sass and ultimately make things easier.

Of course all of this is possible because of Rails, and seeing as how I’m fairly new to Rails, much of the kudos belongs to it as well. Using it on the backend delivers on it’s promises of cutting down wasted time and energy doing menial set up tasks and maintenance. I can make changes in one place and see them reflected all over the app, which is all I can ever ask for from a framework.

So now that I’ve professed my love of haml, sass, and rails, what’s the progress of the app? Well we have some colors on there and forms that aren’t hideous. There’s also a chat feature that’s functional and is rapidly expanding. Basically you can’t DO much of anything yet besides create an account and login, but it kind of looks like a website and acts like one too!

Deploying SQLite to Production w/ Capistrano

This weekend we rolled the innagural deploy of our top secret new rails app to production. We are currently using Rails 2.1, SQLite and nginx proxying to Mongrel. Why bother with Apache (ever) and MySQL before you have to? Additionally we’re on a 256MB slice from Slicehost which is already serving an FB app, so I’d really rather not have the overhead of heavy tools for light applications.

I think I’m a fan of SQLite even though I just started using it. As they say on their site:

The basic rule of thumb for when it is appropriate to use SQLite is
this:  Use SQLite in situations where simplicity of administration,
implementation, and maintenance are more important than the countless
complex features that enterprise database engines provide.
As it turns out, situations where simplicity is the better choice
are more common than many people realize.
...
SQLite usually will work great as the database engine for low to
medium traffic websites (which is to say, 99.9% of all websites).

I’m 99.9% of all websites! And simplicity is important to me, I’m configuring enough already; plus I should probably coding some features or something too. And even if scaling does become an issue, I’d first set up memcached, then analyze and optimize my db tables, then upgrade to a fattier slice, then upgrade to an even fattier slice, then consider a more “enterprisey” database solution: multiple servers and jet-packs for the queries.

Meanwhile, I encountered a “problem” with deploying SQLite to production via Capistrano. This “problem” basicly stemmed from monumental laziness and not reading (or configuring) the default database.yml file. Here’s the thing: on development SQLite works great because you keep updating and committing in your same local directory with your same DB file. In deployment however you usually check out a whole new copy of your app, update some symlinks, and blast off into the night. By default this creates a new SQLite db, and doesn’t include the migrations (they were applied to the old copy). I actually started searching google for the answer to this “problem”, thinking about changing my deploy.rb to update a symlink to the SQLite file… but then it was so much easier to:

production:
  adapter: sqlite3
  database: /absolute/path_to_db/on_server/production.sqlite3 # instead of db/production.sqlite3
  timeout: 5000

I’m actually almost embarrased to post this “solution” but maybe some wayward youth like myself will find it and save some trouble.

Pre-development status

Now that this project is about to start taking flight I decided I should start getting in the habit of posting what’s up in the development world. Eventually we may want to look back at these times and laugh at the ridiculous ideas we thought could pull off. Apparently I’m one of the main developers so I should have a pretty good idea what’s going on.

So far the game involves:

  • Characters interacting with each other
  • Characters building and growing things
  • All browser based with JS/Ruby on Rails
  • Characters can definitely have pets (most important game aspect so far)

That’s the gist of what we know so far. So what have we done so far? Pretty much nothing. But the discussion and spec phase of what we’ll accomplish is very much alive and well. I think this development chatlog really sums up the point of the game and our progress:

Yahivin
it's all pvp all the time
papashaft
I thought there were creatures too?
Yahivin
probably, they might be players
papashaft
what if you find a bear in the wilderness though?
Yahivin
what if you were a bear in the wilderness?!?!
papashaft
then that would rock

Boomtime Development Log – Episode 1

 me:  yo
 pappashaft:  hey
 me:  did you get that console thing going?
 pappashaft:  naw I just got home from basketball
I don't think I'll have time tonight
I have to make dinner and then watch from g's to gents
 me:  what the hell are you talking about?
 pappashaft:  haha
what the hell are YOU talking about?
 me:  touche
 Sent at 8:57 PM on Tuesday
 pappashaft:  we shoudl discuss goals and timelines and features at some point
 Sent at 8:58 PM on Tuesday
 me:  yes
do you read my blog?
 pappashaft:  perhaps tomorrow, I should have more time then
you have a blog?