Knytt Stories DS
Postmortem
Introduction
On August 2007, Nicklas 'Nifflas' Nygren released "Knytt Stories", a 'metroidvania' game with reminiscences of games like "Ico". The game had a very good design, and its user-generated content was very fun to play. The game was released for PC, and some fans asked for a console adaptation. At that time, I was considering to make a simple homebrew RPG for the DS. In fact, We worked from 1996 to 2006 in our very own PC RPG, but due to many factors we never finished it. However, after playing Knytt Stories and making a story for it, I realized that it was a perfect game for the DS, with lots of user-generated content that could provide hours and hours of fun. Besides, I really wanted to finish a game - to show myself that I was able to do it. As a result, the remake of Knytt Stories, KSDS (Knytt Stories DS), was born.
What went right
- Author Support. From the very beginning, Nifflas was extremely helpful with the development of the remake. He allowed us to create the remake, and provided us with all the graphics and all the sounds of the game.
- Community Support. One of the most important factors that made the development of this remake a success was the involvement of the "Knytt Stories" community. As we were creating KSDS, we needed to recreate the world of Knytt Stories: the behaviour of its critters, the movement of the main character (Juni), and so on. On the beginning, we used videos and screen captures to analyze the speed of Juni and the behaviour of the critters. Nifflas then released (by mistake) the source code of Knytt Stories, but we didn't have the necessary tools to analyze the code (Multimedia Fusion 2, MMF2). However, when asked, the community provided us with the actual behaviour of the critters. Some of the variables of MMF2 were unknown to us, but with trial and error we solved most of the problems. The community also wrote tutorials on how to develop new stories, and we used these tutorials to know about how to manage in our remake the internal logic of Knytt Stories (e.g. flags).
- Motivation. As we were remaking an existing game, we didn't have to create any levels for it. In fact, during the development of the game, the community was creating new stories, pushing the Knytt Stories engine to the limit. Such stories were very heterogeneous: from very small stories to epic tales. As we wanted a KSDS player to enjoy as much stories as possible, we did our best to support all of them. This actually motivated us to continue the development: it was very rewarding to push KSDS to the limit and see how these tales came to life.
- Good Initial Design. If you want a house that will stay strong for many years, it must have solid foundations. The same applies to any computer architecture, including games. As a result, we took our time to develop a good design, where every element (Juni, Objects, Particles, Map entities,...) is located in its own "component", its functionality is strictly defined, and their relationships are well known. As a result, when "on-the-fly" design kicked in later in the development (aka. "I didn't consider this behaviour and/or I want to finish it RIGHT NOW!"), all changes affected only one "component", and collateral effects were basically non-existent.
- Homebrew Tools. As KSDS is a homebrew project, we didn't have access to any official Nintendo documentation / development tool. Fortunately, the homebrew community for he Nintendo DS is quite active, and tools such as compilers, emulators, and internal DS documentation are available. Of course, some things weren't perfect, but the open source nature of the underlying libraries allowed us to make the changes we needed (e.g. delete those libraries that we don't need) and to fix some bugs.
What went wrong
- Homebrew Tools. Although the homebrew tools saved the development of the game, they also were the source of some problems. For example, some errors (e.g. related to the management of the VRAM) that are visible on real hardware cannot be found in the emulator. Therefore, we needed to make the tests on real hardware, which was quite time-consuming. Besides, there was no support (at least for the tools that were available) for debugging. We took two approaches to solve this issue. If the error was located in a well-known routine, we debugged it in a PC compiler (such as Visual C++ Express), creating "fake" interfaces to DS-specific routines. For any other errors, we created "breakpoints" and "halt" routines that could provide us with information on the actual state of the game engine.
- "On-the-fly" Design. One of the problems of home made projects is patience. This problem affected us as well, and after a certain point we wanted to have the engine up and running. Unfortunately, not all the elements of the engine were designed (e.g. sound management), and sometimes in the middle of the development we had to stop and design a new feature. Fortunately, the initial design was robust enough to support the addition of new elements. In fact, in the final part of the development we needed to rewrite the whole sprites engine in order to support custom objects, but thanks to our definition of the different components it was a (relatively) painless process.
- No Documentation. For us, one side effect of designing and implementing functionality after the initial design was the lack of documentation. The reasons were simple: lack of patience, lazyness, and "documentation-as-comments" inside the code. This is quite problematic on the long term. For example, in the week before the release, we had to fix a bug that appeared in the management of music. However, that particular library was neither documented nor commented, so it was quite difficult to find the bug and to fix it. If the bug hadn't been solved, the release date would have been delayed.
- Support for Specific Stories. As we aimed to provide support for as much stories as possible, we needed to consider specific situations (e.g. overcrowded screens) that were unsupported by the engine. As a result, we needed to include some hacks within the code to manage such issues.
- Portability. From the very beginning, we aimed for platform portability. That is, as we planned to release the source code once the game was finished, we wanted it to be easily portable to other platforms. However, although the initial design was prepared for portability (e.g. the HW sprites and the images of the sprites are considered in different libraries), we ultimately failed. There are many factors that must be considered in porting KSDS to other platforms, such as explicit calls to underlying libraries (e.g. PA_* functions), the management of the buffers for the two DS screens, the games menus, and the inherent assumption in the behaviour of all critters and elements that the whole engine runs at 60fps.
Conclusions
For us, the creation of KSDS has been a very time consuming process, but we were able to provide a finished remake that is very close to the spirit of the original game. Moreover, as the source code (written in the C language) is available as open source, it can be ported to any present or future platform. This way, the legends of Juni will be enjoyed in the future.
Development Statistics
- Development Time: 2 years.
- Human Resources: 1 designer/programmer/tester (Rodrigo Roman), 1 external consultant (Ramon Roman), many contributors (Knytt Stories community).
- Development Libraries: devkitpro, libnds, PAlib, ASlib, pnglib, zlib, others.
- Development Tools: VHAM, Programmers' Notepad, no$gba.
Last Update: February 19th, 2010