Usual disclaimers apply: this is what works for me, it may not work for you; I could be completely insane and talking about my posterior; I probably am just repeating what other people have said elsewhere; I'm going to be hypocritical in places by giving advice that I don't follow overly well myself. So there.
Why It Matters
It is not uncommon to read about projects that are suffering from lack of development resources. Let's be honest: no project has "enough" people, ever. There's always something else that could be getting done "if only we had another pair of hands!" Some projects suffer more than others, however.
Recently, one of the OpenOffice.org developers opined about the demise of developer contributions, a KStars developer sent out a small S.O.S. on their blog on planetkde.org, we watch projects like Enlightenment or Perl flounder endlessly in forever betas that really damage their developer base, Pidgin was highlighted as suffering from development stall and there are many other projects I keep an eye on that have me .. well .. concerned.
It makes little sense to invest time and energy into a project only to see it hit a Good Point In Development(tm) and then erode as the original developers leave. It is a fact of life that churn will occur in a project. "Churn" is a term from corporate human resources that refers to turnover in job positions. There's always going to be churn in any organization, though: people's lives change in many ways that result in them no longer being with the organization. Free Software is no different, and is often worse than one would like to see in a corporate environment.
This is why building a community around your project is so important: it will either outgrow your current team's abilities to keep up with and/or your current team will no longer work on the project. When that happens, it's a little late to start thinking about project longevity and health. Build now for when things are less good later, and then things never will be less good. This is called "sustainability".
So ... your project requires new blood on a regular basis. Here's maybe how to get some. (New community members, that is.)
Principle 1: The Barrier To Entry Can Never Be Too Low
Every minute someone has to spend getting up to speed before hacking on your project represents lost contributors. Spending time eliminating barriers is therefore one of the best investments for the future you can make. There will always be some barrier to entry, after all a new code base is a new code base and takes some measure of time to get used to. How high the minimum barrier can be will vary from project to project, as well. The more technical and complex the application or library is, the higher the minimal barrier will be. Still, reach for that minimum barrier.
Here are some things to watch:
Before I worked on F/OSS full time I used to spend my evenings reading the source code of various projects. (These days I'm a bit too busy for such luxuries.) I read the source code to Apache, OpenSSH, PostgreSQL, numerous Gtk+ and Qt based applications, etc .. Not much different from reading a book to relax, really. The consistency, or lack thereof, of the code in some projects was striking. It was amazing how much quicker I was able to read through well structured code and get a feel for what was going on compared to some of the less well structured messes I opened up in my text editor.
Best of all: this is low hanging fruit. It's the kind of stuff that is easy to keep in shape with just a bit of discipline and the kind of stuff you can fix on a rainy Saturday when going out isn't such a fun prospect.
What makes up clarity in code structure?
- Code consistency: There is nothing more frustrating when reading a new code base than having N different coding styles. Be strict about style adherence; don't worry about this chasing people off because they can't "code they way they want to". For every one of those people you might lose (and they will be few), you'll gain more to replace them.
- One file, one concept (or class): By putting each class (or concept) into one file you will make it easier to find things, easier to edit things and quicker to build. A decent IDE can mitigate the finding issue, but editing is still done per-file in most IDEs. That means that if you have a file with 10 classes in it that are all related, chances are you'll be forcing the developer to jump around in that one file. You may have a perfect mapping of it in your head, but allowing people to have 3 files open to the exact place they are editing and switch between them is great. A good IDE will provide multiple views on the same file, but it still is a headache to peruse files with multiple classes. What an IDE can't do is limit compile times, and a file that is 5000 lines long will take longer to compile than a file with 1000 lines of the same general complexity. For header files this is multiplied by every file that includes that header. Time spent compiling is time spent doing nothing, and time spent doing nothing is discouraging for new users. For those with awesome IDEs, they aren't harmed by the one file, one concept approach, so there is no downside to doing this. In the F/OSS world, a lot of people don't use an IDE, however.
- File structure: Having one directory with 100 files in it sucks. The new comer will look at that and run screaming. Divide up your code into directories that are topical and make sense. This becomes a sort of self-explanatory mapping of your source tree and helps immensely. Don't get silly and have one directory per file, of course, but if you have a directory with more than a few concepts represented, think about breaking it out.
- Don't get clever: You may some super duper clever way of doing something, but if it comes at the cost of code readability think twice. If it doesn't really gain you all that much pass on the opportunity to be clever. Keep it simple and the people who come after you will love you for it.
- Document your cleverness: There are times you have no choice but to be clever. Some problems are just not easy to solve and to be solved well they require non-trivial code. When that happens, be sure to leave meaningful comments in the code so people can understand your cleverness.
- Readability: Remember that most people learn to read a natural human language before they learn to code. Human language is messy and imprecise, but it evolved around our strange, messy and imprecise brains. So when you write code, make it readable: don't use single letter variable names unless they are "well knowns" like the "i, j, k"s of loop counters. If you can't figure out what a variable represents by the name alone, your name is probably crap. If your name is crap, new comers will take longer to understand what you were doing. That would be bad.
There are many other ways to make code readable, such as using whitespace effectively. There are other places to read about that, though. Just keep in mind: the code should be readable.
- Document Your Design: (This is where I become a bit of a hypocrite ;) Document the design so people can get a high level view of what's going on right away. Reading the code should simply be filling in the details. If I can read a design overview, then look at the file structure on disk (or class hierarchy in an IDE) and then read the code I care about ... I'll be hacking on your codebase in no time.
- Keep The Edges Easy: Concentrate complexity into the inner core of the code base. Spin simplicity out to the "edges" of the code. The "edges" are the bits that people are most likely to start reading or working on. They are the bits that deliver the most visible functionality, for instance. Keep those parts of the code base extra, extra clean and happy. That way there is a "shallow end of the pool" for people start off in and they can slowly wade their way in deeper and deeper until they start crunching on the hard core concepts at the center of your project. Plugin systems and scriptable interfaces are awesome for creating "wading pools" for people to play in.
- Use The Tools: In the case of a Qt/KDE based app, that means use things like KConfigXt, Qt Designer, etc. By using standard tools people may already be familiar with from other projects, especially related projects, you lower the learning curve. Resist the urge to do it by hand or "do it better". Use the tools and you'll get more contributors who have transferable skills. This, by the way, is why one should choose a version control system and programming language based on a maxima of the combination of technical appropriateness and audience familiarity. Writing something in Haskell using Mercurial is basically saying, "I don't want you working on this." Unless, of course, your target developer audience is rife with Haskel hacking Mercurial lovers. Note that this has nothing to do with the Goodness(tm) of Haskell or Mercurial. Sometimes life really is about popularity contests.
Be Ready For Contributors
Making the project ready for contributors is like cooking a nice meal: people will want to eat something that smells good, looks tasty and is full of nice ingredients. However, if they show up for the meal but you don't have plates and cutlery and places for them to sit while they eat ... it's going to hurt your turn out. Imagine a restaurant with the best food in town but no tables, chairs, serving containers, eating utensils or people to take your order and serve you. It probably wouldn't go so well.
Don't be that restaurant:
- Have a host: You know that person who greets you at the door of the restaurant? You need one of those people. That means you also need to have a "front door". That might be IRC, it might a mailing list. Whatever it is, people need to be able to find it and you need someone(s) there to say, "Hi! Welcome to the project.." Nothing hurts more than showing up with a question or a patch and being met with silence. If I walk into a restaurant and nobody comes up to at least greet me within 5-10 minutes, I leave.
- Have appetizers: Appetizers are not supposed to be the main meal, though I have been known to, on occasion, order a bunch of them and make them into a meal. =) Regardless, appetizers are small, tasty bits of food to get your palette and stomach started with. Every software project should have appetizers ready, too: something easy and quick to do. Some projects call these "junior jobs". Whatever you call them, keep a few of them in mind at all times. At some point, someone will randomly ask you, "I'm new here, what could I do?" You must have a quick answer for them, and the answer must be precise and describe something reasonably simple (relative to the project's overall complexity) to tackle. The goal is to get people into the shallow end of the pool munching on appetizers as quickly as possible. This is how you hook people.
- Have a main course: Without a main course, your screwed. Everyone just fills up on appetizers and the core of your project rots. Make sure there is a path from appetizer to main course and that people are encouraged to follow that path. Not everyone will. Some will be like me with appetizers and just fill up on those. That's Ok, of course, but encourage those with bigger appetites to move on. They are the people who will one day replace you. That is a Good Thing(tm).
- Have a menu: Without plans, you're screwed. Nobody will know which way to go and so everybody will go nowhere in particular. Know where you are going and when you are going there. Communicate this on a regular and timely basis.
Remember There Are More Than Coders!
I've been talking mostly about coding so far, but remember that you also will need documenters, translators, community representatives for user relations and marketing, artists, etc. Treat these people just as well as you would a prize coder. Most importantly, let them do their job. If a translator says "I need more context for this string to be able to translate it" bloody well add that context! Don't ask why because it doesn't matter. If an artist says, "This is the image I want to use", use it.
Now, this requires trust. It also requires goals. Hey, that's just like with coders! Only we developers tend to forget that art also needs a direction and an end point. You can define what you want the end artistic impact to be for your project, but let the artist doing the art determine what it means to reach that goal. If they stray from the goal, then you apply leadership. But don't micromanage these contributors out of your project, and remember that when it comes to something like localization, documentation or art ... these people probably are better at it than you are. This is not something developers are good at admitting, so practice it in front of the mirror. ;)
Create A Culture That Inspires
No matter how boring the topic is, a friendly culture can make nearly any task enjoyable. For those of us who like to write and work on code (those are the people you want most, btw), what the code is matters less than having a fun place to work on it in. So make a fun working environment. This takes leadership.
Leadership is a learned skill like any other. If you don't feel that you are a good leader, that's not because you have an irreparable character flaw, it's just because you haven't practiced that skill enough. You can be a good leader, and that will mean being your kind of leader. People lead in different ways, so I'm not going to preach a given leadership style. I am going to make some clear suggestions that can be applied to almost any style of leadership and which are pretty critical in my experience for dealing with creative brainy types.
- Communicate: Have meetings on IRC, respond to emails on the mailing list, blog regularly, set goals for your project and then communicate them to others. Better yet, work on those goals with others and, through communication, build your goals together. Sometimes people will need to speak with you one-on-one, and that personal communication will often decide whether the person stays or drifts away. People bond through relationship building, and relationships are built by communicating. That means open, honest and truthful communication. Don't be a dick, but don't treat people like 2 year olds, either. Speak straight to them as equals and speak as you'd like to be spoken to. Also realize that you will fail at this from time to time. Work on it, always.
- Know your stuff is cool: Why are you working on that project? If it isn't because it interests you, you need to reassess how you make decisions on how to live your life. Seriously, no job and no amount of money is worth working on something you don't enjoy. There are enough opportunities out there for any hard working person to find something you enjoy doing. That said, if you enjoy doing what you are doing, then there is something inherently cool about what you are doing. You don't need Slashdot goofballs to tell you what's cool and what isn't: if it's enjoyable to you, it's cool to at least one person (you). You are not unique. Therefore there will be other people who feel it is cool, too. So without shame, fear or hesitance tell the world exactly what you're doing. Blog about it, and don't apologize for doing so. It may seem silly, but if you write about it someone, somewhere will find it interesting. Tell people what is happening, how it is happening and where you are going. Use screenshots to communicate that coolness, or better yet: screencasts! Expose your own enthusiasm for what you do, and others will respond with their own enthusiasm. Like finding a lover with interests similar to your own, this may not happen immediately. But it will happen eventually. Keep talking about it, and do so from your place of personal enthusiasm. Telling people how crappy and hard your project is won't help, so keep the venting (we all need to from time to time) to a minimum. Telling people about what you actually accomplished last week, however, will inspire even if it's "mundane". One of the KWin guys blogged mostly about bug fixes made over the last month or two and I actually found those blog postings inspiring: long lists of bugs crushed! And yes, your project is as sexy as Plasma or whatever else is considered the new hotness. Never doubt your own interests.
- If you are successful, you will end up being wrong: Successfully creating a community means you will end up with people around you who are better than you at some things. Let them be. It is a gift and a blessing to be surrounded by talented individuals. This does mean that you will at times likely feel a bit intimidated by them on certain topics and that they will at times prove you to be *gasp* wrong. If you are never proven wrong and you always have the best ideas then you are (a) fooling yourself, (b) a deity, (c) your team sucks or (d) your team is not really trying. This is why not being the best at everything all the time in your circle of friends and workmates is actually a sign of success. The people you surround yourself with will make your project better than you ever could alone.
- Allow mistakes, reward success: Mistakes will be made. Let people know when they've made a mistake. Don't berate them for it (more than they deserve, anyways ;) and always show them how it could be done better. When you make a mistake, admit it. This builds trust both ways. Nobody cares if someone makes a mistake, they only care when someone refuses to admit it. Conversely, when someone succeeds, give them the props they deserve. Say thank-you whenever you can and tell someone when you think what they did was cool. If it was a hard, long road (particularly if you made it long and hard on them by demanding excellence) be triple sure to let them know that you respect what they did and appreciate the results. By acknowledging success, you will also have more latitude to correct mistakes without hard feelings.
- Don't let people tell you you are wrong if you aren't: This is going to sound a bit contradictory, but you need to also know when you are right. People in your team, and particularly people outside your team (the transparency that comes with F/OSS also comes with numerous loud mouths who actually don't know squat), will sometimes challenge you on a point. If you know you are right, stick to it. Don't just follow the wind whichever way it blows. This is perhaps one of the hardest skills to pin down with leadership: knowing when you are right, and knowing when you might not be right. Having a confidant you can bounce ideas off of for a reality check is helpful.
- Don't play politics inside your project: Don't let politics enter the picture. Demand that everyone comes in on a level playing field. Require people to work together with the same expectations and commitments. If someone can't figure that out, let them know they can leave. If they refuse to figure it out, tell them to leave. If someone tries to inject politics into your project, come down like a ton of bricks on them. Most importantly, do not ever be the person injecting politics into your own project. Set standards, adhere to them, expect others to do so as well .. but leave the politicking out of it. If a company joins your project, require them to do the same. No amount of money today will save your project if they screw up the culture. If you care only about money, hey, go for it and sacrifice your baby. If you care about your project, prioritize it above money, popularity or other vanities. You will attract more money, popularity and vanities that last and do not kill the project in the long term this way.
- The project relies on you: Take personal responsibility for the project. When problems arise, commit to a solution. When hard work needs to be done, show how it's done by doing it.
- Make yourself irrelevant: Having achieved the above, this is the most important thing you can possibly do. You will not live forever, your interest in your project may not live forever, your life may not forever allow you to work on your project of passion. Therefore, for the sake of your project, you must be replaceable. Anything you know, someone else must also know. New people coming into the project must be taught these things, too. Now, sometimes you'll have someone who does have a special spark about them ... a certain crazy creativity or vision or whatever. The shocking truth is that even after those people move on, any project can continue on successfully as long as you do not come to rely exclusively on that one person. Apple never learned that, and they had to bring back the Man That Makes It Happen as CEO to get the company back on track. That is a consummate failure on Apple's, and by extension Steve Jobs', behalf. Never rely on one person and never, ever think you are such hot shit yourself that you ought to be irreplaceable. You aren't. I'm not. Nobody is.
Build Clocks Rather Than Just Tell Time
In the book "Built to Last" they talk a lot about "clock building", which is the practice of building methods of doing things and passing that knowledge on, versus "telling time" which is simply observing what the right solution is for other people. Steve Jobs can certainly tell the time on the Clock Of Technology Cool, but has he built a clock for others to use when he's gone? He didn't the last time he was with the company and it nearly killed Apple, which is why while I have great admiration for the man, I also think he's something of a moron who suffers at the hand of his own ego. If he was actually doing his job, nobody would care about his health nearly as much as they currently do because it wouldn't matter nearly so much if he were there or not. That sounds harsh, but it's reality.
So it is that I ask myself constantly if I am building clocks for the KDE community to use or if I'm just "telling time". I have no plans of leaving in the foreseeable future, but the future is just so unforeseeable that I try not to fool myself that I'll always be here. One day I will not be here. If in spite of my absence KDE becomes greater than it was when I was involved, then I will have personally succeeded. I will have done the most I can do for the project once there is nothing the relies on me and me alone. Perhaps I already have nothing left unique to offer. In which case, I can continue to do what I do until such time as I'm done doing it.
This brings us the principle of being able to let go. Delegate, pass responsibilities around the project, let other people hold the leader stick at times. Teach by doing, and remember the people who show they are learning by what they are doing. Take care of those people, because they will be the people to step into your shoes when needed and who will grow your project bigger while you are still around.
Well, this post has become far too long as it is, though it is also far too short to cover the topic at hand in any sort of useful manner. I hope it doesn't come across as preachy, it's more a "brain dump" of things I've learned. I wish it also contained the things I haven't learned yet, too, but I'll have to wait for a future me to write those blogs. ;) Perhaps, though, you will find some bits of usefulness in this post as it is. My hope is that you do, and that it becomes a part of the clock you use in your own project.