Thursday, May 28, 2015

The learning curve

Once upon a time in the not-too-distant past, games were small. Game engines were often crafted in a tight, consistent way that made understanding the entire code base relatively easy. It was feasible to keep up to date on "state of the art" techniques with a little bit of dedicated reading.

That time has passed. The days of being able to maintain intimate knowledge of every single system in a AAA game are long gone: games are just too big. And it's not just games that are bigger: game development itself is a much bigger field than it was 10 years ago. There's just too much to understand, and too many breakthroughs being made on a daily basis for anyone to stay on top of it all.

Probably the most useful skill in game development is being able to learn quickly.

I personally learn new things every day. It's a job requirement. When you have a bug in an unfamiliar system, your mission is to quickly get up to speed on what it's doing, what it's supposed to be doing, and why it's not doing what it's supposed to be doing. That all involves acquiring domain knowledge, and overcoming the learning curve.

It's well established that the best way to learn is by doing. But how does one learn how to learn? Well, I can tell you something that doesn't help...

All too often in practice, when people get stuck, they ask for help too easily. And equally as often, their lead programmer's focus is on unblocking them, rather than allowing people to learn how to unblock themselves.

Having an attentive, helpful and always-available lead is good, right? Wrong.

This behavior is bad for the individuals, it's bad for the lead, and it's bad for team dynamics: it creates an environment where only a handful of people are capable, and the rest of the team quickly falls apart when they're not around.

I'm not saying that teaching is ineffective. But if you think about it, the lesson being taught here is a reinforcement of behavior: on a meta-level, it's teaching people to be dependent, rather than self-sufficient.

And it's worse than that. A strange anomaly I've observed is that engineers seem to have a "helpnessness bit". Once it's flipped, it tends to stay flipped. After they get stuck, and receive help, they continue to request help on things that they could figure out for themselves, because their bit has been flipped.

In order to learn how to solve hard problems, you have to solve hard problems.

That means grinding up against them. It means dealing with frustration, and helpnessness, and figuring out a way to make progress anyway. It means figuring out new techniques to unblock yourself, and on the meta-level, figuring out how to figure out new techniques.

Giving engineers an easy answer when they get stuck is actually doing them a disservice. It denies them the opportunity to develop the skills they need to unblock themselves, both now and in the future. It's giving them a fish rather than teaching them how to fish.

Of course, the constraints of a particular project might not afford the luxury of personal development. But I think this should always be a conscious choice, and that it should be made with due consideration to what you gain (immediate progress) vs. what you lose (teaching your engineers to solve hard problems by themselves).

So given a project with enough wiggle-room to "do it right", how should you conduct business? Well, here's my advice for both mentors and mentees.

  • Before you ask for help, spend an appropriate amount of time investigating the problem for yourself.
  • What would you do if your lead/mentor was not available? How would your lead/mentor go about solving this problem?
  • Don't be lazy. Solving problems is hard. It's always going to be easier to have someone explain something to you, but the goal is to become more self-reliant. Put in the effort.
  • Be methodical, and observant. Write down what you've tried, and fully investigate anything you don't understand.
  • If you need more knowledge, figure out where to find that knowledge. Hit the documentation. Read through the code in the functions you're calling. F11 is your friend..."step into" code and see what it does.
  • Check your assumptions, and if possible, reinforce them by using asserts. Is the refcount what you expect it to be? Who owns this object? What chain of events led us to this point?
  • When you decide to ask for help, make it a conscious choice.
  • When you do ask for help, ask for specific help and have your data ready: What does the callstack look like? What specific guidance do you need to become unstuck? Understand that your mentor's time is valuable - they probably have problems of their own to solve.
  • When you receive help, you should be looking for that "lightbulb" moment, when things click into place. At that point, thank the person who helped you, and get back to "independent" mode. Unflip the "helplessness bit".

  • Provide context, but let your mentee solve the problems. Set expectations: make it clear that the responsibility to complete the task is on the mentee.
  • If the project affords it, plan tasks that build on your mentee's previous knowledge. Set them up for success.
  • Unless the task is critical path, give your mentee time and space to figure things out. Don't hover. But of course, don't be absent either. There's a huge difference between between being "hands off" vs. plain negligent!
  • When you decide to help someone, make it a conscious choice, not something you do by default. Weigh the consequences.
  • When someone asks for help, require that they've done their homework first. If they haven't, ask them to do that before you provide help.
  • Provide guidance by asking questions rather than giving answers. "How do you know that your assumptions are correct?", "How can you go about figuring that out?", etc.
  • When you unblock someone, don't solve the entire problem for them. Give them what they need to be unstuck and then let them figure out the rest.

This arrangement is a contract, and it's important for both parties to understand that this is how the relationship works so both sides know what to expect. As a mentee, this isn't the easiest path. But the world needs more self-reliant programmers. And smooth seas do not make skillful sailors.