Making ReelValley - Overview
Recently the team which I am proud to be the part of released a new game named Reel Valley. The game is done in almost 100% pure Nim and I’ve received a lot of questions regarding implementation details and decisions taken. Questions that inspired me to write this first article in my blog :).
The development started in late 2015 and that was the time of many strategic decisions.
Being a person who never stops seeking for better technologies (that is how I like to think of myself ;) ), I’ve been searching for a better language than C++ for a very long time. After learning and trying lots of the well-known languages and no satisfaction I’ve switched to less mainstream ones. Among them were D, Rust, Crystal, some others, and Nim, which I’ve suddenly discovered on Github. I shall not describe all of the pros and cons here, just those that were the key factors in our final decision.
Compiler bugs. Lots of bugs that either needed to be worked around or fixed. What if the core maintainers will not fix those for us timely? How hard would it be to fix those ourselves. And if there are some bugs that can’t be fixed in a timely manner, how hard would it be to workaround those? And Nim has successfully passed that evaluation. 2 simple reasons:
- Nim compiler codebase is rather concise and comprehendable for the most part, despite highly sophisticated stuff it does. Overtime we have contributed quite a bunch of fixes and features.
Community and available third-party packages. What if there’s no package available in Nim that we suddenly need, while in a mainstream language you can easily find dozens of libraries that do the same thing. Can we implement the needed packages on our own, and if not, how easy it is to bind to a lib from a foreign ecosystem? And the answer is YES again.
- Productivity that the language offers is extremely high, the needed parts can be reinvented much faster than, say in C++ or a typeless scripting language.
- It turned out to be very easy to bind to existing C/C++/JS code, be it in a static lib, dynamic lib, C header file, or just copypaste the needed code and inline it, no strings attached.
So after all risks considered, we have started, there were huge wins and small losses, and I still think that the choice was right, and I’m not leaving Nim anytime soon. It is simply brilliant.
Technical Insights of the Game
For those interested in what libraries we are using. There are around 60 direct and indirect dependencies in the client and around 20 dependencies in the server. Thankfully, nimble package manager installs those with a single command. And Travis makes sure that at least our packages are working properly with the actively developed ecosystem. The core of the game is nimx and rod. There are around 15 other libraries that we developed along the run, such as jsbind, preferences, nimongo, nimsl, and others.
I’ve been asked a question about Nim JS backend, whether it is good or not. And the answer is yes, it is pretty darn good (especially with closure compiler), and we’re using it for our tools, but not the game itself. At some point we had to switch from JS to Emscripten, just because Asm.js is much faster, and thanks to Nim the transition went pretty quickly. Hopefully we shall soon support WebAsm target as well.
As it is likely clear from the post Nim turned out to be a great language for any kind of software development, be it commercial production grade software, or a couple-of-lines one shot script, not to mention the huge amount of fun you get when using it. It is very easy to do early prototypes. As you may know prototyping involves chaotic moving of chunks of code around, copy-pasting, changing the semantics of your types (e.g. I though it should be immutable, but now it looks like it has to be mutable), so at the prototyping stage you want to use some low friction language like, say Python or JS. And Nim also falls into this category. No need to fight the compiler to prove anything. But when the prototyping is done, the code is cleaned, you’re done. No need to port it to lower level language because everything you can optimize in C, you can do in Nim.
So hopefully I have answered some of the main questions. If not, ping me on the #nim IRC channel, or Twitter, will be happy to elaborate, and maybe even post more articles here, who knows :).