Archive for the 'software engineering' Category

What is the point of explicit typing again?

Monday, July 7th, 2008

I’m noticing that C# 3.0 has implicit type declarations which is actually a very interesting step to make this language look less like a cheap Java clone. It is a very neat feature that lets you declare your variables like this:

var s = "Hello";
var d = 1.0;
var numbers = new int[] {1, 2, 3};
var orders = new Dictionary<int,Order>();

By show of hands, lets see who doesn’t approve of this feature? Who here thinks that we should explicitly declare the type on the right side of an assignment statement? Yeah, you guys are all wrong. Please tell me, why is it necessary to write:

String foo = "bar";

Could foo possibly be anything else than a String in this line? String can’t be subclassed, and no other data type can be instantiated this way. So the word String doesn’t tell me anything that I wouldn’t know by looking at the line anyway. It also doesn’t tell anything new to the compiler which can infer the type quite well. Forcing people to type String every single time they declare one is just cosmetic… no, pedantic anal retentiveness. Hell, even Scala folks use implicit type declarations - and these are the people who think that static typing in Java is not static and not type safe enough.

The explicit declarations are quickly becoming a thing of the past. The trend is moving towards less verbose, compact and more elegant syntax - in both dynamic and static typing camps. C# seems to be adopting to this new reality.

When I first saw C#, I described it to a colleague as “a Java Clone written by C++ people, or a C++ clone written by Java people”. It seemed to have been created combine the best of both worlds and draw both Java and C++ developers in. But that was a long time ago. Java is no longer the cool and hip language. It is “your dad’s language” - outdated, bloated dinosaur. It’s not going to go away but it is no longer cool. I think Microsoft made a smart move here, distancing itself from it. I mean, implicit data types, lambda statements and all that jazz.. They might actually have a chance to remain relevant as Java is slowly transitioning into it’s new life as a senior citizen of programming languages. Actually, scratch that - relevant is a wrong word here. Change it to popular, well liked or buzz worthy.

Both C# and Java will remain relevant for years to come, just like C is still relevant now. No one thinks C is revolutionary, hip, cool and awesome anymore. But no one seems to be eager to throw it away and forget about it either. Universities still teach it, and companies still hire C programmers. The same fate awaits Java and C#. They will be around for a long, long time.

Installation Wizards are not allways User Friendly

Tuesday, February 12th, 2008

Installation wizards have their place. For example, when you are installing and configuring an operating system a wizard is your best friend. The design of the wizard is paramount as it is often the very first thing your user sees. First impressions are crucial, and if your install procedure sucks, then it puts your whole application in a bad light. That said, sometimes wizards - no matter how pretty, and helpful are just unnecessary overhead.

For example, let’s compare the way a Windows user and an Ubuntu user perform a typical installation. The windows user will start by downloading the package form the internet or popping in the CD into the drive. From there he will have to typically go through following steps:

  1. Look at some generic “This installer will guide you through the process…” screen
  2. Agree to an EULA
  3. Pick program components to be installed
  4. Confirm he wants to install the application in C:\Program Files\The Application
  5. Decide if he wants shortcuts to be added to Start Menu and Quick Launch
  6. Review the summary of chosen settings
  7. Stare at the progress bar
  8. Confirm that he wants to run the application and/or read the README file
  9. Start using the application

Note that I omitted the common steps of entering the product key and online activation to keep things fair. Let’s assume the windows user was installing a multi-platform open source application - something like Firefox or something similarly popular and ubiquitous. To install the same application a typical Ubuntu user would just open Synaptic and find it on the package list (equivalent of finding and downloading the package from the web) and then:

  1. Click on the Install button
  2. Stare at the progress bar/scrolling text
  3. Run and start using the application

What is the difference here? I mean other than one system uses a repository and other downloadable packages - that bit is actually inessential here. The major difference is that in Ubuntu the application is silently installed in the background without asking the user any stupid questions. And believe it or not, this is much more user friendly way of handling installation than a pretty looking wizard.

The average user wants the default components to be installed in the default directory with the default set of options and shortcuts. Think back on recent windows applications which you have installed - how often do you change the default installer options to something else? I typically just leave the default settings unless the app ships with annoying add-ons like toolbars or other adware and let’s you opt out of them by un-checking a box or two in the installer. Other than that, I typically just click next.

Tons of applications these days provide a silent install option that can be invoked by passing a special command line parameter to the installer binary (typically something like /S, /Q or –silent). This performs the whole installation in the background choosing all the default settings in a way simillar to that used by apt and Synaptic on Ubuntu. But the default installer makes us jump through multiple hoops instead. Why is that? Why can’t the silent install be the default option and the detailed wizard be invoked by some command line switch?

Usually people who would want to take advantage of the customization options in the installer are power users who could easily figure out how to trigger this hidden mode. The rest of us would simply hit a button, wait few seconds and then simply enjoy the application.

It seems that folks in Linux and Apple camps always knew this. Ubuntu for example only uses wizards for configuring complex pieces of software - like the OS itself. In the windows world however, the installation wizard is the king for apps big and small. It is sometimes quite ridiculous - for example, it is not uncommon to see a 2-3 MB application composed of a single executable requiring 6 or 7 step installation process. I know because I created such installers myself. Most of us are so used to them we hardly even notice them, but if you sit a complete novice in front of the computer and tell him/her to install some software every extra step they have to take is another occasion for doubt and panic.

And no - I’m not making this up. I’ve been actually asked by coworkers to stand there and watch them install this or that application. They would click the installer, hit the first question and look back at me. I would nod and they would proceed to the next one. Most of them would then apologize for taking my time and explain they were simply afraid they would mess something up if they answered one of the questions wrong. They just didn’t realize all they had to do was to click next repeatedly.

Adobe already figured this out. When you go to install their PDF Reader app these days all you need to do is to clikc on the Install button on their page. Then an ActiveX or XUL window pops up and displays a progress bar. There are no questions asked, no configuration options to be chosen. The reader is just installed and then the progress bar disappears letting the user know his application is ready for use. It’s clear to me that these guys got it. They did the usability research and they noticed that most people just click next all the time. And if overwhelming majority picks the default settings, then why even ask? Just install the app with most common configuration and provide mechanism for power users to circumvent it.

DRM Software Industry Must be a Cash Cow

Friday, January 18th, 2008

I realized something today - we are in the wrong industry guys! We should all be writing DRM software! I mean, at least in theory. I would never do it because I find the idea of DRM morally reprehensible and intrinsically flawed. In fact, I think most self respecting programmers think the same way and stay away from that sector of the market. But it must be a fucking cash cow!

Ok, you don’t see it yet. Let me explain. Imagine doing highly abstract cryptography for people who are so technologically inept that they can’t even spell the word cryptography. Imagine working on products that no one actually expects to work. Let’s face it, even the big fat movie studio executive that just paid few mill to some shifty software company is expecting their DRM to actually prevent the final product from hitting usenet and torrent boards. And best yet - you don’t even have to do much quality assurance because your client doesn’t really give a fuck how this software will affect the machines of their clients. Even if you fuck up, and write something that actually can damage end-users optical drives (hi there Starforce!) you still get paid. It’s your client, not you will need to deal with the customer support, the bad PR, refunds and etc.. Hell, maybe they will even hire you back to write another DRM scheme for them.

What was the last big DRM thing? BioShock? Yes, it’s old news but I don’t recall anything more recent - I haven’t been paying much attention. That one however generated so much buzz it actually registered on my radar (few things do these days). Personally I haven’t used it, but I hear that the game has not only a built in rootkit, but also multi-step online activation process, and that it calls home all the time. In fact I hear that most people who bought it just downloaded a crack to get rid of that garbage.

If you were to slow, I will repeat it for you slowly:

In fact I hear that most people who bought it just downloaded a crack to get rid of that garbage.

Yes, DRM is such a pain that legit customers are cracking their own legally purchased copies (invariably breaking the DMCA) because the copy protection is such a pain. Can you see the irony here? The copy protection which was supposed to maintain the integrity of the package and prevent this sort of thing from happening is being easily removed by a widely available patch that appeared a week after the release of the game.

I guess we can’t forget about ACS and they lovely t-shirt I bought that has their super-sekrit encryption key printed on it. mrgreen DRM is really a joke - and not particularly funny one at that.

Remember Bob, Alice and Eve from your cryptography lessons? Bob and Alice always try to communicate, while Eve is listening. Most cryptographic problems involve securely passing information between Bob and Alice while protecting it from Eve. DRM poses a peculiar problem because it does not follow this model. When you work with DRM you want to send messages between Bob and Alice while protecting them from… Alice. After all, Alice can’t be trusted as she might share them with Eve. You can probably see why serious security researchers don’t actually bother working on one of these problems - it’s stupid, and unsolvable. If Alice can read and comprehend the message, she can pass it to Eve. Period. Entertainment industry calls this “The Analog Hole” while the rest of us refers to it as “The Reality”. The problem with this supposed hole is that it can’t be closed with software. That’s just how it works - you have to use hardware. Can you see where this is going?

Nah, you don’t see it. I didn’t see it at first either so let me tell you. Who do you blame when your DRM gets cracked? Anyone? Anyone? The hardware vendor of course. You thought I’m gonna say “the previous developer” but no - that’s who you blame at a real software shop. At a DRM shop you blame the hardware vendor for dropping the ball, and not making their shit impeccable, and impervious to everything including a voltmeter and a soldering iron attack. At some point the data must be analog, unless they figure out a way to directly stream content into a wetware DRM chip implanted into your head. So really, this is all a matter of where do you patch into the electronic system to recover the data.

Hardware folks know it, but they must play ball or they will be locked out of the content. What good is a next-gen DVD player if it can’t play any of the next-gen DVD’s? So you end up with a system that has two broken components: software that doesn’t work, and hardware that is intentionally slow, complex and expensive which doesn’t work either.

Since plugging the analog hole is an engineering task on par with building perpetum mobile, hardware people will always struggle with implementation. If you are behind the schedule, give the hardware folks a half assed incomplete spec to work from and then change it 3 or 4 times. Oh, and remember to revert to a previous spec at least once in that process to get them totally confused. Then you can blame them on delays. If the client asks why the spec is so shitty, or why you change it so often tell them details leaked out on the internet and you have to do this to keep implementation details secret. Sigh… I wish we all could play this game, but out in the real world developers are actually expected to deliver software which works, is on schedule and doesn’t mess up your system. Only DRM makers can churn out some piece of garbage that doesn’t really do anything beyond making your machine unstable, and still get paid.

But let’s get back to Bob and Alice again. There is a second part to this equation that few people talk about. Bob actually doesn’t send the message himself. He dictates the message to Eve who then encrypts it and hand delivers it to Alice. Confused? Think about it - I’m talking about the human element. How do you get a zero day scene release?

Ok, there is more than one way - I’ll grant you that. But more often than not you get a zero-day by having a supplier close to the source. Usually there are thousands of people involved a movie production, post production, publishing and distribution. They all have internet access and most of them probably have been known to download stuff without paying for it. Any one who touches the source can leak it and tracing such a leak is extremely difficult because copying digital data usually leaves no evidence. The only way you can work is backwards - if you nab the uploader you may or may not be able to work your way back to the supplier.

This is what I mean by Eve encrypting and delivering the message to Alice. Most movies get leaked onto the interwebs long before they get the DRM treatment. So you are really building software to protect something that is already available out there.

Let’s summarize:

  1. you build cryptography software for a client that doesn’t understand cryptography
  2. you are working on a problem that is known to be unsolvable
  3. your client does not expect your software to actually work
  4. stability of end-user’s machine is not an issue
  5. compatibility with hardware/software on end-users’s machine is not an issue
  6. ethics are not an issue - your client doesn’t care if you use a rootkit or a trojan
  7. support is mostly not an issue - at most you might just need to provide an un-installer for the rootkit
  8. if all else fails you can blame the hardware vendor for delays

All you are really expected to do is to cripple user experience to the point where they will just go and download illegal copy. So you make a shitty piece of software cobbled together any which way, make it do some hard-core math to facilitate your half-assed encryption, then charge the gullible but unreasonably wealthy client an arm and a leg and move on to the next victim. Pure profit.

Naturally, I bet the DRM industry does have some honest, hard working people who take pride in their work. They will probably come here and yell at me for talking shit. I’m not knocking you guys - I admit, cryptography is a fascinating subject. I’m sure that the software you build uses very cool ideas, and is actually very effective. I’m really happy that you get to work on those hard and challenging issues - I really am. In fact, I will think about all the hard work you did next time I’m watching (or playing) a pirate copy of the movie (or a game) that your software was supposed to protect. mrgreen

Designing a Tetris Clone: Part 1

Saturday, October 20th, 2007

Someone told me that Tetris was a “hello world” of game programming. I whole heartedly disagree. Tetris may not be an awfully complex game, but it sure as hell is not trivial. The whole concept of a “hello world” is to show the simplest trivial example of functional code that actually does something. But if you think about it, Tetris is not all that simple. So I decided to actually implement the game to show that if you really sit down and try to put it together it is slightly more than just a hello world.

Now, I could just sit down and hack a working prototype relatively quickly but let’s do this the right way. Lets design it, rather than hack it.

Good place to start is to put the spec of the game down on paper. So, let’s just list everything we know about the game:

  1. the playing field is a grid of the size 10×20, 10×24 or 10×16
  2. all tetris pieces are composed out of exactly 4 blocks
  3. the pieces come in 7 shapes: J, L, T, Z, S, I and O
  4. each piece has an orientation and color
  5. pieces start at the top in the middle of the grid, and slowly fall downwards
  6. the speed at which the pieces fall increases with each level
  7. player can move the pieces left and right or rotate them (change their orientation)
  8. when a piece touches the bottom of the grid or top of another piece it becomes locked down
  9. there is a slight delay before the lock-down that allows the player to slide the piece into place
  10. if a full row on the grid is filled it will clear and add to the players score
  11. the original Nintendo formula for computing score is m(n + 1) where n is level, and m takes the value of 40, 100, 300, 1200 depending on the number of lines that were cleared simultaneously (40 is one line, 1200 is 4 lines)
  12. when a line clears, all the blocks above move down
  13. requirements for advancing to the next level depends on a game, but most start with around 40 lines, and the number gets progressively smaller to become 1 level per line around level 20-30
  14. some games implement gravity that makes blocks that do not rest on other blocs slide down causing chain reactions
  15. most games display the next piece next to the grid
  16. most games allow player to instantly drop the block down either via hard drop or soft drop
  17. some games implement a wall kick that allows for rotating pieces backed up against the wall

The 17 points above roughly describe the game and can be used as an initial specification. Remember, we are building a game that already exists in many different version, so we want to create something that is instantly recognizable as Tetris, but we do not necessarily need to include all the fancy features that were added to it over the years.

As they taught you in your software engineering class, pay attention to the nouns. They are your potential classes. Right now I see several really good candidates: Block, Grid and Piece. In fact, we could possibly define classes for each specific piece like LShapedPiece, JShapedPiece and etc… They would all be subclasses of Piece and would define the shape, color and orientation. Each of these classes would also implement rules on how the piece could be rotated. This way Grid class would only need to interact with a Piece class.

I actually can see a nice factory pattern forming here. Grid will call a Piece factory which will randomly generate one of the subclasses, and then return it as Piece. This may or may not be practical, but it seems like a good idea at the moment.

Also, the spec is just a rough sketch of the game. If we want to implement it, we must answer several questions and make some important design choices. For example, how big do we want the grid? Do we want to allow the player to rotate pieces clockwise and counter-clockwise or just in one direction (the later choice means you only need a single rotate button rather than two). Do we want to have hard drops or soft drops? Do we implement wall kicks or leave them out? We also need to pick several variables such as lock delay, the speed at which the pieces drop. We must decide if we want pieces to crawl (move one pixel at a time with specific velocity) or skip (move full block length down every n seconds).

We have a pretty good scoring formula, but just a very rough guideline on level advancement. That will need to change. Oh, and there is also that pesky matter of collision detection - somehow we will need to decide how do we detect that piece has hit a wall, or a locking element like floor or another piece.

We also need to pick platform and a language at some point, but that is not all that important at this point. Tetris can be written in any language, and while some might be better suited for this task than others, it ultimately won’t matter as long as we can use some graphic display libs and don’t have to re-implement a whole 2d display framework.

I’m going to address all these questions Part 2, and start drawing up some UML. I also want to look at actual game piece design - like sprites, and internal representations of a piece and a grid. I already have certain design in my head, but any suggestions are welcome. I also have a very specific language and framework that I’d like to use, but I’m not really designing with that language in mind so I’m not going to tell you yet. Good design should work in any OO language - and once we pick one, we can do necessary adjustments if needed.

Still, I’d like to see what language you guy would use for this. Let me know in the comments. If you suggest a good one, I might even change my mind. )

The GTFO UI Design Philosophy

Thursday, October 4th, 2007

I present to you what I call the GTFO UI Design Philosophy. There are many books written on designing good user interfaces, appropriate methodologies, approaches and techniques. People talk about different UI paradigms, styles and etc. To me UI design roughly boils down to this: “get the fuck out of my way and let me do whatever I’m doing”. That’s it! Everything else just adds polished feel to your design. Knowing when to GTFO and let the user work in peace however is what separates a good UI from an annoying one.

When designing user interface please keep these 10 things in mind:

  1. Making Me Wait is Annoying - every second you make the user wait for your app to launch is a second they are using to imagine strangling you with your own intestines. Seriously. When I start an application, I want to use it immediately. Not in 5 minutes, not in 30 seconds but now. Make sure the UI pops up immediately, and that the controls are functional as soon as possible. Then if you need to load some plugins, or libraries put a throbber somewhere in the corner. As you are loading, let me do easy stuff like open the file dialog and etc… Gray out the shit that is not ready yet, or something.
  2. Stealing Focus is Evil - don’t you just love when you typing something when all of a sudden your IM client or some other app pops into the foreground? While an your app might potentially need to steal focus from it’s own window to display a dialog, it should never, ever attempt to steal focus from other applications. It’s annoying, and it interrupts my work flow.
  3. Modal Dialogs Suck - sometimes modal dialogs might be necessary, but they should be used very sparingly. There is absolutely no reason to make the common save, open and properties dialogs modal. Why? Because modal dialogs not only steal your focus, but also hold it hostage. And stealing focus is evil
  4. Splash Screens Suck - I can’t tell you how many times I said to myself: “boy, I love how this application shows me this big fucking ugly splash for a full minute every single fucking time I start it up”. Seriously, just think about it? Do you like staring at splash screens? No? Then why THE FUCK do you put them in your software? If your Splash screen is there because your application takes 5 minutes to load, and you need to use a progress bar of some sort then maybe consider #1 on this list. Start with a basic UI and update it dynamically as the shit is loading.
  5. Your UI Icons Suck - you can hire a world renowned artist to design icons and buttons for your UI so incredibly beautiful that mere glimpse of them will make people ejaculate rainbows - someone out there will still think they are fucking ugly. Provide functionality to hide that shit - either via some minimalistic text only UI or skinning. What the button does is more important than how it looks, and your power users will probably use the keyboard shortcuts anyway.
  6. No One Wants a Fat, Ugly Toolbars - if your toolbar, status bar, and sidebar take up so much space that there is hardly any left for the actual work area, you fail at UI design. I’m looking at you MS Ribbon, and assorted legion of ugly ass GTK apps. See the rule about icons - no one fucking wants your shitty UI elements in their face. If you absolutely must have big bulky toolbars, provide a mechanism to hide it, skin it or configure it. Otherwise it’s just a distraction and annoyance.
  7. You Do Not Need and Icon in the System Tray - nor do you need to start with windows. Unless you are an app that needs to be on all the time (like a firewall, or on-access AV) you have no business there. If I want you to always be on and start with windows, I will configure it. I’m talking to you Quicktime, WinZip and OpenFuckinOffice and every single crappy piece of shit that comes preinstalled on Dell machines. GTFO! Oh, and dear AV and Firewall makers - if your application does not have a disable and exit button that will kill all your processes, you are no better than the fucking malware you are trying to protect me from.
  8. No, I Don’t Want to See More Tips on Startup - here is a tip: go fuck a duck. How is that for a tip? No one uses these things, they are annoying as shit and serve no real purpose. Note: if your tips are delivered by a talking paper clip, you need to kill yourself.
  9. Don’t Freeze - when your UI locks up and becomes unresponsive most users assume that your app has crashed. In most cases it didn’t - it was simply to busy doing something else to register UI clicks. This is bad as most people will just kill your process leading to data corruption and various other fun side effects. Not only will they think you released a piece of shit that crashes all the time, but will also blame you for losing the data. I’m telling you, that fucking “Not Responding” notification in windows is a death sentence. Linux users on the other hand will just -9 your ass without even thinking about it. Use threads, or forked processes, and always display some sort of progress bar, or throbber animation when busy. As long as shit is moving on the screen the lusers probably won’t even be tempted to click on the UI.
  10. Did I Mention that Splash Screens Suck? - seriously people, lay down on the Splash bullshit. Especially if the bitmap splash image is actually bigger than your core binary. Get a grip!

So here you have it. Follow these 10 simple tips, and your users will love you. Unless of course your app sucks anyway - but I can’t really help you there.

Btw, profanity is there to emphasize the point. We all know that all these things suck for the users. I dare you to take any of these points and argue why doing opposite from what I’m telling you would be better for the user. Sure, some of these things might be related to development costs (making an UI that doesn’t lock up on intensive IO might be harder than creating one that does) but don’t tell me that splash screens, startup tips and ugly ass toolbars that can’t be resized or hidden really save so much time and money.

Every one knows these things. Everyone hates the apps that do them. And yet, every other piece of software on the market (proprietary and free alike) violates at least one, if not all of the tenets of GTFO UI Design outlined above. Why is that?