How I learn programming by building an MMORPG from the ground up 7 times


This article is also published at Medium and dev.to

It has been twenty years since I started programming. Today I want to share the story of how I learn to code by building an MMORPG from the ground up 7 times since I was 12 years old. Sounds crazy? Yep, that’s how I did it. It all starts with an MMORPG I like a lot while I was a kid, it’s called Lineage.

Back in my day, it was the most popular online game in Taiwan, and surely the most popular one among my classmates. The game was designed to always be exponentially harder to get to the next level from the previous one. As a 12 years old kid, I didn’t have time to get to the top level. So I talked to myself:

Well, since I cannot get to the high level in the game, why not make one myself? So that I can be the god in the game, I can do anything I want with by typing a command!

This motivation doesn’t sound creepy at all until I watched an episode of Black Mirror on Netflix.

A clip from of Black Mirror from Netflix
A clip from of Black Mirror from Netflix

Challenge the final boss when you are level 1

You don’t say, building an MMORPG as a programming beginner is like challenging the final boss immediately when you are level 1 just out of newbie village. I realized I have no clue how to build it. Fortunately, for what I’ve learned from playing RPG – if you cannot beat a boss, you go around to kill easier monsters, level up, gear up and come back to try again later. So, I did. The first language I learned was Visual Basic 6.0. I picked up basic things like if statement, for-loop, how to open a file, how to put a control on the form, how to add an event handler.

Later on, I learned how to use Winsocket control to open a TCP socket and communicate between two programs. It was like a new lego brick in my toy box.

Now I know how to make an online game! Maybe I can start building the MMORPG already?

Oh, not so fast, I don’t know how game graphic stuff works yet. I only know how to build simple controls in the VB form. So I wonder what I can build with what I’ve learned, then an idea came to my mind.

What about an online Chinese Chess game?

I put all the knowledge I had together and built this Chinese Chess game. I uploaded it to a popular freeware download site.

Screenshot of VB6 Chinese chess game I made
Screenshot of VB6 Chinese chess game I made

Surprisingly, many people downloaded and played it. Some of them even wrote me an email to report a bug or request a new feature. I was proud of what I managed to build as a kid. Around that time, I also explored and learned many different things, like how to build a website, how to upload your Perl files into a folder call cgi-bin, and you need to change the permission to 0755 so that it runs.

It turned out I knew somethings. However, this is still very far away from building an MMORPG. Then, I started to learn how to make a game. I bought books about DirectX, read tutorials online, learned how to read MSDN. Eventually, I start building this game. I managed to make something like this:

Screenshot from my ugly MMORPG in VB6
Screenshot from my ugly MMORPG in VB6

Yep, it’s funny to look at it right now. As you can see, it’s ugly. If there’s a contest for the ugliest MMORPG in the world, mine could probably take place.

No others to blame

As a student, I spent most of my summer and winter vacations building this game. After that, I went back to school and waited until the next vacation so that I have enough time to focus on building this game. However, when the next vacation comes, guess what?

😱 OMG, who wrote this 💩!?

I said that to myself, when I looked at the source code I wrote from the previous vacation, I had no clue what I was doing there. The code was a mess. There were bugs everywhere, and it barely works, could crash at any moment. It was impossible to add anything new on it. This was not the worst part, do you know what the worst part is? Well, since I am the only one working on this project, I had no others to blame. 😅

I felt sad, had no choice but needed to throw alway the whole project and build it again from the ground up. When I was building the first version with Visual Basic 6.0, I knew to get the best performance, C or C++ is a better choice. Also, I don’t like the fact that to distribute a VB6 program requiring you to install a runtime package. Therefore, I started my next rebuild with C++.

I talked to myself:

This time I will make it right!

I use the new tricks I learned during school time by reading a book or building some smaller projects. I learned some more stuff comes with C++, like pointer, memory management, MFC (Microsoft Foundation Class Library) for building map and resource editor. Soon, I made another version:

Screenshot from new map editor of MMORPG v2
Screenshot from new map editor of MMORPG v2

Besides this map editor you see here, I also made resource package editor, client, and server. And you know, vacation is always short. But at least, I was happy with the progress I made, I thought:

Damn, I am a genius! 😎

Then I went back to school.

A clip from of Black Mirror from Netflix
A clip from of Black Mirror from Netflix

Not again

A few months later, when the vacation comes again, you already know what happened.

A clip from of Black Mirror from Netflix, a girl is running away
A clip from of Black Mirror from Netflix

Here we go again. When I looked at the code I wrote, I felt shame to admit – I wrote all this.

I am an idiot. 😭

So I tore the project down, and start over again. I repeated this process over and over. At some point, I even lost count. I thought I rebuild this project like 7 times. I recall the last attempt was using C++ for low-level high-performance needs, and Python for high-level gaming logic. Here are the screenshots from different versions

More screenshot from of later version MMORPG
More screenshot from of later version MMORPG
More screenshot from of later version MMORPG
More screenshot from of later version MMORPG
More screenshot from of later version MMORPG
More screenshot from of later version MMORPG

I ended up spent all my middle and high school vacations rebuilding this game. In the end, I never finish it, but every time I rebuild, I learn so much from doing this. I learned how important it is to make good architecture design and good code structure. Otherwise, the code gets messy, and soon, you won’t be able to add anything. I learned how to write efficient code, how to squeeze every single bit of performance out of CPU. Like using integer is faster than float, use bitwise operation as much as possible. I knew memory allocation is expensive and learned how to avoid them. Learned weird tricks like loop unrolling, and some useful tricks like pre-create a table and lookup value to speed up some expensive math functions. I even learned how to use many design patterns myself before I read them from the book, such as observer pattern.

What I’ve learned from this

Before I went into undergraduate school, I’ve already been programming intensively for six years. This is how I learn programming the hard way – teach myself everything. This may sound like not a big deal, just a kid spends after school time on programming, but in reality, it’s actually countless sleepless nights thinking about how to solve the hard problems, hitting your head against the wall all the time. Oh, not to mention, I had to learn English at the same time so that I can read all the materials online. I had to read the document slowly by checking dictionary word by word. From time to time, it’s incredibly frustrating.

However, I don’t feel regret I did this, even I didn’t finish the game. In the opposite, I felt grateful I spent my time on this project since it’s super beneficial for my journey later as a software engineer. It’s also very rewarding from seeing something I want to build becoming a reality. Most importantly, I’ve learned meta-learning, which means I know how to teach myself anything I want. That gives me the confidence to challenge myself further later on.

All in all, there are so many lessons to tell, I think these could be also beneficial for people who are on the same journey to be a software engineer, here’s a few of them:

If you are not making a crazy amount of mistakes, you aren’t trying

It’s totally normal that you make many mistakes when you’re learning from build something. In fact, I think if you are not making a crazy amount of mistakes, you probably aren’t trying. Mistakes are your best teacher.

For example, I recall when I was working on a WinSocket handler interface part of the game, there was a really really bizarre bug I encountered. It took me a long time to figure out what happens there. Basically, based on what I recall, there were few lines of code for networking handler interface definition like this

class SocketHandler {
public:
    // 呼叫此函數時代表連線成功
    virtual void onConnectionSuccess() = 0;

    // ...
}

As you can see, I was writing Chinese for comment, in case if you don’t read Chinese, it says

Calling this function means connection succeeded

And the strange thing here is, the compiler of Visual C++ 6.0 keeps throwing an error saying that onConnectionSuccess definition cannot be found. Hey, you can read the code right? It’s just right there!

Guess what, it turns out that the Chinese character “功” in Big5 encoding (UTF-8 was not even a thing by the time I wrote it) is actually composited by two ASCII, and the second character is “\”. And as the compiler was built only to handle ASCII, so to the compiler, what it saw was

class SocketHandler {
public:
    // something something ...... \
    virtual void onConnectionSuccess() = 0;

    // ...
}

The final backslash extends the comment to the next line, that’s how VC++ 6.0 compiler behave (for other compilers, it seems not like this case). With the experience from this hair pulling mistake in mind, I made a decision. I pushed myself to stop writing comments in Chinese, write in English instead. This means I need to check a dictionary every single time I write a comment, definitely not easy for me at least from the beginning. A few years later, when UTF-8 gets adopted more widely, I used it immediately thanks to the pain I experienced.

This example was just one of the countless silly mistakes I made, and it taught me so many things

  • Different compiler behaves differently, and sometimes there could be a bug
  • Big5 encoding problem
  • Stop writing comments in Chinese
  • Use better encoding system like UTF-8 whenever possible

Mistakes are indeed the best teacher for yourself. So I would encourage you, don’t be afraid of making a mistake, and every single time you made one, you should learn from it to avoid making the same mistake again. Then over time, the more mistakes you made, the better engineer you become. I was lucky to have this project, but in the real world, it’s not always safe to make mistakes. Say you are building a launch system for a rocket with human on board. Certainly, you don’t want to make anything goes wrong. Therefore, to be able to learn quickly, it’s essential that you create a safe to fail environment for yourself.

Take a hard, really challenging project to build

Building something easy won’t give you too many chances to make mistakes and learn. I know this is route is difficult and not for everybody, and it takes a certain level of grit. However, if you can, I would suggest you take a challenging project to build if you want to learn programming the hard but productive way. A good challenging big project may look like this:

  • Large scale, involve many components, like server, backend, frontend, etc
  • Can start from small, and extended to bigger (like MMORPG, you can build client first, then add map editor, server, and other things)
  • Really hard to build, involve many unknowns ahead
  • Safe to fail

Aim higher, you can learn more. And remember, even if you fail, so what? You would have learned so much from it, and that’s your assets to keep along the road.

Detour when you hit the wall

While taking on a challenging project, there must be a time you feel hitting the wall. Don’t worry, as I said, think of it’s like you are facing the final boss when you are only level 1. You just need to level up and gear up, then come back to rechallenge it later. So I would say you could detour when you hit the wall. Build something smaller and more comfortable to learn the required skills and knowledge. Think it as like divide and conquer. Say you need networking knowledge, then go ahead and build a small networking project to learn it. You need graphic rendering skill, go ahead and acquire it from another small project.

After a while, with the new skills you learn, it would be like an awesome new weapon you got in your item bag. Now, with the shiny new sword, you think this time you can beat the final boss, and can’t wait to give it another try. Just go ahead! Don’t give up, and be patient, give it enough time, you will eventually conquer the final boss.

Build something long enough to see your own consequence

It’s very critical to build something for long enough time to be able to learn critical engineering lessons. Usually, in school, you don’t get a chance to build and maintain a long-living project. Think about it, the homework assigned to you, once you finish it and get a score A+, have you ever worked on it again? The problem is, since the project is short living, no matter how you build it, as long as it works, nobody cares.

In real life, the life cycle of a real software project begins after you finish it. There will be new feature requests and bug reports. Then you need to implement and fix them. When you make a poor decision, you or other people will feel the pain later, in the long run. There’s a consequence of your action, but very often you may not be able to see it. It could be the poor girl or guy who takes over your project after you’ve moved on to a new position.

All in all, to learn many essential engineering lessons, you need to keep building something long enough to see your own consequence. And it needs to be you to face and deal with the consequence, not someone else.

Wait long enough to forget what you did

One of the many reasons I can learn this much from my own code is because I forgot many details of my code after I stopped working on it for a whole semester. This is really important as if you still remember how your code works, you won’t be able to read it like the code was written by someone else. And after you just finish the code, you usually feel good about what you did, you will be blind to the mistakes you made and the ugly code you wrote. But if you wait long enough and forget the details, when you come back and read it, you will realize how good or how bad it is.

After all, it’s your own code, if you cannot even read it, nobody can read it.

When you think your old code sucks, you are making progress

It has been too many times, when I finish part of the code, I felt confident and proud of what I’ve done. But a while later, I come back and see my own work, I saw so many stupid mistakes I made and felt terrible about it. At first, it’s always very upsetting to see your own problem, but later on, I realized when you can see your own problem, and you know a better way to do it now, it actually means you are making progress. Since then, I don’t feel bad about the horrible code I wrote. I know it’s not perfect, I know it’s ugly, but it’s just a proof of I am making progress on my journey to be a great engineer.

In the end, we are all mortals. It’s our nature to make mistakes. And as long you keep learning from the mistakes you made, you are making progress. You should be proud of the number of mistakes you made.

Finally

I think I was extremely lucky to be able to find out what I love to do in the rest of my life and had enough time to work on big projects, also got access to computer and internet when I was a kid. I know this route is never easy and could feel lost from time to time. With the experience I gain in the two decades, I want to help people, by writing a book I wish I had twenty years ago, for you, like me, who enjoys programming and thinks about dedicating their time pursuing to be not just one, but a great one. Because it’s not easy, I name it Rough Road. You can buy it from the link at the bottom of this article.

It’s still in the early stage of writing. I am adopting lean publishing model here. Which means this book is published when it’s not complete and sold at a lower price at very first. Over time, when I add more content to the book, and I will raise the price correspondingly. For the readers who bought this book early, you can enjoy your early bird discount while there’s more content added later on. Feedbacks are welcome since the whole point of leanpub publishing model is to collect feedback early on. Please also feel free to let me know if there’s any topic you want me to cover.

Finally, I hope you enjoy my crazy story of learning programming and found it helpful 😊

Recent articles:

CADing and 3D printing like a software engineer, part 1 - baby step with an overengineered webcam raiser
How I discovered a 9.8 critical security vulnerability in ZeroMQ with mostly pure luck and my two cents about xz backdoor
High-speed 10Gbps full-mesh network based on USB4 for just $47.98