Capistrano & delayed_job With Rails 4

If you’ve tried deploying your Rails 4 app using Capistrano, and you happen to also be using the delayed_job gem, you may have encountered a problem.

bash: script/delayed_job: No such file or directory

The solution is actually quite simple. Rails 4 uses the bin directory in place of the script directory, so add this to your deploy.rb file:

set :delayed_job_command, "bin/delayed_job"

Done.

Ruby? For games? I’ll hang you for that shit. PART 1

Ruby is an amazing language. It is, without a doubt, my favorite scripting language. The first time I heard about it was back in late 2006. I dove right in, and I haven’t looked back. I’ve built myself a pretty decent career on Ruby, and I couldn’t be happier about that.

And now I decided I wanted to fuck around and make games for fun, and later, for profit. Like a true goddamn American.

Ruby isn’t designed for that. Its bread and butter is the command line, and thanks to DHH, the web. There are gems around that’ll help you out, like rubygame, gosu, and releasy. None of those are ideal. I would strongly recommend against wasting your time building games with Ruby. If you want to create a desktop game, learn C++, Java, or Objective-C (and Cocoa) and start playing in hard mode. If browser games are your thing, look into Javascript with HTML5, it’s seriously sexy stuff these days. Creating a game in Ruby is stupid.

With that said, I’m going to show you how to build a game in Ruby.

Let’s build a hangman game!

Alright, enthusiastic me, let’s do it! We’re not going to use any of those gems I pointed out earlier. We’re going old-school with this one and we’re just going to build a command line hangman game.

Let’s start off by outlining the rules of the game as algorithmic as possible:

  1. User is given a phrase to decipher. The phrase is obfuscated by replacing each letter with an underscore.
  2. User guesses, one at a time, a letter believed to match an obfuscated letter in the phrase. The user is allowed 6 incorrect guesses before they lose.
  3. If the user’s guess is correct, replace every instance of the obfuscated letter on the board with the guessed letter. If the guess is incorrect, add the letter to the “used letters” pile and mark off an attempt.
  4. The game ends when all obfuscated letters are guessed, or when the user gets 6 incorrect guesses.

That’s the gist of the game. If you’ve never played hangman, you’re probably from the Third World, and that’s OK. Also, we’re going to go ahead and keep this traditional by drawing a dude getting hanged. We’re not going to pussyfoot around it like teachers do nowadays by drawing an apple tree with some apples and removing one upon each incorrect guess. No, we’re going to murder an ASCII character, so make sure you’re OK with this before continuing.

Getting our assets in order

A lot of people play hangman with a simple word list. I’ve decided to use movie titles, because yes. I went over to IMDB and copied their top 250 movies list, then dumped it in a file which you can find here. I’m aware there are only 246 movies on that list, and I don’t know what happened either. I may have just gotten rid of movies I didn’t like, or maybe it was movies with numbers in them? Whatever, it doesn’t matter, we’ve got 246 movies to work with.

If you don’t want to use movies, use whatever you want. Just make sure each word/phrase is on its own line, and I recommend against numbers since all of that will be stripped out later anyway.

It’s all about phrasing

Ruby is an object-oriented language. If you don’t know what that means, I have no idea why you’re reading this tutorial to begin with. The first thing we should do is set up a Phrase class to manage the phrase the player needs to guess. We’ll initialize it and select a phrase right off the bat.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Phrase
  def initialize
    @letters = []
    selection.each {|l| @letters << l.gsub(/[^a-zA-Z ]/, "")}
  end
 
  def selection
    seed = phrases.length # Get the number of phrases
    # And use that for a random index
    phrases[rand(seed)].split("").map {|x| x.upcase}
  end
 
  def phrases
    lines = []
    file = File.open('phrases.dat', 'r').each {|line| lines << line.chomp }
    file.close
    return lines
  end
end

Let’s go over this.

The selection method simply counts the number of lines in the file (remember, each line is its own word/phrase), creates an array of phrases (lines), transforms them all to uppercase, and selects a random phrase.

The phrases method supplies all of the phrases in the file to the selection method. Could those two methods be condensed into one? Absolutely, but I’m trying to tutorialize you, damn it.

@letters is an array where each letter in the phrase is an element in the array, with everything that isn’t a letter or a space stripped out. If our word were “Sprinkletits!!1″, our array would look like this:

puts @letters # => ["S", "p", "r", "i", "n", "k", "l", "e", "t", "i", "t", "s"]

If you instantiate that class and run your script, you should see something like:

class Phrase
# ... all that code up there
end
 
phrase = Phrase.new
puts phrase.letters # => undefined method `letters' for #<Phrase:0x100169580> (NoMethodError)

Oh. Right. We forgot to define a method for letters.

def letters
  @letters
end
 
# Let's prettyprint the phrase
def show
  @letters.to_s
end

Add that to your class, run the script again, and you should see:

class Phrase
# ... all that code up there
end
 
phrase = Phrase.new
puts phrase.letters # => ["A", "L", "I", "E", "N"]

phrase.show will simply show “ALIEN”. Now we’re getting somewhere.

But I’m tired of writing for today, so I’ll stop right here and continue this another day. I know, it’s a pretty anti-climactic ending.

Mixing Multiple Audio Files With SoX

SoX, the “Swiss Army knife of sound processing”, is awesome. I’ve been using it a lot lately for a project I’m working on, and I encountered a situation not quite covered in their documentation.

I wanted to mix multiple audio files together to create a new file. Let’s say I have a file with a really cool beat and I wanted to completely ruin it by adding another file with Nicki Minaj rapping.

sox -m sick-beat.wav awful-lyrics.wav output.wav

Very straightforward. Now I have a beat with the sounds of a pregnant wildebeest being tortured in a child’s night terror. But what if I wanted to start the track with her shit lyrics a few seconds after the first track begins? SoX provides the pad effect which takes two parameters: one for before the file plays, and another for after (in seconds). Awesome!

sox -m sick-beat.wav awful-lyrics.wav pad 3 0 output.wav

That should delay her retarded-ass rhymes from starting for 3 seconds, right? Well, no. Instead, it shifts BOTH files. One solution is to pad her rape lyrics first, then apply that intermediary file against the other:

sox awful-lyrics.wav offset-awful-lyrics.wav pad 3 0
sox -m sick-beat.wav offset-awful-lyrics.wav output.wav

That does exactly what we want. But what if you wanted to add the stylings of a more competent rapper to drown out her wailing? You’d have to add yet another line, creating yet another file, before then mixing them. It doesn’t seem too bad for two files (though still wasteful), but it gets more cumbersome as it scales. Granted, it’s a linear growth, but it’s still wasteful since you’ll probably want to be deleting the intermediary files once you’re done. There’s a smarter way to do it!

sox good-rapper.wav -p pad 3 0 | sox - -m awful-lyrics.wav -p pad 3 0 | sox - -m sick-beat.wav combined.wav

SoX provides the useful -p option that treats your command as an input pipe to another SoX command. In this case, the beat starts at 0:00, Nicki ruins it at 0:03, and finally a competent artist like Nas or Mos Def comes in at 0:06 and makes things listenable.

You can also check out avconv and ffmpeg.

Twitter-like Character Count Plugin Written in jQuery

See it in action right away if you don’t feel like reading.

I wanted to pop my plugin cherry, but I wasn’t sure what to put together. A wise man once said, “If you don’t know what to build, just build something you need for yourself.” That wise man’s name? Albert Einstein. Just kidding. It was me. I said that.

I’m currently working on a web app that requires limiting text fields to a certain number of characters, because lowering the quality of discourse to a level of syntactically-fucked brevity is all the rage these days. So rather than just implement it onto my app, I decided to turn it into a plugin. Because, you know, not enough jQuery plugins exist.

Grab the plugin on Github

Usage

Simple.

$("#textbox").lilCharacterCount();

Or, with options.

$("#textbox").lilCharacterCount({
  limit: 140,
  warning: 100,
  allowExceed: true,
  counterClass: "character-count",
  defaultClass: "bg-info",
  warningClass: "bg-warning",
  dangerClass: "bg-danger",
  submitButton: ""
});

Features

  • Count down from character limit to 0
  • Block further text past limit, or allow text past limit and display negative count (like Twitter)
  • Warn user when getting close to limit (again, like Twitter)
  • Disable submit button when exceeding limit
  • Uses Bootstrap classes by default, but can be changed via options

Options

limit
Number. Sets the character limit for the text box. Default: 140
warning
Number. Toggles the warning class on the counter when this character count is reached. When set to 0, it is disabled. Default: 100
allowExceed
Boolean. Determines whether or not typing is allowed past the limit. Default: true
submitButton
String. ID of submit button that, if supplied, will be disabled if limit is exceeded. Default: blank
counterClass
String. Class for the counter. Default: character-count
defaultClass
String. Class applied to counter when the character warning or limit values haven’t been exceeded. Default: bg-info
warningClass
String. Class applied to counter when the character warning values have been exceeded. Default: bg-warning
dangerClass
String. Class applied to counter when the character limit value has been exceeded. Default: bg-danger