team_fortress_2_vr.0_cinema_1280.0

VR Needs a Romero

Jeff Atwood’s blog post, The Road to VR, neatly summarizes a bunch of conversations I’ve had recently after receiving my Oculus dev kit.

“If nothing else, it is abundantly clear that even after all these years, VR presents deep, hairy technical challenges even on today’s insanely fast, crazily powerful hardware. That’s exactly the sort of problem suited to the off-the-charts skill level of legendary programmers like Abrash and Carmack. Having both of these guys working on the newest Oculus Rift prototype with an enthusiasm I haven’t felt since the early 90’s means we could be on the verge of a Doom or Quake style killer app breakthrough in VR.” (The Road to VR)

I have such high hopes for VR. Michael Abrash and John Carmack were responsible for some of the best innovations in 3D Video Games and put the First Person Shooter genre on the map with Doom (Carmack) and Quake (Carmack, Abrash). 

When I first strapped on my Rift and loaded up Riftcoaster, I was expecting graphics comparable to a game from 3-4 years ago. Say World of Warcraft in 2008. Instead, the resolution and framerate feel more primitive than GLQuake in 1998, which left me quite disappointed. I tried a variety of games and had a similar experience – something just felt ‘off’ and my brain couldn’t get into it.

However, there was one game that blew me away. It wasn’t a big-budget shooter, or even one of the more highly rated rift demos. It was Rift Racer, an incredibly low-poly racing game that loosely resembles the old DOS game Stunts from Distinctive Software/Broderbund in the early 90’s.

Rift Racer

Rift Racer, an early racing game for Oculus Rift

This game nailed the combo of graphics that were simple enough to appear ‘normal’ within this low-res world, controls that felt smooth, and above all else: absolutely perfect head tracking. It’s crazy how much of a difference being able to look slightly left makes when taking a left hand turn… Or the moment when you’re launched up in the air from a huge ramp and look down as you quickly plummet towards the ground. All of these details added together to create a wonderful, immersive experience.

Abrash constantly refers to ‘immersion’ and this demo made me understand why. Some percentage of aspects of the world around you must feel ‘real’ in order for your brain to believe the trick.

These decisions I just described are not feats of engineering or technical challenges, they’re design decisions. I’m describing how the game ‘feels.’

Who will be the great designer to step up and push the technology in a human direction? Who will painstakingly tweak the nausea-inducing prototype to nail the exact right use of visual cues, audio, and sensor motion until my brain truly believes I AM the Pyro from Team Fortress 2?!

It’s great that we have two of the world’s greatest game programmers working on this challenge, but for VR to succeed, we need a designer with a vision to compliment Carmack and Abrash’s wizardry.

The book Masters of Doom beautifully describes the type of product created when a great designer and a great engineer get together. Doom and Quake were perfect examples of this union.

If Doom and Quake represented the first wave of interactive 3D, Virtual Reality will be the second. A designer needs to rise to the occasion, or else we’ll end up with clunky, high-tech systems that don’t feel human. The same pairing of great games with the right graphics, controls, and mechanics need to be designed for VR to be a success.

Who will be VR’s John Romero?

Special thanks to Christian Arca and Henrik Rydberg for critiquing a draft of this post.


Did you like this post?

Donate 0.001 BTC

By donating a tiny amount of bitcoin, you’re letting me know that I should continue writing new blog posts. I don’t plan to get rich but want to see what happens if the ‘Like’ button involves a transaction of a trivial amount.

Importance of Being Present

Being Present

Have you ever sat in a meeting where everyone stares at their laptops? You look around the room and can’t tell if anyone’s actually paying attention. Chances are they’re doing their own thing: Checking e-mail, Playing Minecraft, who knows?

As laptops and mobile phones have become more ubiquitous, the problem worsens.

It’s easy to stare into your screen while someone else is talking. “I’m just checking this one e-mail,” you think to yourself, or “What if our servers go down?! I have to be able to respond on IRC, right?”

I found that more and more, I would just be refreshing Twitter or checking Hacker News.

In other words, I wasn’t present.

So for the past year, I haven’t brought my laptop to meetings, and I don’t check my phone.

It’s been fascinating.

The Results

  1. The people who are talking ONLY look at you. Everyone else has their laptop open, so the speaker’s eyes are fixed on you because you’re the only one looking at them and making eye contact. Maybe everyone else is subconsciously aware of what’s being said, but it’s really interesting to see everyone else staring at their screens while you and the person talking are actually communicating.
  2. Meetings take less time. If one person is totally engaged, it quickly becomes clear that things are going off track and they can speak up and say “Hey guys, let’s keep it moving.”

This doesn’t happen if people are staring at their screens. Instead, they just continue typing or doing whatever it is they’re focused on and assume that the conversation will naturally continue and get itself back on track. You think, “This is a great opportunity for me to check the Oculus Rift forums and see if my order’s shipped yet” or “Time for me to check Reddit repeatedly!”

When you don’t have your laptop, your only option is to sit and stare at the wall.

You see this happening over and over again. Though people feel like they’re being more efficient by bringing their laptops, it’s not really true. You have people who sit there and do other work during a meeting, but because they’re forced to listen and pay partial attention, that work suffers. It would actually be better if they just excused themselves and did their work in a separate room instead of contributing halfway to the conversation and halfway to their work.

What a colossal waste of time.

Take the 10-15 minutes that it takes to listen and then do your work separately, in a place where it’s actually quiet and you can focus. Not only will you complete your work more efficiently, but the meeting will actually take less time!

Two caveats

  1. Some people have said, “But Brad, I work in an organization where we regularly have meetings that are 1.5-2 hours long.”

    If your meetings regularly last that long, you’ve got bigger problems to solve. To start with, don’t bring your laptop. Be present, and others will hopefully realize that your time is valuable and spending two hours watching each other’s mouths move is a waste.

  2. Perhaps you need your laptop for a presentation. Maybe you have some data to show, or a new prototype you want to show off. That’s fine. While you’re presenting, pull out your laptop, plug it in, and present away. Once you’re done, turn it off and close it. You’re done presenting.

The Benefits

I’ve found that I remember more from meetings and have heard constant comments from people that they love how ‘engaged’ I am. In other words, “I appreciate the fact that you actually paid attention to me when no one else did.” That’s a terrible thing for someone to have to say! Presence matters to people. They notice, and they care.

So next time you go to a meeting or are sitting there talking to someone over coffee, put your laptop away, put your cell phone away, look the speaker in the eye, and be present.


Donate 0.001 BTC

By donating a tiny amount of bitcoin, you’re letting me know that I should continue writing new blog posts. I don’t plan to get rich but want to see what happens if the ‘Like’ button involves a transaction of a trivial amount.

Image Credit: Unknown Artist

If only Twitter could bring him back…

As a Product Manager, I try to think of every potential permutation or edge case that could affect a feature. I suspect the PM’s at Twitter never anticipated this one…

Ovidiu Opresco was an amazing designer and member of the Shapeways community. He took up 3D Modeling at the ripe age of 70 and created tons of great products, including the awesomely viral Dad’s Beer Ring:

Sadly, Ovidiu passed away this week. The Shapeways community posted memorials for him, and he will definitely be missed.

Today, a few days after his passing, I received this notification from Twitter:

“Bring Ovidio Opresco Back to Twitter… Mention @OvidiuOpresco in a Tweet to bring them back.”

Man. In any other scenario, this would be a great feature, but when I saw this today, it made me quite sad. No amount of tweeting will bring Ovidiu back to us. Rest in peace.

My Daily Checklist

I’m terrible at sticking to a routine. Whether it be a simple daily task or a monthly recurrence, I tend to do quite well for the first 3-4 attempts and lose interest shortly afterwards.

After years of trying apps, systems, and elegant ways to solve this problem, I’ve settled on a simple paper todo list that sits on my desk.

Here are the essential product tasks that I make sure to run through on a regular basis:

Weekly checklist
* What’s in the next release? The next one after that?
* Are dev and product estimates in for all projects we care about?
* Do we have release dates for all the projects we care about?
* Who will pick up each team’s work?

Daily checklist
* Who is working on what in dev/product.
* Daily sales, uploaded models, community growth, traffic sources.
* Results of past/current tests.

How did I pick my checklists? These tasks represent the minimum necessary set of stats and information to know what’s going on in the Product team and across the company. Believe it or not, with 60+ people, it’s really hard to get a good grasp of what’s happening.

Why so much focus on what people are doing ‘right now?’ We have a daily Product standup, but there are alot of small issues that are surfaced at any given time and it’s important to make sure we stay focused.

Why so much focus on releases? I was never a huge proponent of release dates, falling more into the ‘when it’s done’ line of thinking made famous by iD Software, Blizzard, and Valve. For this reason, I tend to ignore long term milestones. However, I find that projects slated for release in the next 2 weeks gives just enough visibility to the rest of the team to plan their day to day without turning into an inflexible waterfall shop.

What do you check every day to keep things manageable?

Organizing Handlebars Templates in NodeJS with Jade Partials

I’ve been banging my head against the wall trying to learn Backbone.js. My usual process for learning a new technology or framework is to try to do things the ugliest way possible to get it working, and then refactor and spot patterns to organize things. One of the most frustrating pieces of my stack right now are my handlebars templates, which started out lumped into a bunch of <script> tags at the top of my page.

For those of you that have tried working with Handlebars before, you’re probably more than familiar with blocks of {{code}} like this stuck into your <head> tag:


// Report - Sales Tax
script(type='text/x-handlebars-template', id='salesTax-template')
  h1 Sales Tax
  {{#each report}}
  {{#dates}}
  h3 Start Date:
    {{start}}
    | End Date:
    {{end}}
  {{/dates}}

  {{#totals}}
  h2 Totals:
  p Services:
    {{services}}
  p Products:
    {{products}}
  {{/totals}}

  h2 Tax:
  {{#tax}}
  p Services:
    {{services}}

  p Products:
    {{products}}
  {{/tax}}
  {{/each}}

I was really frustrated with these files cluttering up my layout.jade file in my root directory, because I need to deliver the templates when I first load the Backbone app. I’ve read a ton about how to split Handlebars templates into their own files using Backbone, but haven’t seen any decent solutions, so I set out to solve it using other tools in my stack.

The (ridiculously simple) solution I came up with was to use Jade partials on my NodeJS server so that with the initial pageload, Jade would compile all of the templates into one main HTML file and serve it to the client! Easy.

So here’s the code I’ve got in my layout.jade:


// Handlebars Templates - move these to separate files eventually
!=partial('templates/reports')
!=partial('templates/reports/salesTax')
!=partial('templates/reports/newClients')
!=partial('templates/reports/selectStylist')

The !=partial command searches the views directory for any files matching the path/filename you specify ending in .jade. For example, I’ve used the folder ./templates and placed all of the templates for my reports under ./templates/reports. The base template that acts as a container for my other report templates is called index.jade and is called on the first line. The rest of the templates are for individual report templates.

Finally, I’ve included the following code in my initialize() function for each of my Views to render the templates.

reportView.coffee:


### Reports - Base collection for all reports ###
class window.Reports extends Backbone.Collection
  model: Report

# Overall report master view!
class window.ReportView extends Backbone.View
  initialize: ->
    @el = $('.containerOuter')
    _.bindAll this, 'render'

    # Compile Handlebars template at init
    # (Not sure if we have to do this each time or not)
    source = $('#report-template').html()
    @template = Handlebars.compile source
    @render()

  render: ->
    renderedContent = @template { }
    $(@el).html renderedContent

Jasmine and NodeJS Testing

As you know if you’ve read my previous posts, I’m still wrapping my head around this whole development thing. Having worked on websites for a long time from the product side, I hear engineers talk about things like BDD, writing tests, etc and how it’s definitely the right way to go. As such, I’m striving to do things the ‘right way™’

After poking around through a few different NodeJS testing frameworks, I settled on Jasmine (mainly because we use it at Bookish and I liked how the specs look when written in Coffeescript). There’s a npm module called jasmine-node that gives you the basic toolset you need to get Jasmine tests working, but it unfortunately doesn’t come with any good documentation on how to setup your test runner or anything like that. Here’s the best way I’ve found to run tests from the command line so you can run them locally or from your CI environment.

Step 1: Install jasmine-node

Note: This requires npm. If you need help installing npm, click here

Installing jasmine-node is actually quite simple. Just use the following command from your project’s base directory:

npm install jasmine-node

This will create a folder under ./node_modules/ called ‘jasmine-node’ that contains the command line version of jasmine which is compatible with nodeJS. If you want to check out the jasmine-node source tree before installing, take a look at github repo.

Step 2: Create your test runner

This is where, in my opinion, the jasmine-node docs fall short. Installing jasmine-node is a cinch, but you have no idea where to go from there. The first thing I figured out is that jasmine-node just gives you the simple executable that will output the results of all of your tests as well as the framework for testing, but it doesn’t give you the actual script to run the damn tests :D

As such, I’ve stolen a really great test runner script for jasmine-node. I can’t remember where I got it from, but it should work for you. I call this file ‘runtests.coffee‘ and place it in my ./tests/ directory:

./tests/runtests.coffee (download)

jasmine = require 'jasmine-node'
sys = require 'sys'

for key in jasmine
  global[key] = jasmine[key]

isVerbose = true
showColors = true
coffee = true

process.argv.forEach (arg) ->
  switch arg
    when '--color' then showColors = true
    when '--noColor' then showColors = false
    when '--verbose' then isVerbose = true
    when '--coffee' then coffee = true

jasmine.executeSpecsInFolder __dirname + '/spec', ((runner, log) ->
  if runner.results().failedCount == 0
    process.exit 0
  else
    process.exit 1
), isVerbose, showColors

As you can see, the testrunner loads jasmine, parses the command line parameters, and then runs each spec file in the ./spec directory.

Once you’ve placed your testrunner at ./spec/runtests.coffee and run it through the coffeescript compiler, you can make sure it works by running the following command from the base directory of your project:

node ./tests/runtests.js

If something’s busted, node will throw an exception and otherwise, you’ll see something like 0 tests, 0 assertions, 0 failures Nice!

Bonus points: To create a simple cake command to run your tests, add it to your Cakefile! (example)

Step 3: Writing your first spec

Most testing frameworks have the concept of a test suite and jasmine is no different. Each file defined under ‘./spec‘ represents a set of tests and within that set of tests, you can create a number of features, a number of tests for each feature, and a number of assertions for each test. If that last sentence sounded like jibberish, check out the jasmine suites and specs documentation. I won’t go into different spec-writing philosophies, as I’m still learning that myself.

To create a spec, you need to make a new file under ./spec Older versions of jasmine-node required you to have ‘spec’ in the filename but that doesn’t seem to be the case any more.

Let’s start with an example from one of my projects, node-towerd, a tower defense game written in node.

In my game, there is a controller called ‘world’ which runs the show. It proxies events to and from game objects as well as to and from the client. Within the world, there are a number of game entities like maps, mobs, and towers. Let’s take a look at the spec for towers:

./tests/spec/towerspec.coffee (download)

### Tower Tests ###
basedir = '../../'
App = require basedir + 'app.js'
Tower = (require basedir + 'controllers/towers.js').Tower
TowerModel = require basedir + 'models/tower-model.js'
Mob = (require basedir + 'controllers/mobs.js').Mob
MobModel = require basedir + 'models/mob-model.js'

Obj = (require basedir + 'controllers/utils/object.js').Obj

# Unit Tests
describe 'Towers towers.js', ->
  beforeEach ->
    world = new Obj # Required because maps relies on 'world' for some events

    # Stub data
    @name = 'Cannon Tower'
    @id = 'cannon'
    @active = 1
    @symbol = 'C'
    @damage = 1
    @range = 2

    @fakeMob = new Obj # Load a fake mob to emit events
    @fakeMob.symbol = 'm'

    @tower = new Tower @id, world

  it 'Loads a new tower called Cannon Tower', ->
    expect(@tower.id).toEqual(@id)
    expect(@tower.name).toEqual(@name)
    expect(@tower.active).toEqual(@active)
    expect(@tower.damage).toEqual(@damage)
    expect(@tower.range).toEqual(@range)

  it 'Saves itself to the DB once loaded', ->
    TowerModel.find { id: @id }, (err, res) =>
      expect(res[0].name).toEqual @name

  it 'Spawns itself on the map at 5, 4', ->
    @tower.on 'spawn', (type, x, y, callback) =>
      expect(@tower.x).toEqual(5)
      expect(@tower.y).toEqual(4)
    @tower.spawn 5, 4, (callback) ->

  it 'Finds no targets when none are in range', ->

    fakeWorld = new Obj

    # Spawn the tower
    @tower.spawn 5, 4, (callback) ->

    # Spawn a fake mob
    fakeMob = new Mob 'warrior', fakeWorld

    fakeMob.spawn 0, 0, (callback) ->

    @tower.checkTarget fakeMob, (res) ->
      expect(res).toEqual []

  it 'Fires on a target when one is in range', ->
    fakeWorld = new Obj

    # Spawn the tower
    @tower.spawn 5, 4, (callback) ->

    # Spawn a fake mob
    fakeMob = new Mob 'warrior', fakeWorld

    fakeMob.spawn 5, 5, (callback) ->

    @tower.checkTarget fakeMob, (res) ->
      expect(res.id).toEqual 'warrior'

This is a relatively large spec, and I’m sure I’m doing a ton of things wrong, but it should give you a good idea of how most specs are structured. You start by loading all of your dependencies via node’s require command. Note: you don’t have to require jasmine-node, the test-runner takes care of that.

Describe your feature

Next, you describe each feature with a describe 'featurename', -> anonymous function. This lets jasmine know that we’re going to start defining a new feature. If any tests under ‘featurename’ fail, jasmine will report back so you know where to start debugging.

Before and After

Once we’ve described our feature, jasmine lets us group any logic that needs to take place repeatedly before each individual test runs via the beforeEach feature. It’s usage is really simple. If you need to create new objects, reset variables, or wipe your database, just create a function called beforeEach or afterEach like so: beforeEach ->

Tests

Finally, let’s write the damn test! Defining each test is as simple as creating a new function that starts with ‘it’ and writing out what you expect the feature to do in plain english. For example:

it 'Loads a new tower called Cannon Tower', ->
  expect(@tower.id).toEqual(@id)
  expect(@tower.name).toEqual(@name)
  expect(@tower.active).toEqual(@active)
  expect(@tower.damage).toEqual(@damage)
  expect(@tower.range).toEqual(@range)

Within each ‘it’ function, jasmine supports a number of ‘matchers’ that allow you to evaluate whether the feature is working as intended or not. In your jasmine-node reports, these matchers are called ‘assertions.’ In the above example, we make sure that a number of variables are equal to what we’re expecting. You can use matchers/assertions to check if variables are defined (or not defined), make sure a variable is set to a certain value, or even check if an exception is thrown. For more info, you should read the full list of jasmine matchers.

Wrapping up

So you’ve installed jasmine-node, created your test runner, created your first spec, and defined your first feature! You can now run your test suite and see if everything passes.

Warning! When writing asynchronous tests, jasmine-node will not automatically wait for your asynchronous functions and callbacks to run. You need to tell it to wait a callback using the asyncSpecDone() and asyncSpecWait() commands. Their usage is as follows:


describe 'Customers', ->
  it 'Should save a customer\'s address', ->
    var customer = new Customer()
    customer.save (err) ->
      expect(err).not.toBeNull()
      expect(customer.name).toEqual('bob')
      asyncSpecDone() # Tell jasmine that our Async function has finished executing

    asyncSpecWait() # Tell jasmine to wait for the above function to finish executing

To see more example specs from my project node-towerd, click here. To read more about writing specs in jasmine, click here.

Coming soon: Continuous Deployment in NodeJS with Jasmine and Jenkins (once I actually get it working!)

A Simple Game Loop in NodeJS

When I set out to learn Node, the last thing on my mind was writing a game server. I was first intrigued by the event-loop architecture and the ability to write the same code on the client and the server for web apps. Looking back it’s the perfect choice for serving multiplayer games.

This is a quick overview of typical game architecture. All examples reference my github project node-towerd. Feel free to skip ahead if you already know this stuff.

Every action in traditional game architecture follows this pattern:

  1. Handle client input
  2. Update the game world
  3. Draw anything that’s changed

As it turns out, only the first two happen in Node. We draw everything on the client.

The first struggle was setting up this game loop in Node. Typically, your game loop happens in set increments called a ‘tick.’ This allows the game to do things like move an enemy or player at controlled speeds over a given period of time.

This traditional game loop would look like this in coffeescript:

setInterval gameLoop, 33 # 33 milliseconds = ~ 30 frames per sec
  onTimerTick() = ->
    handleInput()
    UpdateGame()
    Render()

I decided to take a slightly different approach given node’s focus on events:

  • Updates that happen on regular intervals use the game loop
  • All other events that require immediate reaction use EventEmitter events that are fired by entities (slang for game objects) within the world.

For example: a mob (enemy) must be able to cross the screen in about 10 seconds. If our event loop hits once per second, the mob should move 1 tile per second. Each time a mob moves, each tower should check if it’s in range and fire accordingly.

So my server-side game loop looks something like this (see ‘world.coffee‘ for the exact code):

### Start the game!! ###
start: ->
@game = setInterval =>
  @gameLoop()
, @gameTime
gameLoop: -> # One iteration of a game loop
  # Runs every '@gameTime' seconds
  @emit 'gameLoop' # Stuff listens to this to know when a 'turn' finished

Each time (@gameTime) hits, the server emits an event called ‘gameLoop’ that every entity listen to. When a mob moves, the mob fires an event and other objects in the world listen for that event. In my current example, I’m using the world as an event relayer (proxies events between objects and to the client), which I’ll cover in a later post.

This is quick recap of the simple Game Loop I put in place. If you want to know more, check out this post which is the most exhaustive resource about the subject I’ve found.

Shut up and learn to code

As a product manager, one of the most difficult feelings in the world is to be involved in an early project, work with a team to come up with a vision, put together some great mockups and wireframes, and then sit around and twiddle your thumbs while everyone else is writing code.

Although Adil warned me otherwise, I decided to revisit my coding skills.

“Dude, I need a handle.”

Seriously, I feel like Joey from Hackers (pictured above).

As I set out to learn all of this stuff, I kept some really simple rules:

  1. Stick to one language (I chose NodeJS/Javascript)
  2. Work on one project at a time
  3. Always code in the open (no closed repositories/closed source projects)

For my first project, I created a simple Bookshelf app that lets you import your lists from Goodreads. When they fix up their API (currently no OAuth requests go through), I’ll add the ability to import friends. You can see the project here: https://github.com/bdickason/booklist

For my second project, I decided to build a game. This took me completely out of my comfort zone. Whereas most of the stuff I did for Booklist which was a typical web app was very similar to the projects I work on every day. Game programming is almost entirely different. Yes, a few core concepts apply but the idea of basing your entire cycle off of a game loop (more on that to come) and rendering complex animations via Canvas were totally out of my league.

Needless to say I’ve been pounding away on it and after a few weeks, have a decent Tower D clone. As Notch says, I have no idea what the game is going to be as I work on it, so I’m trying my hardest not to finalize the idea and just let the code do the talking for now. You can check out this project here: https://github.com/bdickason/booklist

Director of Product Shapeways