I have always been fascinated by how things that might look insignificant at first can snowball into changing one’s life. Four years ago my grandfather came to me with a small piece of paper where he had scribbled the name of some high tech start-up he heard about on the local radio “you told me you were considering getting a new job, ever heard of this company?”. Now let’s just say that his understanding of what I do for a living doesn’t go much beyond “stuff with video games and computers” and I had little hope that the company would be in any way relevant to me.
Long story short, that company was into real time 3D, I went there for an interview and I met their engine lead, an extremely friendly and knowledgeable guy who was later to become a very good friend. He had been deeply involved in the creation of one of the most amazing video games I ever played as a kid. Deeply impressed, I signed right on the spot and learned a bit later that he was also an invited teacher for a few hours a week in a video games school. I told him about my own interest in teaching and, a few months later when the school was looking for someone to handle a small scripting course (30 hours), he backed my application and I started the following semester.
Three years later, as the school opened a new specialization track for game developers, I became the main teacher for the programming classes (over 400 hours). This job is one of the best things that ever happened in my professional life, and I am still trying to understand just how lucky was the chain of events that led me there.Rolling my sleeves
Just like me, most of the programmers in the games industry I have been working with over the years seem to have followed the same kind of path: got their first computer as kids, became the typical bedroom programmer, nerd and gamer, and eventually got a degree in CS or some related technical field to finally get a job in the games industry. Self-taught, without the Internet, with only a few books and manuals, we had to mostly rely on trial and error to get stuff working, and the first results were usually unmanageable messes of spaghetti code. Let’s not talk about the lack of IDE, OO languages, on-line help and debuggers, or even a decent operating system.
That took years but we finally found solutions. We gathered knowledge and experience, better tools, better languages, design patterns, a library for every need, insanely powerful computers, and unlimited access to a large part of human knowledge through the Internet. Now, as someone who did not use any of this during his education, how should I transfer all that to students? Simply by explaining the “right way” of doing things, the one I had to painfully learn by myself. Code should not be written without a clear idea of what we are going to do nor without a well defined structure. The problems at hand should be carefully analyzed first, to see which parts are going to interact with which other parts. I would explain how to name things meaningfully, how to dispatch the code in compilation units and properly use the features of the language, and why we should aim for encapsulation and flexibility and avoid cyclic dependencies. After a while I paused and took a good hard look at my course – and realized it was the most boring crap I had seen in a very long time. Had I been presented with it back in the days where my interest in computing was only starting, I would have probably decided to go for something else.Let’s try again
Then I remembered what my first contact with a computer was. It was in 1986 and the Intel 386 was brand new and awfully expensive, but my elder brother got one through his job. When I asked him what I could do with that thing, he bought me a book about GW-BASIC. I read that book from cover to cover and I didn’t understand much of it, but it was about creating stuff and that sounded very exciting. I came back to the computer and started hunting and pecking on the keyboard and I eventually managed to get the damn thing to display a few lines with the DRAW statement, which was some kind of turtle graphics sub-language within BASIC.
The book did not tell me what to do or how I should do it, it was only explaining the features of the language. There was nothing between me and the computer, I could experiment with it the way I wanted, and immediately try every idea that would cross my mind. An endless world of possibilities lay in front of me like mountain-high stacks of Lego bricks (sounds nerdy, right?). And from that day, as I tried to build software I made every single possible mistake, and every time I learned something it made me realize how seriously messed up my previous attempts were. I read somewhere that students are usually taught programming by explaining ready-made solutions to problems they are prevented from experiencing. That summarizes my experience with school in general. Never roll stuff on your own, use libraries! Design first! Use proven patterns, tools and techniques! Don’t you dare use a global! Don’t mix beer and wine! Oh yeah, don’t drive on the railroad track! And so on. I think that is the wrong way to go. Instead, let’s run into problems first. So I abandoned templates, virtual functions, inheritance. I removed private members, and even classes and structures as a whole, I removed pointers and references, I put everything in one big file and I used global variables, I even avoided writing functions and had the whole program in one chunk. I kept on cutting everything I could until I had the bare minimum a small, interactive program could be based on.Not in Kansas anymore
And this is basically the kind of mess I got my students to work with. They would start with a few lines (calls to a minimalistic DirectX/PSP wrapper I wrote that could only display sprites and poll the buttons). Most of the time, whenever they tried to add anything, something would break. I would investigate with them to find out what had happened and why it had happened, and backtrack to the origin of the error. Once I saw that they were starting to grasp the basics I progressively introduced some language features like scopes, functions, and structures. But I always insisted on keeping things as simple and straightforward as they could be.
Starting with the basics is certainly not a new idea in teaching, but letting the students experience the pitfalls (basically everything memory related in C) and building something reasonably complex without learning the “proper” techniques first was fun, in a “let’s jump off that cliff and see how it goes from there” kind of way. After a few months came the first assessment, and I had no idea if I was doing any good. I asked each student to write a small and well defined program all on his own, and I set an oral exam were I asked them to explain what they had written, so I would ask questions on their choices to ensure it was personal work. It had been a long time since I was that stressed at an exam. At the end of the day I had been blown away, they all came up with a different solution. Their programs contained lots of mistakes, but they mostly worked and they were all genuine inventions. They had combined together the very basic principles they had learned in different ways (sometimes very convoluted ways) as simple means to reach a goal. It was not about programming anymore but what could be done with it. After that I kept on introducing new features, and when I finally started explaining the first concepts of OOP, the reaction I got was “why didn’t we use that earlier?”. And not some “what the hell do we need that for?” perplexed stare.Conclusion