Hello, Digital Ocean!

I recently switched this blog to using Digital Ocean for hosting, so please let me know if you notice anything broken.

On a side note, Digital Ocean is amazing and I highly recommend it to anyone who needs web hosting. You know how Github makes working with Git repos so pleasant? Digital Ocean does the same thing for web hosting. Down to step-by-step documentation for everything you need to do.

If you’re looking for hosting, try Digital Ocean. (They aren’t paying me for this or anything, I’ve just never had such an positive experience with hosting provider. Or, really, any positive experience with a hosting provider.)

On the flip side: Hostmonster is terrible. Never use Hostmonster. They verify your identity over the phone by asking for your password (!), autogenerate several .html files in your document root that you cannot delete, and nickle-and-dime you for stupid things.

Makin’ Mazes

After my previous post on the subtleties of CSS subpixel rendering, Andrew pointed out that readers might be more interested in how to dynamically generate mazes. It sounded crazy, but here we are.

First of all, if you’re interested in this stuff, there’s a great slideshow on maze generation here and more resources on the procedural content generation wiki.

Basically, your maze is made up of boxes:

single_square

You create the maze by making a grid of these boxes, and then Kool-Aid-maning your way through certain walls.

Ohhh yeah.
Ohhh yeah.

How do you choose which walls? That’s where the algorithm comes in.

First, you choose a square to start the maze at. You add this square to an “active set,” which is the set of squares that you’re currently enmazing:

this.active_set_.push(startNode);

Then you choose one of the square’s neighbors at random. If that square isn’t part of the maze yet, you connect it to the starting square and add it to the active set. If it is already part of the maze, you choose a different neighbor. If all of the neighbors are already part of the maze, you remove the starting square from the active set.

var new_node = startNode.getNeighbor();
if (new_node) {
    this.active_set_.push(new_node);
} else {
    goog.array.remove(this.active_set_, startNode);
}

Now choose a member from the active set and repeat until the active set is empty.

Putting this all together, this looks like the following:

Maze.prototype.generate = function() {
    this.active_set_.push(this.startNode_);
    while (this.active_set_.length > 0) {
        this.run_();
    }
};

Maze.prototype.run_ = function() {
    var node = this.pickActiveNode();
    var new_node = node.getNeighbor();
    if (new_node) {
        this.active_set_.push(new_node);
    } else {
        goog.array.remove(this.active_set_, node);
    }
};

The actual full code for this is a couple hundred lines long and you can get it from my Github repo. However, the two functions above are the “meat,” the rest is just details.

Screen Shot 2014-01-18 at 12.22.27 PM

The most interesting part of the code above is the var node = this.pickActiveNode(); line. Depending on how you pick nodes from the active set, you get different “shaped” mazes. For example, here’s random:

random

30% choosing the first square in the active set:

some_pop_first

60% choosing the first square in the active set:

60p_pop_first

Each maze has a different “character.” Pretty cool!

Update Your Feeds

Some RSS housekeeping:

If you haven’t subscribed, subscribe over RSS or email!

If you subscribed within the last couple of years, thank you and you don’t need to do anything.

If you subscribed more than three years ago, please make sure you’re subscribed to kchodorow.com, not snailinaturtleneck.com. This site has been permanently redirecting to kchodorow.com for years, but there are still a few subscribers on snailinaturtleneck.com. I’m going to let snailinaturtleneck.com expire in about a month, so please update your subscription!

Thanks for reading, everyone!

Fixing CSS antialiasing on Chrome

I’ve been working on creating mazes with LimeJs and I ran into a problem:

Screen Shot 2014-01-18 at 12.42.13 PM

As you can see, this maze looks like it was rendered by a dying printer: there are horizontal white lines all over the place. I was going crazy trying to track down the cause: the squares were perfectly sized/placed and the padding and margins were all zero pixels. It looked fine in Firefox, just Chrome had the issue. Finally, Andrew figured out that it was antialiasing on pixel borders and, if I offset the images by less than a pixel, they wouldn’t be “rounded off.”

I tried offsetting everything by .5 pixels:

Screen Shot 2014-01-18 at 12.41.57 PM

Better, but not perfect. However, with .1 pixels:

Screen Shot 2014-01-18 at 12.41.34 PM

Good enough!

I made a patch for this but I haven’t made it work for masks so I’m not going to do a pull request for it (yet). However, you can cherry-pick it from my fork of LimeJs and use it by adding the following line to your start() function:

lime.Renderer.DOM.ANTIALIAS_OFFSET.y = .1;

If anyone knows anything about why Chrome antialiases stuff like this, I’d be interested in knowing (I found lots of sites complaining that it was weird, but none explaining it).

Happy hacking!

Glupdate

After getting Google Glass, I started wearing it around. Every day I’ve worn it, someone has asked me about it. A waiter even asked to try it on (which I let him, not like he was going to run off). Only guys have asked me about it, but that might be because guys tend to be more willing to talk to random people in public.

A couple things I’ve noticed:

  • Taking surreptitious photos of people is super easy. Glass takes a photo when you wink, so as long as someone isn’t looking at you, you can take a photo of them without them noticing. I really like this, because I like sketching people but you can only stare at someone for about half a second before they can tell. With Glass, I can take a quick photo and sketch from that.
  • The screen automatically turns on if you raise your head. Unfortunately, Andrew is a foot taller than I am, so every time he starts talking I look at him and my screen turns on. Then I feel like a jerk because it looks like I’m doing something else while he’s talking, whereas I’m just trying to give him my undivided attention. The head tilt angle is adjustable, but I think I’d need to modify it to something comical for it to not trigger in conversation. (Maybe you can make it negative… I’ll have to play with that.)

Game Jam Resource List

The best programming thing I found in 2013 was game jams. They are so much fun, a great way to get better at programming, and stretch my artistic chops. They also really makes you focus on finishing the game, which (for me) is the hardest part.

There are downsides: jams take up the entire weekend and, when Monday rolls around, my hands are Friday-level tired.

Anyway, since It’s been such an amazing hobby, I thought I’d share some of the resources I’ve found in case anyone is interested in trying it out.

Finding Gamejams

CompoHub has a calendar of all (or at least most—sometimes it’s a little behind) upcoming jams. Ludlum Dare is the biggest game jam, it’s held once every 4 months.

If you’re looking to “roll your own,” New Year Game Jam has a great idea generator.

Programming

I like using JavaScript because then everyone can run my games: they’re not dependent on having the Java SDK or .NET or something. I use LimeJs as a game engine. It’s pretty basic, but it is flexible and uses Google Closure, which provides a JavaScript API that’s really nice.

Art

I do all of my art with Sprite Something, which is only iOS and costs a couple bucks but works great.

TexturePacker seems to be the de facto standard for spritesheets, and it’s worked great for me so far.

Music

This totally amazes me, but this guy Per Nyblom made an automatic music generator that will create “random” music for your game with a click. He doesn’t have any plans to open source it (yet), but http://rml.pernyblom.com/ is open source.

For sound effects, there’s cfxr/sfxr.

TODO

Next year, I’d like to do at least one of: a game with a server backend, release some of the general libraries I’ve created to work with LimeJs, or integrate a game with Facebook/a chat service/something else.

Also, my goal is to keep updating this as I find more useful resources. Hope this helps someone!

Hello, Glass

google_glass_grey-580-90

On Friday, I got Glass, which is pretty cool so far.

I got to “bring a guest,” so Andrew and I went over to the Glass studio in Chelsea Market after work. I had been there before for a workshop on designing Glassware (or, as I prefer to call them, Glapplications), so I knew that when they asked, “Would you like anything to drink?” they weren’t just offering soda: the Glass Studio has a full wine bar available. Andrew and I got glasses of red wine and settled in.

When I got the glasses, the guy was like, “Are they lighter than you imagined?” which seemed like a required question. However, they weren’t, they were like sunglasses with a chunky earpiece.

The guy showed me how you say, “Ok glass, take a picture” and I turned to take a picture of Andrew but didn’t quite make it before I think I blinked and it took this:

glass_andrew

Which I’m pretty delighted about, because it’s one of the best pictures I’ve ever taken, light-and-focus-wise. So, it’s got a pretty good camera and, unsurprisingly, the less involvement I have with it, the better the picture comes out.

Other cool things:

  • I hate talking on the phone, and this makes it easier (don’t have to hold anything to my ear, just tap the glasses to answer the phone).
  • Directions on them seem super useful. Again, way better than phone.
  • You can screencast whatever you’re doing with Glass super easily, which seems like it might have cool possibilities.

Interestingly, my hair got in the way a lot when I was swiping: I guess whoever designed the UI didn’t have long hair. Also, I find that its dependence on voice interaction is kind of annoying. I don’t really like talking, period, and I feel like a moron talking to my glasses. The last downside I’ve noticed so far is that the battery doesn’t seem to last very long. I wish they had put a second battery in the other side, so that the glasses were at least symmetrical.

So far, my verdict is: seems like an awesome tool. 7 out of 10, with points deducted for looking nerdy.

Davy Jones’ Freezer

Last weekend I participated in The Arbitrary Gamejam #5, with the theme “Damn the Torpedoes! Full Speed Ahead.” I came up with “Davy Jones Freezer,” where you’re an ice cream transport that needs to get through a minefield to deliver ice cream to an island.

Screen Shot 2013-12-08 at 11.32.50 PM

This wasn’t as tight a game as The Little Volcano, but I learned a lot of new things. Things that worked:

  • Having a tutorial class. I always loathe doing the tutorial and it was almost painless.
  • Figuring out exactly what to deploy. I deployed exactly three files: the index.html, the javascript, and the spritesheet. Previously, I’ve ended up throwing a ton of unnecessary crap up because I’m not sure if I need it or not.
  • Having a goal for the player. The judge for the last Arbitrary Gamejam pointed out that a goal would have been nice and he was right!

Things that didn’t:

  • The workflow of drawing something in ArtRage, exporting it to Gimp, magic-selecting the canvas away from the edges, resizing it, exporting it again… ugh. I’m sticking with pixel art from now on, the workflow feels a thousand times more efficient.
  • The ocean class kind of got away from me. Not only did it become one of those mutant classes that contain references to everything, but I spent a long time struggling to create an infinite board. I think I probably could have broken the problem down better with a few minutes of thought (and maybe a piece of paper).
  • Up through the end, the background was irritatingly flicker-y. Still not sure why, but I think I need to understand the LimeJs rendering code better.

Screen Shot 2013-12-08 at 11.33.10 PM

I wanted a font that said “Here there be dragons.” When Andrew saw it, his reaction was, “Would you like a Dove bar?” Now every time I see it, I think “Dove bar.” The theme of the game doesn’t help, I guess.

All in all, I’m glad I did it, I learned a lot, but I’m a bit disappointed in the final product. This weekend is Ludum Dare, so hopefully I can create something that I’m happier with.

Getting Better All the Time via Code Review

I read a great blog called Ask a Manager, which recently posted a question that I think had more of a technical than business solution:

[New coworker’s] HTML and CSS work are terrible. This is his first “real” job out of college, so I understand that he has some catching up to do as far as honing his skills (as well as how he conducts himself in the office, but that’s another story entirely), but I don’t think that excuses his lack of front-end coding skill if that was part of his job description. I’m currently trying to jump in to help develop one of his projects, and I’ve wasted the past two hours trying to pick apart his code into something I can use. My other coworker has met the same frustrations when trying to use this person’s code.

If someone’s straight out of college, they don’t know how to code professionally. They might be an irredeemably terrible programmer, but they can probably be whipped into shape by code review.

But won’t code reviews take a long time? Well, honestly, yes. It slows you down. However, you’re making your code base better, saving future pain, and passing it forward by teaching the next generation. One of my coworkers came up with a good strategy to review code as fast as possible by making multiple passes:

Pass 1: Style

Make sure spacing is sensible, variable names are more than one letter, it looks like the code around it, and generally follows whatever style guide you’re using (Google has public style guides for most languages, just use one of those if you’re a small company).

Pass 2: Readability

Now that the code isn’t blinding you on contact, see if you can comprehend what the code is supposed to do. If it takes you more than a minute to understand a section, leave a comment that you don’t understand what it’s doing, it needs to be simplified or, if it really has to be complex, it needs a comment explaining what it’s doing.

Pass 3: Functionality

Now that you understand what the code is doing, make sure there are no obvious errors and that there are tests. For new employees/interns, I’ll actually run the tests and make sure they actually pass, since that seems to be a problem sometimes. Also in this pass, make sure the interface is documented and makes sense.

Pass 4: Sparkle

This stage can be project-specific, but it’s the general gotchas that you, as an experienced engineer, know to watch out for that they may not. Do they need to add hooks for monitoring? Are there error cases they’re missing? Should they add another layer of abstraction or use a different class hierarchy?

You can combine these passes, especially as the coworker starts producing better code.

Finally, if you’re reviewing their code but they just aren’t getting any better, you can resort to Joel Spolsky’s advice for slowing down a lousy programmer (see the “Neutralize the Bozos” section).

Scratches & Bruises

Scratch

Last week, I volunteered at an NYU event (hosted by my old club!) to teach high school girls how to program. It totally changed my mind about what to use to teach kids how to program: they should start with Scratch.

It probably helped that one of Scratch’s creators, Tammy Stern, introduced it. In a few minutes, she created a program that made Beyonce’s head larger and smaller depending on how loud the audience clapped while a funky beat (programmatically generated) played.

90% of the groups of high schoolers ended up with a program that fit a single formula: find celebrity that they liked, find a horribly tacky background, find a song that they liked, then make the celebrity move back and forth on the background while the song played. I only noticed two groups that programmed something interactive, the rest basically used Scratch to make a movie. User interaction seems more conceptually difficult, so it makes sense, but I thought it was interesting.

Each volunteer from Google brought two old-school 15-inch MacBook Pros with them for the students to use. They were really heavy, but I felt like a wimp for hardly being able to carry two laptops. The next day my neck felt stiff and, when I looked in the mirror mid-afternoon, I noticed that my right shoulder was about six inches lower than my left. I tried shrugging it up. It wasn’t painful, but it also didn’t stay up.

I checked in with Andrew about it (one of the perks of working in the same building). He took a look at my shoulders and said, “Let’s go to the doctor’s right now.” The doctor said that a muscle in my back had been “bruised” by the exertion, which was pushing my shoulder out of whack. Over the weekend, my muscle recovered and now my shoulders are just about even again. Phew!

unicorn

P.S. At the Black Girls Code thing I did a few weeks ago, the students had to look up images that they wanted to use on their webpage. One of the girls did a Google image search for unicorns. The first result was the photoshopped image on the right. The little girl gasped. “Unicorns are real?” she asked me, completely seriously. It must be confusing to be a kid in the age of Photoshop.