This had been written as I grew up. It mainly concerns only the computer stuff I’ve done, it doesn’t have anything about music, school, and other aspects of life. I may have skipped a few things.
My experiences with game (and software) development began when I got this thing called QBASIC from my neighbour. I started copy-pasting tutorials from all over the internet, not understanding a thing. Finally though, I gave up and tried to learn how it all works. I made a few QBASIC programs. Some of them involved graphics, but they weren’t that great, just some random lines (at that point, trigonometry was something I’d never heard of). My Dad then gave me a fun assignment: Write a program that takes some numbers and sorts them. I wrote some algorithm that worked (a few years later, I discovered that it was called ‘Gnome sort’). I decided that, if I can write programs that sort numbers, I can make games.
I searched on Google for ‘game creation program’. I found a lot of stuff I downloaded and could not use, until I found Game Maker. I stuck with it. It had two ways to make games :- Drag and drop, and programming. At first, I used drag and drop but it was good only for simple games (like pacman). I switched to coding. It took me a long time to learn, but I still stuck with it thinking I would some day get it. Game Maker had great documentation, which helped. 3 weeks later, I finished my first game, Space Age. I made a few more games. I made lots of little demos and quick applications, trying to incorporate physics, particle effects and whatnot. A lot of people released their Game Maker games’ editable documents (source code), which served as a great place to learn. My dad bought the full version for me, and then there I was, bashing away at the keyboard almost everyday. I just loved the way Game Maker organised your game. It was flawless. In Game Maker, there were the following 3 important things:- Sprites (the images and graphics), Objects (the actual logic objects), and Rooms (the worlds or levels). Each object handled itself, instead of one big function where everything is done. An object actually defined a ‘type’ of object, and then there were individual instances of these. It was an ingenious method of organizing the game. But, all my games were 2D. I tried to to 3D. It worked (‘Kidnapped’ was a 3D-GameMake attempt, Summer 2005). But when I made the second level of my game, it was almost reduced to a slideshow.
I decided to try making games using C++ (I had seen some C++ code before and was horrified) in September, 2005. My dad bought me a C++ book long before that time, I tried to learn but couldn’t. I discovered that it was about Visual C++ (the IDE), not the language itself. But, there was a small C++ section too. I learned from that. After a week, I downloaded Ogre and tried to make something (I had seen Ogre before, but thought that it would be really complex and difficult to use like the other C++ engines). For around 3 or 4 days, it didn’t work. I put it up on the forums, and in less than 2 hours, I got a reply and it got fixed. Been using Ogre since then. :-) I messed around with the tutorials on the Ogre wiki, and wrote some little applications (one of them involved a Robot you could walk around with, and suddenly he went into jetpack mode and you flew him around). I also made a small remake of Pong in 3D (Winter 2005). Taught me quite a bit about 3D math and physics.
After making many small demo games and little apps (and later adding physics and sound to them), I decided that something serious should be done. I began work on HAPDV (I forget what the acronym meant). The game was to be about driving hovercrafts around a city, racing, and combat. It was a very ambitious project. I found that it was difficult to organise a game in C++ unless you had some kind of well-thought-out-framework going. So, I tried to emulate the Game Maker method (splitting everything up into objects, each minding their own business). But, the game required lots of work and art and was abandoned (stopped). During the Summer of 2006, I decided to sit down and start designing a clean, extensible framework, that allowed each ‘GameObject’ to do different things, while still maintaining an ‘order’, notifying them of events, and in general, managing things. A framework that works like Game Maker. Each day of the summer vacation I would make little diagrams showing object relationships, hierarchies, and flowcharts of such a system. Thus, NGF (nikki’s Game Framework) was born. It allowed the programmer to make objects, organize and manage them, update them every frame, send messages between them, make worlds (Game Maker rooms), load levels and lots of other stuff. In the first, and half of the second, month of the vacation, I didn’t write a single line of code, just design. Then, I made a short code sketch, and then wrote the actual code. The problem was that, in India (I went there for vacation), I was working on my aunt’s laptop and had no C++ compiler (she was a Java coder :P, and even if I installed a compiler I’d have to get the dependencies and setup Ogre and stuff), so I couldn’t test my code. I could only prove it right. Once I came to Doha, I incorporated NGF into a demo I made before the vacation, and was surprised to see that it worked with only 2 or 3 small errors. I then made the world manager, the level loader and the Blender 3D (3d modeler) to NGF level exporter.
I had been thinking of a game that had a ball rolling around in a maze back in July. The maze should have electricity, spikes, bombs, switches, keys etc. I drew some small sketches and planned until October 26, when, finally, I had written the first line of code of GraLL. The first time I ever ran GraLL, it had a ball in empty space that just fell into the depths of infinity. By August 2007, it was completed, and I first released it on the event of my dad’s birthday (10th of that month) (later, there were some bugfix releases). I also made a little website for it. It had had 30 levels, and was quite a bit of work. Every time I figured I finished something, there was something else left. Working on a large project by myself was a hard thing to do. I had to do the art, the programming, and the levels myself. But, I did it anyway. I did it just because it felt good doing it. I did it for the process, not for the result. During the Doha Asian games in December 2006, we went to stadiums everyday to check events out. It was great fun. Somehow, it also gave me great ideas for GraLL (no, the ideas weren’t based on sport, just that, as I enjoyed myself my motivation grew).
After that, I worked on adding more features to NGF, to make it more general purpose and less tied to GraLL. I released the NGF source code the end of that year. Soon, I wasn’t able to concentrate much on writing software, because I had to concentrate on school, and also because I began to develop a deep interest in music.
After the end of the final exams, I got back to work. I began developing a new level format for NGF. The old format was just a ‘scenedump’ (yes, almost as unorganised as a coredump). This format was more organised, and allowed per-instance ‘properties’ (such as ‘difficulty’ for a Monster, or probably ‘diffuse component’ for a Light). I also cleaned up the code a bit. Near the end of the first term of school (around June), I added more features to NGF and started work on a small demo application (which was similar to GraLL) called OrangeBall, because I was getting bored. :-) For my summer vacations, I went to India, and I continued to develop it there for a while. However, I got bored soon (again), and thought of doing something different. In the middle of the vacations (August 2008), I decided to try Linux. I’d already tried it out before (SUSE) but couldn’t get the internet connection to work. This time, I tried Ubuntu, and it worked fine. I tried setting up a working development environment (gvim + premake = awesome!) under Linux because I found it nice (I especially loved bash, no more mouseclicking and waiting for a screenfull of icons to load). I tried getting Ogre, MyGUI, Bullet to work. I faced a few problems at first, but it was fine eventually. I wrote a little application to test that everything was working fine. I also tried scripting using Squirrel, and found it to be great fun. I made my own little website with a blog and a page for my software projects, at http://nikki.drupalsite.org. After I returned to Doha, I found it really easy to get Linux set up on the Desktop. The internet connection worked fine too. I tried some alternative window managers (instead of the resource-heavy GNOME and KDE, both of which provided features I didn’t really need anyway). I settled with ‘xmonad’, and ‘dwm’ on a few occasions. I was preoccupied with school, but tried to learn as much as I could at the same time. I released a ‘new NGF’ with better features, and much better documentation (a tutorial, a demo application and a manual).
However, a few days after the release, my desktop monitor got busted, and I moved over to the laptop. We never got the monitor fixed, but that was alright, it helped me concentrate on school more. At first, I worked with Windows (oh noes!), which was already installed on the laptop. I began reading a book called ‘The Cg Programming Tutorial’ which was released free by NVIDIA, to learn more about shaders. I’d written quite a few fun shaders, and read some papers about optics and tried stuff from them. Then, I decided to actually understand how quaternions work, and read a few math articles. After that, I wrote my own quaternion implementation for Cg shaders. Soon, however, I got bored with Windows, and decided to install Linux again. :-) On the laptop, I installed Arch Linux, a more ‘geeky’ distro than Ubuntu. I had problems getting input to work at first, but fixed it. I installed ‘dwm’, really cool window manager, and hacked the source code to suit my needs. Soon, I got Ogre and the usual stuff installed, and got NGF working too. One weekend, I started working on a thin Bullet-Ogre connection called ‘BtOgre’ and released it. It seemed to be useful to quite a few people. It was more minimal than most other Bullet-Ogre connections at the time, and didn’t try to wrap Bullet constructs. It only did the Physics→Graphics and Graphics→Physics communication (in fact, the files were named to reflect this philosophy). I decided to learn Haskell, and over a week, I read a book called ‘Real World Haskell, and wrote a few simple programs. Haskell taught me about functional programming philosophies. They seemed quite weird at first, but when I tried to forget everything (no, not permanenlty, just for that period) I knew about programming at that time, I could see the logic. I tried Lisp too, it was pretty cool. Then, I turned to learning assembly programming. By learning assembly, I understood more about how the CPU works (at the software level). I’d learnt about the registers of different sizes, high and low bytes, extended registers, endianness, segmented/protected memory models, the hex and binary number systems (I knew about them already but this gave me a deeper understanding), hex-binary conversion (convert 4 digits and concat because hex-base = binary-base ^ 4) etc. I saw the interface between hardware and software, where everything happens. I used quite a few languages before, but I never really knew ‘how it all worked’. Through assembly I understood the real stuff about compilation, linking etc. It was one hell of an experience. :-) An internet friend of mine (I met him on a TF2 server) and me would talk for long hours about this stuff. He was an embedded systems programmer. This particular winter was one of the best in my life. It showed me that, at times, you have to give up something you’re used to, and try stuff out. I moved to the laptop, and because of the constraints involved (can’t play games, installed different distro) I tasted a completely different environment (well, not that different, most Linux distributions follow the same model, but this particular one involved a lot of ‘do it yourself’ stuff). After that I had to concentrate on school because we had the ‘board exams’ (which everyone considers pretty important) coming up.
During the board exams, I in fact had a lot of free time. There were between 3 to 10 holidays between each exam, and I could get a lot of non-school stuff done too. I evaluated Lisp as a scripting language for games. I got it working great, but ultimately, when it came down to what I wanted scripting for – level-edit-time costumization of per-instance-behaviour – it couldn’t scale well. Particularly because I couldn’t get CLOS working very well with the C++ OO mechanism. After looking around at many languages (Lua, Squirrel, Python, Io) on which to use, I finally setteled on Python because of the cool boost.python API. I wrote a small interface on top of NGF that allowed Python-scriptability of Ngf GameObjects. It was easy for GameObjects to write their own methods to be exposed to Python without having to talk to boost.python. This was done by having requests for members of the object be redirected to call a ‘method’ function. This ‘method’ function took the name of the function and the arguments. It was a C++ callback. Using gperf for the hash mechanism, I could get methods working quite easily. C++ members could be explosed to Python too. Scripts for each instance could be written right in Blender, where objects are placed, and shapes are modeled. Then, I wrote a simple serialisation mechanism to be able to save and load the state of the game (in one night :-) ). What it did was create a container of ‘GameObjectRecords’ that held information about each object in the game, and then serialised that, instead of directly serialising all GameObjects. It saved the state of the game as in Python (Python sides of the objects could have their own member variables) too. The ‘load’ mechanism involved a two-step process to fix dependency issues between objects, especially circular ones. I also seperated the Bullet-NGF connection into a seperate plugin, to keep the core NGF code cleaner (earlier I used dirty #ifdef stuff). By then the exams were over. My dad considered buying a new computer, one with all the latest jazz.
At this point, NGF was getting pretty mature. The best part was, I could decide how it all works, because I wrote it :-). After we got the new computer (Quad Core, 4GB DDR2, NVIDIA GTX 285 :D ), I began work on GraLL 2. GraLL 2 was to have a lot of new stuff, Python scripting, a ‘dimension system’, new obstacles, better physics… All this was made easy due to the new developments in NGF. As I worked on GraLL 2, I found flaws in NGF and BtOgre that I fixed as I went along. GraLL 2 had eye-candy improvements too, I wrote shaders in Cg (the book I read in winter helped), normalmapping, parallaxmapping, and glow. Lights (point/spot) could be placed in Blender. Instance-specific scripts could be edited right in Blender’s text editor, making things a lot easier. The code was on GitHub, and I had a ‘Notes’ file with a complete ChangeLog right from the start. In summer that year (August 2009), we went to India on a vacation. I took along the GraLL 2 code on the laptop (was easy, as now it was on GitHub). Since the laptop couldn’t run shaders with good performance, I was forced to turn them off, and this way I could test GraLL 2 on a low-end system. On vacation, I fixed many bugs in (mostly Physics stuff, stability issues) and developed the menu system. Since this one used ‘MyGUI’ (an Ogre GUI library), it had the usual GUI controls (sliders, radio buttons). Also, in India, we bought some books. I bought a book on ‘Understanding The Linux Kernel’. It was a great book, I was always interested in how Linux works under the hood. I also read Tanenbaum’s book on operating systems (belonged to my aunt, she used it in college). It’s nice to see how the system that manages programs, memory, IO etc. (which is usually taken for granted) has to do so much book-keeping to carry out even tasks that are considered quite simple, like reading/writing a file. The driver has to be communicated with, locks maintained, race conditions prevented. It’s a big headache, but also fun to read about. :-) The book inspired me to look deeper into Linux again. We were on a train journey to Chennai. On the train, I compiled an ‘LFS’ (Linux From Scratch) system, with my own costumized kernel! However, though the installation was a great learning experience, I couldn’t exactly use it for day-to-day work. I need something like ‘pacman’ or ‘apt-get’. :-) So I decided to get back to the regular distros (although I did try Gentoo).
After returning to Doha, I got back to work. I tried to improve the Python scriptability of GraLL 2, by writing Python dosctrings, and better feedback about errors. At this stage, the Python scripting system in the game was advanced enough for me to be able to start developing ‘prefab’ objects (as I call them). ‘prefab’ objects are simply native objects with scripts added, saved in a ‘frozen’ state in Blender ready to be thawed in your level and played with. :-) It’s like a native object, except that a lot of it’s functionality is written in script, and the script functionality actually becomes another level of abstraction (the Door prefab reads the NGF GameObject propertylist in the script!). The first prefab was the Generic Door. It read it’s ‘opening condition’ from a string. The string is a Python expression that evaluates to a boolean value. Whether it opens or not depends upon this value. This way, the Door is ‘generic’. I also added a generic ‘Pickup’ system. Instead of having to stick to just ‘keys’ or ‘powerups’, you have a generic Pickup object, each instance of which can have a ‘type’ associated with it. The Player keeps a track of how many Pickups of each type he’s picked up. This information can then be examined at any point through the Player’s Python interface. With the Door and Pickup mechanism, if you set the condition to ‘other.hasDecPickup(“KeyR”)’, voila! Instant Door! The ‘hasDecPickup’ function just decrements the Player’s count of a certain pickup, while returning whether or not he had it (before decrementing of course (semaphores, anyone? :P ) ). All this, and the Door and Pickup don’t even know about each other, and the Pickup doesn’t even know what types of Pickups are available! I also added a handy feature that allowed you to just click on an object and retreive a handle to it in the Python console. Saves you from having to assign random names to every object, forseeing that future moment where you’ll have to reference it in your console scripts. I also added something people had been pestering me to put in GraLL 1 – enemies. Well, not really very clever ones that come up with ingenious plans to destroy your hopes of completing the game – but rather unintelligent ‘turrets’. They shoot at you, take a rest for a while, and then rinse and repeat. Some might even wait until you come into view. This involved some fun state machine stuff. First, the state machine involved ‘in-class logic’, but then I wrote a separate ‘NgfStates’ library that has fun macrohax (argh!) to build simple statemachines using a nice syntax within the class definition. Then, I realised that I had to make it possible for users to make their own levels, own textures, and any other kind of media for use in the game. So I came up with the ‘User Content’ mechanism, in which users can just dump their own content (maybe even in .zip files, it searches them too!) inside the ‘usr/Content’ directory in the game directory. At the time of writing this part of this Biography, there’s just ‘user levels’ and ‘user materials’ (with an in-game material WYSIWYG viewer/tweaker).
(this period witnessed a lot of additions to the game, which, due to my blog-infrequency, have been summarised in this post – please do read it for a more technical description)
Now, it was time to add some old GraLL 1 obstacles to GraLL 2 (Traps, Acid). Of course, this being a sequel, more is needed. So, I added some new obstacles too, like the ‘FallingBrush’ (in-game – a ‘Falling Block’, falls when you roll over it), the ‘OneWay’ (a screen through which you can only pass, well, ‘one way’), the ‘Magnet’ (a rather fun physics obstacle that can attract or repel magnetic objects (guess what? GraLL is magnetic :-) ), ‘AmbientSounds’ (well, not really a gameplay object, but a Python prefab that loops ambient sounds to set the mood). I also added a HUD. This was a dynamic HUD, to which timer, pickup or icon displays can be added dynamically. The ‘dimension 1/dimension 2’ icon at the bottom of the screen, for example, works this way. Then came a really fun new feature – gravity inversion. You press ‘G’ (or whatever key you’ve assigned for ‘gravity switch’), and woosh! GraLL flies ‘upward’, the camera view turns (ableit smoothly – this involved some fun Quaternion math) upside down and the level has been ‘inverted’. This feature effectively doubles the fun (in the levels that it’s available – gravity switching isn’t free you know – you need the ‘Gravity Key’) – just like the ‘dimension switch’. Also added were the ‘SpeedBoost’ and the ‘JumpPad’ – both of which I think are rather self-explanatory.
December saw a period of gradual decline in productivity. This of course, was because of academic responsibilities I had to attend to (high-school examinations, and I’d decided to try the January SAT too). Right after the end of January, I tried to get back to work – but I could only do so much before another ‘low period’ in March (yes, I didn’t add to my biography between September and May, hence the ‘prediction’). I decided to start working on the levels, realising that I had enough obstacles and features. After all, it’s how you connect them together and make something bigger with them that counts, as highlighted by this excerpt from an interview with Chuck Sommerville (creator of the original version of ‘Chips Challenge’ – a game that had a big influence on the design of GraLL (and thus GraLL 2) )
“One way to come up with a new idea is to think of ways to use an element in a manner that you have never seen it used before. As an example from Chip’s Challenge, monsters, buttons and doors could be used to build a simple counter that would determine the time when the access to a particular part of the maze would close. … Another way to make a good level design is to come up with an idea inspired by a real life process and try to model it in the level. One of the designers, Peter Englebright, came up with a most interesting level, “Perfect Match”, which was inspired by a description of bubble memory. Bubble memory was an experimental form of computer memory with a string of bits that were continuously rotating around on a circuit. He built a level that did a simple simulation of this process. You could add a bit with a clone machine or delete a bit by diverting a monster to drown."
By the beginning of March, I managed to complete 6 levels, and finished part of level 7. Level 6 introduces the dimension switch in a rather fun way – after you get the switch, there’s an ‘ambush’ (Python scripting FTW!).
For the next two months I did nothing. No work on the game, at least. I even managed to live through the first anniversary of the first day of GraLL 2 development without noticing. This was rather disappointing, but then, I did something else – I’d learnt about electricity and magnetism. And also a little single-variable calculus. While I did know a little calculus before myself, it was far from a rigorous understanding (I read the book on Calculus by Tom Apostol, the stuff in which was far more rigorous than any I’d seen before). And electricity and magnetism – I knew none (nothing worth talking about, at least). I was always keen to check out E&M (as I shall abbreviate it from now) – it’s what makes computers run at the low level. I tinkered a bit with assembly, and got as deep as reading the output from a linker and trying to understand which part of the program each instruction corresponded too. But that’s it. It never got deeper than that. The programs I wrote, were written on an abstract interface. How this actually worked in physical reality, I did not know. I wanted to read about electronics, but obviously, electrostatics, current, magnetism etc. were prerequisites. So I began to read about these things. I decided to also try giving the AP exam in May 2010 to see how well I’d understood the stuff. This was before we began studying current electricity in school, so I self-studied (the material intersected with the E&M stuff I was into). I was surprised that I managed to miss such a fascinating side of Physics. I had to read some Classical Mechanics stuff before to try and understand how to go about implementing physics in a 2d game (for the 3d games I worked on I just used ODE or Bullet). E&M however, remained untouched (in school we did just some qualitative descriptions in 10th grade, 12th grade would bring in the detailed stuff from Coloumbs Law to Maxwell’s Equations, but I had to learn this before we did so in school anyway). After the AP exams I decided to get back to GraLL 2 work. Thus, I just learnt about some basic E&M stuff – the usual highschool cirriculum till Maxwell’s equations – but never any electronic circuitry. Something told me GraLL 2 was missing me (I’d say the feeling was mutual though :-) ).
I completed level 7 (which was ‘on hold’ for two months!) and began working on level 8. Level 8 involved a ‘spinning platform’ (imagine a 2-blade propeller in a large upward facing vent). There was an intricate arrangement of bombs and keys floating above this platform (in both dimensions), and one would have to make his way through it while also taking care not to fall off the platform. Then soon…
(to be continued)