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