OOP(S), We've Been Going Backwards

I'm about to blow your mind, because you've probably never heard someone say this in all of your indoctrination, erh, ahem, I mean training. Object Oriented Programming is wrong.

The fundamental tennets of Object Oriented design methodology are fallacious. The promise of OOP is that anthropomorphizing data will make it easier for programmers to grasp the data interrelations and interactions, but it just muddies the water for how that data is processed. The class does not exist. It really is just a bag of data--your CDog instance is not a dog, it's electrical signals that represent numbers that represent data that represent a dog--and to treat it otherwise is to peddle in lies.

OOP has done nothing to decrease the complexity of application development, nor has it led to more successful projects (success measured in terms of coming in on-budget). And if you look at the OOP advocated by such ecosystems as Java and Struts, you'll even see a massive increase in complexity.

In any enterprise scenario, the most important thing is data. An enterprise application is nothing without a solid database, and the database will live on long past the application itself. That's the fallacy of N-Tier and MVC architectures: that the database is somehow an integral part of the application. How many times have you worked on new intranet applications that were connecting to and manipulating old databases, be them ancient mainframe systems or over-leveraged MS Access debacles? We'll be writing programs in C# 7.0 before we completely migrate off of dBase II. That's why COBOL applications still exist, the data storage was integrated into the programming language. And in an ever more regulated business environment, our requirements for data are only going to increase exponentially.

But what changes constantly and dramatically is how we want to see that data. That is our application. The means by which we manipulate data are absolutely decoupled from the data itself. In 20 years time, you're not going to want to know how report XYZ was calculated (in some part because it was probably wrong), mostly because your business needs are completely different and that report just doesn't make sense anymore.

By using OOP, you're marrying your data and your behaviors, by its very definition, and then trying to hide your data. It's like playing 20 questions with your business. When some new business analyst comes along, trying to make a name for himself in the company, and declares that System XYZ that has been running perfectly well for the last decade needs to be rewritten "to bring it up to industry best practices", in an OO scenario you're in the old cliche of "throwing out the baby with the bathwater." This is especially true if you've used an ORM system that lets the application drive the database design.

This is probably why there aren't very many jobs for Lisp and other functional language programmers: because their languages were pretty much right the first time so there is no pressure to "upgrade" and their applications just work the first time because they know the difference between data and how we manipulate the data. In functional programming languages, EVERYTHING is understood to be just bags of data. In Lisp and Scheme, you pass around lists to all of your functions, lists that don't advertise particularly well what are in them. That's because, for the most part, it doesn't matter. You don't want your application to know very much about your data. You want to segregate those parts of the application that do know about the data to very restricted and limited areas. The more generic the bulk of the code, the more reusable it is.

Which brings me to yet another fallacy of OOP: code reuse. When was the last time you reused a class you wrote yourself? I bet you have a "Utility" class somewhere that's a bag of static methods, we all do, because OOP doesn't account for the fact that functionality exists separate from data. That doesn't count, that's not a real class. I'm talking about BusinessEntityWidgetX implementing GodAwfulInterfaceY. When was the last time you reused either across applications?

So OOP, you promised the world, and you never delivered. Then you built a system of indoctrination around yourself (university computer science programs) to protect yourself from criticism. Congratulations, you've achieved the status of religion.


On Arguments

My friend Far McKon recently posted a bit on living in a connected world and the responsibilities of having an online persona. Check out his post, "Have Big mouth, will travel." I was originally writing this as a comment on his post, but it got to be quite long and I thought it would better serve as a post on my own blog.

I try to use the type of situation that Far refers to as learning experiences (always after the fact, "the bridges I burn light the path before me") to see where I can improve my debating skills. These days, I try to only talking to people who don't agree with me; it forces me to be honest as well as humble. I could have avoided a lot of arguments in the past by being more cognizant of my audience, specifically who that audience might fully entail. It can be a slap in the face to realize that a lot more people heard what you said or read what you wrote than originally you intended.

The key is to recognize the difference between content, delivery, and desired outcome. There is more than one way to express any opinion, and even very contentious opinions can be expressed politely without resorting to patronizing political correctness. Without practice, your delivery is reflexive, and without control over your delivery, you won't get your desired outcome. Tailor your delivery for the outcome. People don't wan't to have their opinions challenged by a stranger. You often have to "lose" the early battles to get to a position where you can win the war.

It can make you a better writer in the process. When you're more aware of what you want to say and the emotions you want to evoke, you can cut out the extraneous bits that are primarily repetitions of your thesis through the various lenses of your own full range of emotional responses.

But there is also a certain level of responsibility that needs to be shouldered by the other party. If we take on all of the responsibility for poorly ran arguments, then really we're admitting that the other person is perfect. Also, irrational people exist*, and there is just no accounting for them.

So, what does it all mean? Should we have more anonymous systems to allow us to express our opinions to the fullest? Or should we censor ourselves to be more palatable to the masses? I think the answer is, "Yes". Since the advent of the Internet, we live in a world where people get to tailor-make their social circles. Before the year 2000 (the distant future), if I wanted to talk to someone on a Saturday, it had to be my next-door neighbor. We didn't get along on most things, but we had an amiable relationship because we had to have one. Now, I can piss off my neighbors all I want and it doesn't matter, I can find validation online in my custom community.

In the long run, I think it's healthier for each of us to learn how to argue our points in the complete open. But sometimes, you just gotta say, "FUCK 'EM ALL TO BURNING HELL AND BACK AGAIN, RARRRRRRR!" Venting can be healthy, too, and we need new places to vent. For us 'Netizens that have been around the block a few times, maybe that just means being faster than Teh Nooblets on reinventing our online personas. It certainly means ignoring Facebook Connect and Google Sign-In and OpenID. God, whatever happened to having to remember a dozen passwords for all of the sites we interacted with?

* There is a whole post on whether or not arguments are based in lack of rationality in one or more parties in the conversation, or a lack of shared facts. Keeping it short, I now recognize that no amount of facts can save certain people. But for the most part, it's the lack of shared facts.


How to Write Tetris

I'm starting a series of articles on how to program basic, 2D video games, with the object of focus being the game of Tetris. I'm going to try to be as language agnostic as possible, but certain parts of this project are extremely OS and programming language dependent. So far, I plan to do the articles in seven parts:

  • Part 1: Timing - Making the "game loop" is something that trips up a lot of new programmers. The game loop is a constant feature of your game project, so getting it right is important. There are a number of ways to do this in a variety of different languages; I'll show you the most common ones.
  • Part 2: Basic Graphics - You're not going to get very far if you can't draw something on screen. We'll focus on 2D graphics APIs, as there are plenty to come by that are more than suitable for this task.
  • Part 3: Tetris Logic - I'll go into detail on how I have decided to implement basic "Tetris" logic, and my motivations for doing so. There are any number of ways to do this.
  • Part 4: More Advanced Graphics - The graphics we did in Part 2 are serviceable, but not pretty. We'll learn how to leverage free tools for drawing tiles and backgrounds that can really punch up the look of your game while remaining very simple to implement.
  • Part 5: Sound - The sounds requirements for such a simple game are very limited, so this is only going to cover some basic points.
  • Part 6: All The Trimmings - At this point, the game should be playable, but we won't have any of the "trimmings", e.g. menus, game over screens, score tables, options, etc. Here, we'll go over what users typically expect out of their game experiences and how to implement them in a way that is robust and easily expandable.
Along the way, I'll be pointing out different areas of programming best-practice that often only come out of many years of experience. I've been programming professionally for over a decade, so hopefully you can learn from my past mistakes and get off on a good footing.


I'm quitting

I have a bit of an announcement to make. I quit my job today. For the last two years, I've basically been in an ever increasing spiral of depression over the fact that I hated my job and had grown to hate the menial work of programming that pretty much consists of 80% of all work in this industry. I jumped around on projects and new jobs trying to deny it, to find some kind of secret sauce that would fix it all ("Maybe I just need a different environment, maybe I need to get away from this shitty code base."), and it only served to make me want to wall myself in my room and never come out again.

So I quit. I'm probably going to quit programming for a living. I haven't had any fun programming in the last 3 years because I've been too caught up with programming for work that when I get home I'm spent. Back in September of 2010 I started a project that should have taken me 2 months. Three years ago, I would have rushed home from work and worked on such a project until 2 in the morning. It's still not done and the fact that I haven't been able to do that is a serious canary in the mineshaft in terms of my ability to perform in this field. I like to think that I'm a person capable of keeping promises, so I gotta push through the burnout and just get that project done stuff done. Conveniently, I've suddenly have a lot of time on my hands.

I've got enough cash to get by for a few months without needing to have any income, and then my lease runs out on my apartment, I'll cancel my internet and utilities, and my cash requirements plummet dramatically. I'm not in as good of a debt position as I would have liked by this point, but that's yet another symptom of what I've been doing (or rather, not doing) for the last 2 years.

I don't really know what I'm going to do long-term. I might end up flipping burgers, or I might end up a freelance photographer. Part of the whole point is to reassess my life decisions and come up with a plan that keeps me from getting burnt out like this again. Now seems like a good time to get a bunch of loan proposals done for different business ideas that have been sitting on the back burner for the last 3 years. Grad school applications suddenly seem feasible.


The Antoine Dodson Affair

Urlesque, purveyors of teh funnays, tackles a little more serious fair in the midst of their typical format.

The article brings up the "rape is not funny" issue, siding firmly in the affirmative. The auto-tuned, song parody of the video falls into the category of "rape joke", but it's not about the rape, it's about the flamboyancy of Dodson. When he says, "hide your kids, hide your wife, and hide your husband, they rapin' everybody out here", it's not funny because "everybody" is getting raped, it's funny because he suggested hiding your husband! Anyway, I don't want to go too far down this road, because the article is much more about race than it is about rape.

They're fairly critical of Ed Bassmaster -- a comedian who has successfully turned his popular YouTube in-character-prank-calls into paying acting gigs -- and his parody of the original video. They say he "Needs more blackface, bro!". I think that's pretty unfair, Ed is basically adapting one of his more popular characters to this meme. But whereas Ed can't parody the video because he looks white, apparently the last video in the list is okay, because it's made by an obviously-black-man. I'm really not sure what Ed's race is, and I don't think it should matter in this case.

The hand-wringing over whether or not it's racially appropriate to laugh at Dodson or the parody videos seems to me to be a tad hypocritical. If race shouldn't be an issue, then don't let it be an issue. Enjoy a ridiculous video for what it is. It just feels more like people jumping over themselves to declare their "sensitivity" to the "issue". Really, it's a hypersensitivity to race that is actually just patronizing. I like the news station's answer to the issue, would it have been better if they didn't let him voice his opinion at all?

Those are my two cents on a completely inconsequential topic. Thank you.


HTML5 Stereocopy Demo

I've written some JavaScript code that is a basic demo of stereoscopic rendering with the new Canvas element. The techniques that the Wikipedia article describes that I have used in this demo are:
  • Stereopsis (in this case, simple linear transformation in X-axis proportional to Z-axis as an approximation to a real 3D transformation)
  • Occlusion of one object by another (Z sorting)
  • Subtended visual angle of an object of known size (scaling object size proportional to Z-axis)
  • Haze, desaturation, and a shift to bluishness (interpolating object color proportional to Z-axis)
The performance in Chrome is pretty good. This also runs on the Android browser, though you have to drop the rendering down to 10 objects even on the Motorola Droid to get anything resembling reasonable frame rates. It also runs in Safari for Windows, Firefox, and Opera. I've included Google's EXCanvas script to get it to work in IE, but performance is abysmal.



3 Hour Game Design Contest, m.VII

TL;DR Summary:
Make a puzzle game in 3 hours. Win GDNet+ Membership. April 10th, 2100 UTC.

#3: a PayPal transfer worth 3 months of GDNet+ membership ($12.95).
#2: a full year of GDNet+ ($39.95).
#1: a $75 gift card for Amazon.com (email gift card).

For the seventh competition ever (it seems weird to me that we've done 6 of these things already, and yet the last one was over 3 years ago.), we are going to mix things up this time. I've just open sourced some code for creating grid-and-tile puzzles, ala Tetris or Dr. Mario or whatever. It provides a very basic framework for defining pieces and figuring out different ways to place them on a board. Included in the distribution is an example of the Tetris game. On top of that, there are two examples of UI implementations for the game, using either the system console or Windows Forms, demonstrating a sort of MVC setup for game development. Also, I've included the NUnit tests in the source code; if you want to run them, you will need to install the framework (the solution file is current configured to not build the test project when building the solution, to avoid errors for anyone who doesn't have NUnit installed). It's pretty simple, but if you have any questions, feel free to ask.

So, the contest will be based in some way on puzzle games: you can use my library if you want or not, you can spend the next few weeks porting my library to your favorite language if you want (I've released under the MIT license), you can develop your own puzzle game library if you want, it doesn't really matter, as long as you meet the secret theme. If you would use my library, I would greatly appreciate it, to give it a sort of "real world" test, see what people make of it, and see where it should be taken from here. But, it's not required.

We usually have prizes for this contest, typically a certain amount of cash via PayPal intended to be used to purchase a GDNet+ membership. Prizes are donated by the community as a whole. I've donated games before as well. At the very least, I'll end up covering 1 year, 3 months, and 1 month of GDNet+ membership fees as the top 3 prizes. I might dig through my hardware pile and find something interesting. Anyone else is free to offer something.

Saturday, April 10th.

The past six contests were "Black and White," "Fire," "Crackers," "CARTS," "The Stars", and "The Pits". The emphasis is originality in interpretation. With the Crackers theme there were entries that featured fire crackers, saltines, people "cracking" windows open to prevent leathal doses of methane gas, and southern honkeys.

I'm getting rid of the ASCII art requirement this time. If you want to do that, that's up to you, I like ASCII art games. I personally think the contest is easier if you do ASCII art, but that's just me. You might find it easier to do it in HTML5 or Flash, which is perfectly acceptable.

  1. Submissions must meet a predetermined theme (which will be revealed 15 minutes before the beginning of the contest)

  2. Any Language (C, Java, C#, Python, javascript, Brainf***, I don't care) or API (SDL, Allegro, PyGame, JOGL, even SVG in HTML5 is cool) are acceptable, as long as you handle all distribution yourself (Ideally include all assemblies. You may link to download page, but please, don't just link to the project's homepage). This is especially true if you use a "game maker", I don't want to have to hunt anything down to play your game.

  3. Writing the code in the time limit is "on your honor". That's why I keep the theme a secret: you might be able to make a generic game between now and then, but you won't be able to make anything specific to the theme. But seriously, why would you cheat for such a simple contest?

  4. Judges will judge on a full binary version of the software. They will not compile the software. Source code is not required, though you may request source code to be posted with your submission.

  5. Judging is conducted by a panel of non-competitors

  6. Judging is based mostly on overall gameplay and originallity of game design. We understand that content will be light, that graphics will be underdeveloped, that input MIGHT be a bit akward. Gameplay and concepts are key.

  7. prizes (when available) are listed above, runners up receive nothing.

Three hours is plenty of time to make a classic arcade game, or something new with simple gameplay. The threads for the previous contests are available below. Unfortunately, all of the links are broken. I still have an archive of all of the games, I just need to find a place to put them (maybe CodePlex?)

If anyone wants to volunteer as a Judge, please post here and list your machine specs as well as your pertinent software running on your computer. For example, I'm:

Processor: Intel Core 2 Duo E8600
Memory: 8GB RAM
GFX: NVidia GeForce 8800 GTS
OS: Windows Vista Ultimate 64bit
Browsers: Google Chrome (default), IE8, FireFox 3.6
Other Software: Whatever the lastest, non-beta versions of Java, .NET, Python, Ruby, DirectX, and XNA are available. I don't remember, but I'll make sure everything is up to date before the contest.

Not that it's terribly important, given the low level graphics this contest will require.