Sunday, May 27, 2012

Management 101

You're a lead programmer and have been for a number of months, or years, and one day your manager taps you on the shoulder and says that there's going to be a change.

You're going to be a manager!

Congratulations!

Welcome to management!

Your work life will never be the same! Well, that's a bit of an exaggeration but things will be quite different. You've had a taste of leadership and mentorship leading up to now (right? ...right?!), so the difference won't be so stark.

I'm not going to talk about management styles so much as point out a few things that may not be obvious for programmers who are new to managing people instead of software.

Obvious-yet-not-obvious point #1: Managers are information conduits.

Your primary goal is to get all the information to your team that it needs in a timely manner. You need to beat the rumor mill; every time they look elsewhere for information, their faith in you degrades a tiny bit. Think about when you go to your manager most often -- it's not to ask about your raise (well, maybe it is...), but it's to know what's going on, who needs what by when, what's coming down the pipe next month, or who should be taking care of that urgent support issue that just fell out of the sky.

Obvious-yet-not-obvious point #2: Nothing should be a(n unpleasant) surprise when it doesn't have to be.

Pleasant surprises are great. "Beer this Friday? Company's paying? Sweet!"

Unpleasant surprises aren't. Some are occasionally unavoidable -- the company often can't give advance warning about layoffs because that will wreak unnecessary havoc on morale and the share price -- but many aren't. If you're about to give someone a below target performance evaluation it should not be a shock to them. The lead up to this should have included several, possibly difficult, conversations about where things are heading and the consequences if the trend continues. Not only that but a case like that should have a plan for remediation.

Obvious-yet-not-obvious point #3: You are responsible for the growth of your people.

One of the big differences of being in a management role compared to being in a mentorship-focused lead role is that when one of your employees didn't get a promotion for which they had been hoping, you are now the first person they will ask why. And you better have good answers for them.

Every quarter I sit down with each member of the team and we put together a list of accomplishments that we want to achieve over the following three months. This list of objectives is broken down into what's expected (on target) and what goes above and beyond expected (above target/significantly above target). At the end of the quarter we go over everything that's been accomplished, and at the end of the review period it's obvious to all parties if there's been continuous, steady improvement.

Although the onus to execute lies with them, you need to coach them, guide them, find opportunities for them and help them find their way out of ruts.

Obvious-yet-not-obvious point #4: Trust is difficult to form but easy to break.

One item to keep in mind is that topics that come up in a 1-on-1 meeting should be considered confidential. If you ask your star why he seems distracted and not his usual affable self and he mentions that he's dealing with some unpleasant family issues, you'll want to keep those discussion notes private. "Jim's not on his A-game because his Mom died" is not an appropriate point to mention at the team stand-up meeting. It's also not appropriate to mention if anyone else asks why Jim seems to not be his usual self.

During that conversation, a lot of faith and trust was placed in you when that news was broken, it may have taken them a long time to work up to telling someone at work about it, and if you violate that trust you may never see it again. This may mean that you'll never be the recipient of other personal thoughts, like "I'm unhappy with my job and want to do something else, probably somewhere else."

Obvious-yet-not-obvious point #5: You'll have less time to do programming at work, but that's OK.

Much of your schedule is going to disappear to meetings, to the overhead of task scheduling, to problem solving, and back to meetings. At first I felt that I was failing because I was doing less programming work but this wasn't the case -- it just took a while to recognize that all the other tasks filling my schedule had value too.

Obvious-yet-not-obvious point #6: People aren't machines, they don't have instruction manuals.

You can't attach a debugger to one of your employees to find out what's wrong, nor can you write an automated test to prevent problems from coming up. Forming a network with your current and former managers is extremely helpful when it comes to fielding these new problems that you will run into. Failing that, you can always ask HR, they are going to become surprisingly helpful in your new role.

I hope that I didn't scare you -- you're going to do fine. Really. Some adjustment will be needed but it'll all smooth out soon enough. In my next post I'm going to talk about establishing stability after this minor organization shake-up.

Thursday, December 15, 2011

A Non-Exhaustive List Of Things That Xcode Sucks At

I do a lot of cross platform development, ranging from PC to consoles to Mac/iOS, and as a result I've used a lot of terrible tools before. Some were early in the development cycle of a new platform so they were understandably rough around the edges. Xcode, however, is a whole new level of terrible. Device registration and provisioning is a pain but this is mitigated by not having to do it all that often.

  • It crashes. A lot.
  • No mixed source/assembly debugging. Having source interspersed with assembly makes it much easier to find your bearings and orient yourself with respect to your code. Mind you mixed listings shouldn't replace either source-only or assembly-only debugging, but should complement them.
  • Registers view is at the bottom of the watch window. If I'm in assembly land I don't want to see my symbolic locals, I want to see my registers. Allow me to put my registers front and center!
  • Focus moves from debugger command window when "step instruction" commands are issued from outside my own code. I have to re-click on the debugger command window every time I punch in "si". On what planet is this acceptable?
  • The debug menu says that control-F7 will step one instruction. Pressing control-F7 on my keyboard (ultra thin USB) does not step one instruction. In fact, it doesn't do anything.
  • Hovering over the debug icons say that pressing control and clicking "step into" will step a single instruction. But this isn't a sticky setting, so if I press control and click "step into" twice, the first time will step an instruction and the second will perform a source line step. Mondo fail.
  • It would be nice if the callstack window was separate from the thread selection control. This way it's quick to cycle among multiple threads to get an idea of where each one is without having to expand, and contract, multiple drop-downs.
  • Tabs with source files would be *super* *handy* for switching back-and-forth between multiple files when debugging. Often I find my self changing (enabling/disabling) breakpoints in separate files regularly as execution progresses and it's a huge pain to have to go back to the folder view to find my file.
The principle of least astonishment is a good guideline for putting together a good user experience, unfortunately whenever I have to use Xcode in anger it consistently astonishes me.

Monday, January 10, 2011

HlslDom: An Overview

HlslDom is a .NET library for programmatic HLSL shader program creation, inspired loosely by Microsoft's CodeDOM.

When using HlslDom you first create a Program, the top level container for all functions, user defined types, and global variables.

Types that are intrinsic to HLSL, like scalars, vectors, and matrices, are managed by a type registry. These intrinsic types, save samplers, are heirarchical in that vectors are considered a number (1..4) of scalars, and matrices are considered a number (1..4) of vectors. These basic types can then be aggregated by the user into a structure, with semantics set for each field.

HlslDom supports most of the intrinsics that are included up to Shader Model 3.0. Intrinsics can be called like any other function and polymorphic versions will correctly validate parameters and determine return parameters.

The concept at the centre of HlslDom is the expression. Expressions are used to represent everything from arithmetic (with BinaryExprs), to variable declaration (DeclExprs), to program flow (IfExpr/ForExpr/TernaryExpr). Expressions may or may not have a value. Those without values are usually syntactic constructs like if/for/while expressions, while those with value are expressions that evaluate to something that can be used, like a call to another function or a struct member access.

Variables at all scopes can be automatically named, or given names. Expressions that may be expensive to evaluate, like calls to functions or large mathematical constructs, can be assigned to local variables with DeclExprs (declaration expressions), and optionally set to "const", to keep the amount of generated code down.

User-created functions are a collection of at least one expression. That one expression that a function has to have, at a minimum, is a ReturnExpr representing a return value. The returning type of the function is automatically inferred based on the types of its contained ReturnExpr.

Once all the desired user defined functions are created, the program can be emitted. Currently HlslDom supports emitting straight up HLSL or emitting a DirectX effect definition.

HlslDom can be found on GitHub (https://github.com/maxburke/HlslDom).

Fun with XNA, part 2

It's been four months since I've last written about my XNA project -- an eternity! I haven't been idle, most of my work has been behind the scenes on pipeline stuff.

When I left off last I had the world geometry rendered, with basic lightmaps and textures, but there was quite a bit missing. Quake 3 was quite a vibrant game, in large part due to the multitexturing effects that were used. Surfaces animated and swirled, effects were stacked on top of each other, lights flickered and pulsated. If all I'm drawing is polygonal geometry with one texture and maybe a lightmap it's not going to look anywhere near that good.

Quake 3 achieved most of its visual effects with shaders, though being released in 1999 it was many years ahead of languages like HLSL/GLSL/Cg, and even ahead of fragment/vertex assembly languages. Contrast that with today where our world is nearly at a point where el-cheapo feature phones have programmable graphics pipelines. Quake 3's shaders were relatively simple, specifying a texture that could be used, how it was to be sampled and its colours manipulated, and how it was to be blended with others.

I needed a way to get these simple Quake 3 shaders into my engine, into a more XNA-friendly format. There were a few approaches I tried.

First, I tried hand writing a couple shaders. Brute force is occasionally worth it, but not here. It took way too long to be a viable process, but at least I figured out what I would need to do.

Next, I tried generating shaders at runtime but this I shelved because XNA doesn't support runtime shader compilation when deploying applications.

I took the beginnings of the previous step, generating the shaders programmatically, and worked it into a pipeline step. This first step to generating them in a pipeline was to parse the existing Quake 3 shaders. Since the format was documented (here is the Q3 Shader Manual), I figured this was going to be cake. Sadly, it wasn't documented well enough, and I was getting a slew of unexpected tokens and effects. I ended up guessing as to what they might be, within the context they were used, and discarded the rest with a TODO attached that I will take care of them later :).

Once the Q3 shader was parsed I had to turn it into a list of textures, some flags, and a pile of HLSL. The textures and flags were pretty easy, but the HLSL less so. I tried a simple text-based HLSL generator but keeping track of state and variables became messy in short order.

After putting the project down for a few weeks, I was sitting on the couch thinking that it would be nice if it was as easy to build a shader as it was to build C# using Microsoft's CodeDOM. Out of that, I put together a library, HlslDom (which is hosted on GitHub! https://github.com/maxburke/HlslDom), to stitch together HLSL programs via code.

This weekend I was at home, sick, and didn't have much to do but work on HlslDom and this shader compiler. The shader compiler is now done, it generates valid HLSL, and I'm getting the HLSL shaders integrated back into the game portion! I'm hoping to have screenshots following soon.

Friday, January 7, 2011

Virtuals don't kill performance, people do.

This post is in response to Scott Graham's blog entry on a Data-Oriented C.

There are two areas where we come up short in regards to the use of data oriented programming, tools and (more importantly, IMO) education.

C++ gets a bad rap for enabling poor programming techniques but in the end the language isn't inserting virtuals on our behalf. Evangelism I think is the key here. People need to see the kind of code in action, beyond hand-wavey snippets included in blogs. Books need to be written. School curricula need to be updated to show these techniques to students. There is an entire industry centred around preaching the use of OO patterns and the result is that people finish university thinking that Cats are Animals are Objects and they all need Update methods.

To make the default decision be the correct one it would mean having to make incorrect choices either impossible (preferable) or extremely painful. I think, in that case, that perhaps C isn't the best choice of language as a base for this type of programming. Perhaps a shader-type language, something that is extremely restricted in terms of what the programmer can do outside of his own local task context and ideally removes the task of management of data (memory allocation, etc.) from the actual computation. A language that can be retargeted to asymmetric environments like SPUs or GPUs and operate well within the inherent restrictions that accompany them would be extremely beneficial with the new processors that are entering the market.

Tuesday, December 28, 2010

HlslDom

My latest project is HlslDom (GitHub: https://github.com/maxburke/HlslDom). Its creation was driven by my XNA project where I needed a solution to create HLSL shaders as part of a pipeline.

It's written in C# and is designed to integrate into .NET applications. Because the target application is XNA it is mostly designed for DirectX 9-level HLSL, though any and all patches are welcome if DX10+ support is desired :)

Tuesday, December 21, 2010

Stop! Enough already!

At which point do you stop adding? Is there an end point for product expansion? Is simplicity inevitably doomed to be displaced by shiny new things?

As a kid I used to love playing sports video games, sometimes even more than playing the actual sports, and every few years I still think I enjoy them. Keyword: think. Every other year or so I'll pick up the latest NHL or Madden video game, drop it into my Xbox 360, and start a new game.

Then the loading screens flash, showing the controller mappings, and my interest usually goes from mildly curious to nonexistent. Every button and control stick is mapped to multiple functions depending on whether you're on defense or offense, with the ball, without the ball. It's mind boggling. Modern first person shooters and RPGs aren't much better but there's usually some sort of ramp up in game play for you to adjust to before you're expected to be a Dual Shock Harry Connick.

There's always a rush to add more, to make it new, to justify a purchase. With some video games it's to the point now where my hands have problems contorting themselves to chord the buttons correctly.

It's not just video games that are succumbing to this. It's also Facebook. It's Twitter. It's Ford. Some of these goods aren't forced though, I don't have to buy a new video game or a new car if I like the old one, I can just stick with what I have. This doesn't really apply to Twitter or Facebook or the (somewhat) new Google search results page -- these services are forcing new functionality down my throat.

Is it possible for a product or a service to say, "nah, let's stop, I think we're as good as we're going to get"?