Many new developers wonder: Where do I start making a real product that I can live off? So I thought I’d share my thoughts on this.
How to start?
The first thing you need is an idea.
The best way is to take a problem you have and try to solve it with a program. For example, in my theatre group, we used to use a CD player backstage to play the different songs and sounds we needed for the play. We just burned them all on a CD, and someone sat in the dark with a tiny flashlight and a scrap of paper listing the cues and associated track numbers. So I wrote an application for this.
It was a great success. Not because nobody ever had the idea, or because it had any high-tech features. It was just a list of sound files that got played back, with keyboard shortcuts. However, I knew where it would be used: Backstage, in darkness, with an open door to the stage. You don’t have light back there because then the audience could see all the actors of the characters that have supposedly been killed sitting there. So, you don’t do complex UI, you make sure everything is triggered by keys that can be found in a tactile fashion. You make sure all the graphics are dark, and the menu bar doesn’t brightly light up everything. You remind people at the beginning to turn down the backlight, and you tape off the Apple logo on the back of the screen.
I knew this because all the situations and problems were deeply ingrained in me, because I was familiar with the problem domain.
The second-best way is to solve a problem you see somewhere else. You may not have it yourself, but you’re close enough to know the workflow, and see the spots that can be improved. As an example, for quite a while, the US used to perform online banking by having actual humans go through the database of online money transfers, copying the information onto paper cheques, and then air-mailing whole bags of them off to whatever bank the transfers were for. That’s inefficient! Certainly that can be fixed by throwing some technology at it? Surely I can create a system that interfaces with the bank computer, then converts and transfers them to other banks?
Maybe. But maybe, this was due to US laws requiring a paper trail for money transfers. There are always surprises hidden in workflows. Not just outdated laws, but also safety regulations. As an outsider, I do not know of these. So, since I’m not inside the problem domain, I have to make sure I have an inside person who can give me the reasons for everything. There’s nothing worse than spending a year designing a perfect product whose base assumptions make it unusable in practice. Or worse, illegal.
The most comfortable way is if someone hires you to create a program for them: They know their problem domain, they have ideas for solutions, the program practically has already been designed, right? With an existing design, it is easy to forget that I am the engineer, I am the systems architect. The person that hired me probably hired me because I can do things that person hasn’t been trained to do (then again, they understand a problem domain I have no clue about, so it’s not as if they’re stupid). They have probably tried to design a program the way they think would be easiest to do. But they’re not programmers. What may look easy to them might actually be incredibly complicated, or might be aiming too low.
It is my job to “translate” their requests into a program, to find out what they really need. To achieve this, it helps to have close contact to potential users and find out how they work every day. Again, like we did in the previous approach.
The most difficult way to start with a program is to do something you always wanted to do. Take the theatre as an example again: Some roles in theatre are challenging to play, but they’re not particularly interesting to watch. Others are pretty boring and easy to play, but are most important to the audience, be it because they drive the plot, or provide some much-needed comic relief at a central point of the play, heightening the impact of the final dramatic scene. Similarly, coloraturas are amazingly fun to sing, you really get to exercise your vocal chords and breathing apparatus, but all that up and down, while technically impressive, doesn’t stay in memory as much as a simple, catchy melody.
If one of the three approaches above can be combined with this fourth option, that is a gift from heaven. But otherwise, you owe it to yourself to investigate whether there is any need for whatever idea you always wanted to realize. But again, translate from what people tell you. Henry Ford is famously claimed to have said
If I’d asked people what they wanted, they would have asked for faster horses
Similarly, the first GUIs were considered a fancy waste of CPU cycles. The iPhone was seen as useless, as existing phones already made perfectly fine calls.
The people asked back then didn’t know how not having to memorize cryptic commands would free brain power for the tasks that really count, how having a more physical display would improve comprehension of the onscreen data. How direct touch manipulation, drag and drop would speed up learning the user interface by leveraging existing real-world knowledge. What a great relief it is to know that no matter what corner you turn, you’ll always have a map in your pocket that helps you find your way back home. How much more convenient it is to just save the bulk of a Walkman in addition to a cell phone…
Great! Now I have an idea! I can start now!
Ideas are worth nothing
We all have probably seen a message like the following on a mailing list:
Q; this is quite draining on the resources as well as jumpy. What can I do to get this resize function called a lot, but without killing the system? Maybe a run loop callback?
A: What are you actually trying to do? So far, this sounds like you’re going about things all wrong, and that’s why you’re getting bad performance.
Q: Sorry, but I am trying to keep my project pretty need-to-know, to deter the real programmers from stealing my idea!
Wait. So we’re all dishonest thieves, yet he’s going to take our advice anyway? Without intending to, this poster insulted everyone on the mailing list. That reminds me of J. Michael Straczynski, writer of nearly every episode of Babylon 5: He once wrote that, whenever he told people at parties that he was a writer, they told him “I’m gonna write a book when I retire”. He found that insulting. Now those people didn’t mean anything by that, but a writer spends years of his life perfecting his skills. Not just spelling and grammar, but learning the subtleties of words, composition, how to structure a story. They have to do research on each subject they write, … why does everybody think they can do the same work once they retire, without training?
That’s why I don’t care about someone stealing ideas. Everyone has hundreds of ideas every day. They are worthless, unless someone actually realizes them. Execution is everything. And just because I have the idea to create something like Word, doesn’t mean I can actually pull off creating one huge application that combines all these ideas into a coherent whole.
Also, while I’m always careful not to underestimate the power of a good idea, I try to keep in mind that I am very likely not the first one to have an idea. When I started out at my current job, I constantly came up with great ideas, and every time was eventually pointed at the corresponding feature request in the issue tracker, which also had a list of stumbling blocks I hadn’t thought of that prevented this from being the simple, easy fix that I originally thought it would be. Be it issues of scalability to 3000 satellite channels, patents, unavailability of worldwide data providers, or whatever else.
Getting started and finishing
So, once I have an idea, the next biggest hurdle is not running out of money before I can start selling copies and make money back. So of course I need to consider the business case, make sure I work out a price that doesn’t just cover costs, but rather also lets me live decently, and sends the right marketing message. But what else can I do to speed up my release?
An answer Matt Mullenweg gave to that question was: “if you’re not embarrassed when you ship your first version you waited too long”. And that’s a great way to start a product. I design my 1.0. Then go through my design and take out everything that isn’t absolutely necessary. What is necessary? To know that, I have to know my unique sales point: What does my application do that none of its competitors do? What makes my app so special, so different that nothing else on the market will suffice? I must find that one aspect, and make sure it’s in the first release. And build everything around it so this central, main use case can be achieved. Cut away everything else. That is my real 1.0.
I can release that, and finance all the other features that bring me parity with the competition with the income from that version. In the beginning, it may just be an add-on to the competition. Then I add the other features back in, bit by bit. And I must remember to not be shy to charge for new features. People saw my 1.0 when they bought it. They knew it only did these few things, and they bought it anyway. It is worth the price to them already. Anything else I add is a gift, a marketing expense. So, I take the features that only work in some countries, but not in all, or bug fixes, things that I can’t put on an ad for a version 2.0, and add those gradually. But I try to stay aware of what people are willing to pay for, what has value to my users, and try not to be afraid to charge for that work.
Think of your users
One major advantage of working out my unique sales point is that it will give me clarity of focus. Whenever I am tempted to add this handy feature and this wish of one customer, possibly saddling myself with additional maintenance work in each release, and adding complexity to my user interface so it can support all those features, I can take a step back and ask myself: Does this solve a problem for the typical user of that 1.0 version I released initially? And if it doesn’t solve an actual problem that my users have, why the hell am I adding it?
Everything needs to be subjected to the user’s needs (which may be, as I implied earlier, different from the wishes they voice – it is my job to find out when there is a mismatch). But that doesn’t just apply to the program design of features and code. It also applies to the entire workflow, up to and including the hardware the user is on, and even the user’s surroundings, and their life situation at this point in time.
To take an example I mentioned before, users are often reluctant to update their software, for fear that an update may break something they rely on. Some developers try to overcome this conservative attitude by forcing their users to upgrade. But now imagine a user writing their diploma thesis: They need to get it finished by a deadline, or they won’t get their degree. They will set up their system with reliable software at the beginning, maybe do a few tests to ensure the things they need work, and then they want it frozen. It may not be a matter of life or death, but it may mean the difference between cheeseburger or caviar for the rest of their lives.
Alternately, they may be on a North Pole expedition, only to find out one week in that my application requests an online activation every week and stops working if that can’t happen.
While I may not share my users’ priorities, may not even know about them, I need to account for them in my design. I need to honor their data, make my file format robust enough that I won’t corrupt the meticulously-collected samples my user collected. I must honor their schedule, and let them postpone updates, let them quit right now before the EMP hits and fries their notebook computer, and honor their priorities. And as much as it hurts me, playing with my program is usually just a necessary evil to users. What they really want to do is write that novel, file those taxes before the deadline, or switch out of my application to take that call from their doctor with those test results.
And I also need to keep in mind that I may go out of business or even die, or just lose interest, and have a contingency plan for that. I can’t just abandon my users after I’ve taken their money. I need to make sure they can keep running my software even if my activation server is down, or that someone who bought my software ten years ago can still get at the data on that unchanged antique Mac they bought it for, even if I long ago stopped developing and maintaining classic MacOS 9 software.
Now that my product has an idea and functions reliably even in the face of adversity, what else do I need to account for so I can create a real finished product and not just an amateurish project? For one, there are a number of tasks that need to be performed. A visible one is graphic design, but I also need to provide support to my users (this tends to take up increasingly more time the more I sell), document the program both for myself (or anyone following in my footsteps) as well as for my users. I already know the program, and I built it, so it works the way I think is most obvious. But everyone’s brain is wired a little differently, and everyone brings different knowledge to the table, so I will have to document things for someone.
At some point I will also sell internationally and need to localize my program. A thing I learned early on was to use native speakers of a language and have them translate into their mother tongue. I’m a German with certifiedly excellent English skills, still I would not recommend someone hire me to translate a German user interface into English. They should pick an English speaker who knows German instead, because it’s easier to understand the gist and subtle nuances of a sentence in a foreign language than it is to actually build an equivalent sentence, even in my own language. Professional translators are worth their money.
Also, localization, documentation and many other tasks need to be performed again for every release I make. So I make a checklist of tasks to be verified, even on dot-releases:
- test migration of preferences, documents, databases etc. from previous versions to the current one. Users don’t like to have to re-apply their preferences because your program “forgot” them because you fixed a typo in the defaults key. They also sometimes launch a copy of an older version and edit files created by a newer version with them, then re-open them in the newer version later. What will happen? Will the data be inconsistent because the old version didn’t update a new data structure?
- test the first run experience. Adding a single alert at startup did not seem like much, until I realized that I was now up to three alerts in a row for new users. Also, did I correctly set default positions for all windows? Does the user get bombarded with empty windows and no clue what they do, or are there hints what the app does? Does the user quickly get to a point where they can use the application?
- What is the cost of this update? What happens to people who bought the old version a day ago, or who just bought an old copy of version 1.0 still sitting in some store on the shelf?
- Does everything still work?
- Do certain features require regular maintenance?
- What happens to people who have another version of my application installed, be it a demo version, the app store version, a web site version … ?
The dastardly feature
And that leads us to the cost of each feature. If you add a crash reporter, you may need to update the list of Mac machine names in its framework. If your application needs a country selector to pre-configure some settings, you may need to update the list of countries whenever politics cause a change in that (and believe me, once you have to watch out for it, you’ll realize it happens more often than you think). If your application talks to several web APIs, you will have to watch each of these for server-side changes that are not under your control.
But these are obvious recurring tasks. What about UI complexity? Every time you add a preference to let the user modify the behaviour of your application because you can’t do it automatically, there is one more item in your Preferences window that the user has to evaluate and discard when searching for that one option. And at a certain point, people will just look at a window full of 20 checkboxes, throw up their hands and ignore your preferences. They might as well not be there.
Also, every new feature can have bugs in need of fixing, can have unexpected conflicts with the behaviour of other features, can break on new hardware released after you release your program. If you don’t notice it right away, users who made their purchasing decision on the fact that your application had this particular feature will not appreciate if you remove it again. You can always add a feature, but you can’t take one away.
Also, adding a feature that only some of your users can use is annoying and perilous. You can run afoul of false advertising laws if a translator isn’t told to remove mention of an unavailable feature. If you add other features that are dependent on these features, you suddenly have a whole slew of UI elements that are useless to a subsection of your users. And really, can it be a major feature for a release if it’s not available to everyone?
And finally: Users don’t think about features like developers do. To sell a feature to a user, you have to figure out a way to make it relevant to them. Provide it as part of a solution to a problem they have, not as a technical data point. Apple did this very well with their FaceTime commercial, showing that it’s not a gratuitous feature for people who’ve been using the telephone before, but rather allows deaf people to use a telephone.
Having a product and selling it
So, now I have the perfect product, it is well-written, based on a decent idea and deep domain knowledge, has a focus sharp like a razor – a unique sales point. It is maintainable and I’ve worked out all the ancillary details I need to support my users, documented the use of the application and prepared an exit strategy. I no longer have a project, I have a real, sellable product. How do I get it out into peoples’ hands?
I need a payment processor. No, actually, I need at least two, in case an exceptionally good sales month causes errant fraud protection to trigger, like it happened to the MacGraPhoto bundle, for example. It doesn’t matter whether it’s two online payment processors, or whether you know that if online sales break, your stuff can still be bought on Amazon, or in brick-and-mortar stores, or whatever.
Also, I need to make it easy for people to buy my software. So I’ll add a simple, non-boolean asymmetric key based locking scheme, but I won’t go overboard with activation or other things that might prevent users from using my software. It is hard to be noticed at all, and I don’t want to risk losing even a single eyeball at this point in time.
But how do I hack the press? I’ll need a press kit, I can do special sales – but not too often. If I as a customer buy a monthly 5-part game, and before the third part is released, I get a newsletter from them telling me I can now get it half-price … Yes, I got it two months early, but it still feels weird. I would wait a month after the last part’s release to discount it, at least. The goal of a special is to get new customers who think they’re getting a deal, not piss off existing customers making them think they paid too much. And it’s not as if I need a good reason for a special. As long as they get a decent offer, users don’t mind if my reason for giving the discount is arbitrary. Also, bundles with other developers’ software that complement mine can be helpful (the support queue can be a good source for information what these programs are). I can join forces with someone else, it’s a special occasion and a deal that press may want to write about.
But I have to mind my surroundings: If I offer a deal on my web site, but not to other dealers, I am essentially competing with my partners. So unless it’s a small thing like a few free coupons for press or users who take part in a survey, I’d better make sure my partners get the deals as well.
And finally, you can join forums (or mailing lists) about topics related to your products. They’re talking about stuff you’re interested in, so it shouldn’t be too hard to take part in the discussion there, maybe help a few beginners with your deep domain knowledge. Don’t just go there and flood them with advertising. Take part as who you are: A person interested in the topic, who happens to also be a developer of a useful piece of software. Be honest. It is all right to mention your product when the conversation heads in that direction, but ensure that everyone in the conversation is aware that this is your program you’re recommending here, every time. Don’t be the baby buggy salesman who crashes a wedding, be the friend who makes cool tools.