On Game Design

Standard

I haven’t done much coding for the past couple weeks.

There are a couple bugs to squash for the mesh generator. The algorithm needs some work to reduce the variance of triangle sizes, which is causing lighting problems. These are minor things, it is mostly done and honestly, most of the time it looks amazing. I don’t have a video of the latest incarnation right now; if you are a reader who would like to see it, post in the comments =) I don’t think I have a large enough reach though, I write these posts mostly for myself. (It does feels great when others enjoy what I write)

Getting to this point made me reach a sort of existential crisis. I knew my intention was to create a game, but suddenly I had no idea of how to make a game out of this mechanic. The obligatory question popped up: Should there be a game? I decided I needed to learn about game design. It took a lot time spent reading and researching and even more time spent doing other things to clear my head. The results were not what I was expecting…

Continue reading

Rolling my own renderer was a good call

Standard

Last week I wrote about the mesh generation algorithm in my game. This week I have focused on working on a 3d renderer that is compatible with OpenGL ES. I have had more social life than what is good if I want to meet my deadline for First Demo.

Creating my own renderer was a good call. As I have said, I am not going to need fancy subdivision data structures. Also, thanks to this decision I have learned a lot of stuff that is relevant to the core mechanic of the game. I feel like I don’t need to say this but it also has been almost too much fun.

The design is going to probably change after I get feedback from the first demo, but one thing is probably set in stone: The core game mechanic is to generate atomic 3d objects out of finger gestures. This means that when the player touches the screen, the game code needs to infer a 3d position out of a 2d screen coordinate.

This was a very fun problem to solve. You can’t invert a projection matrix and even then you shouldn’t invert matrices. The solution is a simple function that, given a point inside the screen and a depth value, returns a point that is inside the view frustum at ‘depth’ distance from the near plane. When this point is projected to the screen, you get the original screen point.
After that, converting to object space is a matter of doing every step that the shader does for the camera transformation, only backwards, and in the CPU.

I started with a standard FPS camera, but then realized that for this kind of application another type of camera is more appropriate. The current camera is defined by a “center point”, a “distance from that point” and a rotation vector. The purpose is to have the camera always focused on an object to make creation of new objects easier. An advantage of this is that the “distance from the center vector” is a pretty decent value for the “frustum depth” when inferring 3d points from 2d gestures. This means that when the demo is running, new objects will be very close to the current, focused, object.

All this object-space-to-screen-space and back code was easy to write because I had all the concepts fresh in my mind. If I didn’t write the rendering code I would still have had to do a lot of research. I also believe that everything is going to end up being more efficient because I am allowed to make a lot of assumptions that, say, OpenSceneGraph is not allowed to make. Things like knowing that the near plane is z=1 and that the frustum is symmetrical give you some small performance benefits. A more significant factor for performance is the complete control that I have over every part of the path from user input to OpenGL calls. There is nothing being computed that doesn’t need to be computed. That would not be true for a more general purpose pipeline.

Another cool thing: The other day I was thinking “how the hell am I going to do the texture mapping after I have a 3d mesh?”. The answer was obvious: I already have it!. I am not creating anything 3d until the last minute. At the last minute what I have is a 2d triangulation and a vertex-height-map. The 2d triangulation is a pretty good UV mapping of the final mesh =).

As for the actual texturing, I think I will just use Perlin Noise for now. Perlin Noise is very good for Wood materials and extremely good for Cloud materials. Dirt is going to be easy. A simple bump map (also Perlin Noise), a brown texture, and high specularity is going to make it look awesome.

I think basically everything in this game is going to have Perlin Noise…

By next week I think I will have a pretty cool YouTube video full of mesh generation goodness. If not, I’ll just write about Emacs 24 or something.

Devolve: Part 1

Standard

I have been writing a program for a couple of months now. It started as something else but now it’s turning into a game.

First: Video time:

When I used to do 3D modeling and animation, I remember being fascinated when I stumbled upon Take Igarashi’s T.E.D.D.Y. Years later, after I decided I wanted to be a programmer, I attempted to write an implementation. It wasn’t that long ago, but I didn’t have the programming chops to pull it off and I failed miserably.

My second attempt started in November of 2011; about two months before my internship at Google (of which I intend to write a huge blogpost when I know what points I can convey without burning any bridges, especially since I intend to compare my experiences at both Microsoft and Google). These series of posts will be solely a devlog on the most fun project I have ever worked on.

The Idea.

I wanted to make a “Modeler for the Masses” based on Teddy’s paper (freely available and excelent). I don’t even know if Takeo’s paper was the first but I later found out that this idea has already been explored; it is called Sketch Modeling and I assume that it hasn’t been very succesful. I haven’t looked into it further.

My idea is to bring auto 3d mesh generation from 2d shapes to the tablet and smartphone as a core game mechanic. I didn’t want to make a game, especially since I intend to sell this, but this is what I want to work on so this is what I’m working on. It’s too damn fun.

The initial, very mutable, idea is a terraforming sandbox game. You start with nothing but a horizon (with maybe an ocean). And you create your world using some “elements” like cloud, earth or wood. Think of inception’s limbo. Unconstructed dream space.

But before I speak of the fun bits, I want to say something about the money part.

First off, I chose the name for my “studio” (aka me): devolve_inc. It sounded cool. Bought a domain and everything. I even attempted to make a website but I soon realized I was just stroking my ego…

I bought “The Lean Startup”. A really hip business book. I’m not a business guy but I have to become one since this is a one man operation (even though I tried my best to recruit friends). I liked the idea of extremely fast iteration. Even though it is a short book I feel like the main ideas, like the concepts of pivoting and learning could be put in a smaller package. At first I didn’t think this development method could be applied to games. Games, to me, were works of art done in seclusion by a team or individual and then released to a violent environment where it might not succeed. That is why I was afraid of working on a game for profit. Then I thought of Minecraft. Minecraft was developed in an open an continuous fashion. The user base was huge by the time v1.0 was available. Even now I think Minecraft is always changing (I quit after I actually forgot to eat for a whole day while playing it and realized it would eventually kill me). I think games without stories can use the methods in the book easily, not as much as a web app, but easy enough on an environment like the android market, where apps update automatically. This is why I chose Android as my first target: no app review process so I can launch an unfinished product and iterate with feedback. I also chose C++ as the implementation language; I didn’t want to at first, but it really is the only sensible choice for this kind of project. Python + Kivy was another consideration but speed was a concern. A couple days ago I met a game programmer on Google+ who is rewriting the code of his hobby game from Java to C++ because of performance problems. I don’t want that to happen to me. C++ is also the language I know best so it’s not so bad. I have a love-hate relationship with C++. Right now I’m tending to “Love” so I won’t rant. Eventually I will hate it again and I will dedicate a post to C++ hatred. Like any long-term relationship, there are problems and it takes work to make it work.

The fun stuff.

Mesh generation is almost done. It’s essentially finished but it doesn’t look like it because it is still an orthographic projection. I’m working on a 3D renderer right now. I debated with myself on using a middleware engine, but there were enough reasons against it that I chose to roll my own renderer:
*) Portability: I am targeting Android, iOS and development is being done on a linux box.
*) Requirements/Features: A third party engine might be used for a FPS or a Flight Simulator or anything else, the needs of my game are very basic. For instance, I don’t think I need fancy space subdivision data structures for the first version of the game. Also, the nature of the game calls for code that moves between Eye coordinates, World coordinates and Screen coordinates with ease. I feel more comfortable knowing that I have complete control.
*) Fun: It’s just fun. I’m on a self-imposed deadline but I am a hedonistic programmer.
OpenSceneGraph is still an option I haven’t ruled out in case that writing a custom scene manager and renderer proves too much of a burden.
I am using the Armadillo library for Matrix math but I have my own unnecessarily-optimized-with-SIMD-extensions classes for 2d and 3d vectors for the mesh generation code.

Mesh generation closely follows the Teddy paper; the paper could be more detailed on the mesh creation section. For example, searching for “Chordal Axis” got me topology and biology results and it wasn’t well defined in the paper as far as I recall.

The idea is to take a 2d stroke that is not self intersecting as an array of mostly-equidistant points, create a Delaunay triangulation and then subdivide it using a skeleton that is very easily derived from the triangulation (that’s the chordal axis).
My implementation is a simple incremental Delaunay algorithm. Theoretically this algorithm is O(n^2) but in this case, the guarantee that contiguous points are next to each other makes point location really really efficient (Thanks to my friend Jason Bandlow for realizing this; I was too dumb to see it). Thanks to practically-constant point location, on the average case the algorithm is O(n). This is awesome. Without excessive optimization my algorithm’s bottleneck is now the STL’s hash table implementation. I can optimize further but I won’t until there is a real need.

The subdivision process consists of adding points along the inner edges of the triangulation. The z-values of the new points are calculated with an ellipse function that depends on the length of the edge. This means that wider parts of the shape become fatter and thight parts become thinner.

I didn’t follow Teddy’s paper to the letter. I am not subdividing manually. After knowing the location the new points, the algorithm just retriangulates with the original boundary points and the new interior points. This is all 2d, but the creation keeps a height map that is used to create a 3d-mesh really quickly after re-triangulating.

The subdivision is not always clean. There are some inputs it likes and some that it really hates. Sometimes there are triangles that are too big, and sometimes some triangles are too small. Sometimes both. I know how to make it better; in fact, it’s in the design and it has not been implemented. Right now the subdivision is good enough that I believe the end-user won’t notice if the triangulation is not beautiful or uniform. If the difference in triangle size causes rasterization artifacts then I will go ahead and implement the mesh-refining part of the generation algorithm.

This is what I have. I have a long way to go but I have some very smart people that I might convince to help me =)

First Week at Microsoft

Standard

My first week at Microsoft was great!
This should have been my second week; but due to some immigration issues caused by my stupidity I had to go to San Diego, cross the border to Mexico and back again in order to have a J-1 status… Long story short: all is fine but I’m starting a week late.

Most of my time was spent in meetings and setting up my environment; which is a pretty complicated process here at the Death Star.
I found my first bug and got to write my first line of code on Friday, which is pretty good.

Most of what I am doing I can’t talk about until PDC, which will be in September. But there is still a lot that I can blog about.

I get to code graphics (and other) stuff in C++.

First of all, I haven’t done any real Windows programming before in my life. The closest I had gotten was to compile under Cygwin or actualy using msvc but emulating Unix as much as I can. I had to learn about how Windows applications are made.

Second of all, I am working with some new APIs. On the plus side, there will be thousands of programmers using these APIs in the future and I am one of the first guys to actually use them (and hopefully find as many bugs as I can in the process). On the down side, there is virtually no documentation. There are specifications and code comments, but other than asking the guys who are actually working on this stuff, there are no other references.

I am very excited about the fact that the impact of what I’m doing will be very tangible.
Most days I have been working 10-13 hours. In part because I wasted a week and in part because I love being here and I am very excited about my project. I am drinking way too much soda though, it’s free.

I am very lucky. Besides getting a job here, I got the perfect role for me. Most of my work will be in graphics and if I do everything right, millions of people will use what I am writing. My brain is still trying to get that to sink in.

I haven’t appreciated the city as much as I would like; but once my first paycheck arrives, that will change. That doesn’t mean I haven’t gone out. I got to see a play: “The Agony and the Ecstasy of Steve Jobs”. It was 2:30 long but it felt shorter. It was mostly hilarious. I would definitely recommend it if you get a chance.

I have been to Pike Place Market and I have walked around the Space Needle. I got drunk with my roomies and I also went to a couple of bars. That’s more than enough for two weeks considering I have no car and a small budget. The highlight of it all thus far has been compiling Windows (or, more accurately, the part of Windows that I need) and working in a beautiful office on the kind of stuff that I would be doing at home for free; only in Seattle, with a guarantee of huge impact, and getting paid.

First day in Redmond

Standard

My internship starts next Monday and I arrived yesterday, which was a Tuesday. I have plenty of time to do anything I want as long as it doesn’t involve spending a lot of money, driving, or walking too much. Today a friend invited me to have lunch in one of the Office buildings. It’s incredible. Free drinks, pool tables, air hockey tables, arcade games, lots of whiteboards and ethnicities.

My apartment is beautiful. My roommates are not here yet so I have the desk all to myself. We have a fireplace, a TV, washer and dryer (you know you’re a spoiled brat when you have to google “how to use a dryer”…) and everything else you need except for dish soap. I need to buy dish soap.

The only problem is that I can hear everything my neighbors are doing. The neighbor above me either has a gigantic bipedal dog or a very obese hyperactive child. I don’t know, but someone is running all the time.

This also means that my neighbors can hear everything I am doing. They will hate me once my guitar gets here.

Now I am off to downtown Redmond to buy a toothbrush, underwear and food.

Interviewing for a Microsoft Internship. Part deux.

Standard

I got the job!

All in all it was an amazing experience. Even if they hadn’t hired me I still would have been pretty happy (I was saying that before I had the offer). I got the chance to have dinner and talk about programming with extremely bright people. I met really nice and smart people from my own country and now we are going to be working at the same company; most likely not on the same team/group, but still…

I went to Vallarta for three days. My dad, who is a businessman, made a “business meeting” in Vallarta so that he could be with me.

The hotel didn’t give me room right away so I stayed at my dad’s room studying. I was pretty paranoid so I was making sure that I knew all the stuff I put on my CV as deeply as possible. When I was taking a smoke-break next to the window, I saw other interviewees chilling out. Having some drinks and spending time at the pool. In retrospect, that is how I should have spent the day. Nothing I studied during those hours directly helped during the interview. It may have helped my confidence but I should have just relaxed.

We were invited to have dinner with the interviewers the night before the interview. We were told it wasn’t an assessment. I still had the suspicion that there were ninja interviewers taking notes on our behaviour. There were three tables set up and I chose the one John Guin was sitting at. Both because the prettiest girl was sitting there and because John was hilarious. Turns out my choice of table was pretty good since Mike Fortin came to our table and sat next to me.For the next couple of hours I had a great time talking to Mike and John. Topics included what’s it like to work at MS and their backgrounds, we even spent time talking about the version control system they use at Microsoft. Mike made quite an impression on me when he said “I’m the one to blame for Windows Vista”. He is in charge of the team that is responsible for Windows being fast. Hardcore stuff.

I took the risk and told them that MS Paint sucks. Fortunately they agreed. Not only was the dinner delicious and the conversations interesting, but I made a good impression on Mike which helped me when, praise Zeus, he ended up interviewing me the next day.

I returned to my hotel so excited that instead of sleeping I spent a couple of hours at the bar with my dad, his friend, and a bunch of drunken Canadians.

My interview was supposed to be at noon, but they moved it to 7:30 am a couple of days prior. I only slept about 4 hours but the adrenaline of the next day was enough to compensate. The Microsoft guys were nice enough to get us breakfast at their hotel since ours didn’t serve until later. The interview began at 7:30 sharp.

We were taken to a room within the conference center. There were cookies and soda. Within a minute or two a small army of interviewers came into the room calling people by name. Slowly, pale students and recent graduates were standing up.

I had four interviews. All of them consisted of around ten minutes of talking about my interests and around 40 minutes solving a coding problem. There were no whiteboards in the conference center rooms so the small point markers I bought were pointless (no pun intended). We wrote code on paper. I always kept in mind all the tips I read from the Internet.

Donna, my first interviewer told me that Manav, the guy who interviewed me in Mexico City had put in a very good word for me during dinner. That was a tremendous boost of confidence. She made me write an algorithm about returning a sorted linked list from two sorted lists. It was pretty easy but I chose C so I could show her that I knew how pointers work. She gave me some tips and we wrapped it up.

My second interviewer was named Bambo, and he started off telling me that with my math background maybe I could find an formula to the solution of an algorithmic problem involving consecutive letters in a string. I spent a couple of minutes thinking and I found a solution only to realize that I hadn’t understood the problem correctly. He posed to me another problem and I went on to try to find a formula for the solution. I realized too late that this time what he wanted was code.

Realizing I made two mistakes in a row, I told him “damn… I’m not doing well”; he just laughed and told me that the point of the interview was to find out how I think.  He changed directions and asked me how I would test a dialog box. Then he asked me how I would test Notepad. One thing that made me feel good was that he complemented me on not giving up on a problem. Still, my confidence dropped after the interview. I didn’t feel like I had done well. The disappointment didn’t last long. I found out that Mike was my next interviewer and I got excited.

Mike started of telling me that I asked some good questions the night before; again, confidence boost. He asked me if I wanted to go right ahead to the coding but I was a bit tired so I told him to ask me some questions first. He asked me what was my favorite program that I have written. I told him about an Internet proxy I wrote to substitute all images in websites for a picture of myself on my mom’s computer (For instance, instead of the google logo, there was a picture of me doing a stupid face). He laughed, but clearly he wanted me to tell him my most challenging program. I told him about the shadowing in pycave. It was the first time I had to buckle down and read research papers, learn a bunch of stuff and then implement it. Programming smart tricks with OpenGL’s fixed function pipeline is not exactly an easy skill.

The problem I had to code was to determine if a matrix had a copy of a smaller matrix within it. After I finished, he told me if I had any questions and I asked just the right question to get him to ramble for 10 minutes about some awesome stuff his team is working on; very interesting.

When I returned to the main room, there were only two guys left. Most of us just had 3 interviews. Of the ones who had 3 interviews, they only hired one.

My fourth interview was with a guy named Nar. I was worried that having a 4th interview was a bad sign, but he told me that it was actually the opposite. That meant I was doing well, so I got a confidence boost again. He works on device driver architecture for Windows. He asked me about Haskell and then he asked me to find an algorithm to find the largest palindrome within a string. After staring at a piece of paper for a couple of minutes he told me that I could find a solution in O(n^3), O(n^2), but he didn’t expect me to find the linear solution. I found a quadratic solution but it took too long to write and we didn’t have time to test it or for me to ask him questions. He did ask me some questions that made me think I was getting hired.

When I was waiting in the room for the last time, I was drinking coke and smoking my nth cigarette. Suddenly I heard my name and nervously walked to the aisle. I saw my recruiter and my four interviewers waiting to congratulate me. They gave me a t-shirt and they gave me an offer. My heart was pounding . It was one of those moments that really engrave themselves in your brain.

Tips for the interview.

I asked them during dinner what is it that they’re looking for in candidates. Mike told me: Intellectual horsepower and passion.

This is subjective but I believe this is what helped me:

Be methodical. Understand the problem. Plan the solution and *then* code. I did this in all interviews but the second, the only one I felt didn’t go well enough. I got complemented on it. It is important. Example: My first problem was about linked lists. The problems are going to be ambiguous so they can tell how you think. Is the list composed of integers? Can I destroy the original lists to save memory? Are the lists terminated by NULL? Can they be circular? (you don’t want an infinite loop!) What happens if the function receives wrong data? Say, a Null pointer instead of an allocated node? There are a lot of things left undefined behind a simple definition and they are absolutely vital to give an adequate answer.

Show passion: I made a good impression by having projects of my own and by getting excited when talking about programming. I don’t think you can fake this.

Don’t worry about statistics. There is a lot of luck involved. I got interviewed by the right people. It is likely that a different subset of the interviewers wouldn’t have hired me.

That’s pretty much it.
As for the actual internship, I will blog as much as I legally can about my experience the next summer =).

P.S.

I edited this post because I realized I didn’t write it as well as I could. I’m still not the best writer, but I had written this in a hurry. The original content is intact, I just made the presentation better and added a little bit of extra content.

Interviewing for a Microsoft Internship (Part one)

Standard

I haven’t posted anything in quite a while now; I figured this is a good time to start writing again. It was not an uneventful year, but I didn’t feel like writing.

A couple of months ago I got an email sent to the CS students at UNAM about Microsoft recruiters coming to interview people who wanted to do an internship. The day before I spat out a résumé and decided to go. They did a presentation and asked some coding questions to the audience. Some guy got a Zune for answering something. I got a frisbee for participating…

A mexican Microsoft employee talked with me for about 30 seconds and then asked me to write code on a piece of paper to recognize a very simple regular expression. When I finished, he told me that I shouldn’t have used pseudocode. That if I made it to the next interview, it could kill me.

I didn’t feel very confident; wasn’t sure if I’d make it to the next step.

I got an email a couple of weeks later asking me to go to the Microsoft Mexico offices to be interviewed by someone called Manav. The interview, during which I had to write an algorithm to check if two rectangles collide, lasted around 25 minutes. Since I like making games, I have written that thing a thousand times; still, I got nervous and screwed up one of the cases. He told me and I had to correct it.
The interviewer was really nice. I told him that I recognized him; that I had googled him (In retrospect, maybe it would have been better to say I binged him =P). He asked me if I had any questions and all I could think to ask was “How did I do?”

It took them a while (more than a month) to send me an email. An hour ago I got one inviting me to Puerto Vallarta to be interviewed once again next week. I wasn’t sure about it, since I told him that I was a graphics geek and then had trouble writing in the whiteboard one of the most common things to write in graphics. Still, I landed the interview and I am feeling confident that I can do well.

It is the last week of my school term, so this means that starting today my time will be mostly spent practicing Topcoder problems, and not so much studying and doing homework. I may have to speak to a teacher to take the exam/turn in the homework after the interview.

I really hope to get hired. It would be an amazing experience.