So we’re very happy to have a guest blog entry today from Peter Thoman, better known as “Durante” in gaming circles. Rather than a lengthy intro explaining why, I’ll let his own words below do the talking, so we hope you enjoy it.
Team Leader @ XSEED Games
A few months back Ken Berry of XSEED contacted me to ask whether I could do anything about the issues with their Little King’s Story port. Despite hearing good things about the game, I hadn’t really followed that particular PC version, since a lot of other titles were released around the same time and it’s not really my genre. Still, I was intrigued to see what was wrong with it, and delighted at how Ken was able to provide me with the source code for the game without too much bureaucracy.
Before going into the details of how I improved the port, I want to remark on the difficulty of this project for the original team who worked on it. After receiving the source, it was immediately clear that this was not a simple port. Little King’s Story was built on a custom engine designed from the ground up for this particular game, and its particular original target platform (the Wii). Clearly, during its development, it was seen as a one-off project that would be done once it ships, and portability or maintainability were secondary concerns.
In any case, I quickly figured out that the largest issues with the port were overall performance, intermittent stuttering, and a whole host of issues with the 60 FPS mode, and decided to tackle these in order.
First, I removed the frame limiter to more easily investigate performance issues. Even on my high-end system, I only measured roughly 80 FPS in the overworld area at the start of the game. Basic profiling revealed that it was entirely CPU-bound, and I assumed this was not going to be caused by the original Wii code, given that it ran acceptably on a ~700 MHz processor.
This assumption turned out to be correct after more in-depth profiling: the vast majority of the game’s CPU time was spent interacting with the DX9 API. I won’t go into the full details here, but the crucial point is that many individual objects induced a state change of the rendering pipeline, with its associated CPU overhead. I decided to tackle the issue by implementing various caches (for passes and materials) which prevent state changes unless they are necessary. After a bit of tweaking, this lead to a performance of around 123 FPS in the same testing area, an improvement by more than 50%. More could be done – like always in optimization – but since the game is limited to 60 FPS at most anyway I decided to move on to another issue.
On a high-end CPU, stuttering was actually a more fundamental problem than the performance overhead discussed above. While moving around in the world, every few seconds the game would noticeably drop one or even more frames. First, I thought that the culprit could be some timing issue, and while improving the frame sleeping logic helped by making the game play feel better, it still didn’t eliminate the major stuttering.
Profiling an intermittent stuttering issue such as this is far more difficult than working on overall performance. Sampling-based evaluation is almost useless, and that’s by far the most developed category of tools. Ultimately, I resorted to using Nvidia NSight and its integration library, and manually narrowed down candidates for causing stutter by marking individual regions in each frame execution. A somewhat time-consuming process, but it paid off:
In this image, the colorful stacks indicate the stutter causes I ultimately tracked down, and the lower half shows a similar sequence after dealing with the underlying issue. Note that the marked regions, which previously could take up 2 to 3 frames, are now in the 0 to 2 millisecond range. To give you a more visual idea of the improvements I’ve created this comparison video.
Issues with 60 FPS
Offering 60 FPS – or, much better, support for completely arbitrary framerates – is a common demand for PC versions of games, and one I fully agree with. In quite a few cases where it is not offered, mods later demonstrated that the effort to do so would have been very small for the developer, and that the only reason it was not provided is a lack of care for the PC version.
Little King’s Story is not such a case. There are many reasons for this, here are just a small subset of them:
- 1. The game does not have a unified system for handling time or animation speed. Many modules act independently of each other, and often time-specific information is encoded in places where it would not be expected.
2. The central NPC simulation code assumes that it can pre-compute how long it will take (in frames) for an NPC to complete an action, such as moving to another location.
3. Some bosses, enemies and scenes are moved or designed in custom scripts, which use a custom virtual machine and instruction set that is not intended to share framerate information.
My initial goal was to provide arbitrary framerate support, but point 2 in the list above makes that an infeasible goal. It would basically require rewriting large parts of the simulation, which makes up a significant portion of the entire game’s ~1 million line codebase. Given that, I shifted to the goal of making locked 60 FPS work as well as possible.
The original port fixed the speed of most NPC animation sequences, but left many other hardcoded animations, and even the gameplay-relevant time progression rate untouched at 60 FPS (resulting in double speed).
I employed a side-by-side 60/30 FPS setup as shown above, and chipped away at framerate-dependent speed mismatches little by little. In the end, I managed to fix the simulation speed, the speed of many hardcoded object animations (such as trees or grass), and the movement speed of NPCs and animals.
However, the custom scripting system used for some boss battles and scripted scenes, point (3) in the list above, still prevents the 60 FPS mode from being perfect throughout the game. However, unlike the initial release, 60 FPS is playable (and a huge improvement in smoothness) during the majority of the gameplay. As a workaround for the remaining situations, I’ve implemented a 30 FPS toggle for the 60 FPS mode, which is engaged using the “F1” key. Note that this comes with some issues due to point (2) above: animations already in progress at the moment the framerate is toggled will run at an incorrect speed until the next movement starts.
Graphics, Launcher and Control Improvements – What I Wasn’t Asked For
While working on the game, I noticed a few things which would significantly improve the visual quality and not really take too much time to implement. So I did. This include multi-sample anti-aliasing (MSAA), anisotropic filtering, transparency supersampling and a few other minor tweaks.
The most complex addition was creating an option for more shadow casters, including trees and grass. I found the lack of tree shadows a bit disappointing given that other objects cast dynamic shadows, so I added this as a (somewhat CPU-heavy) option. While I was at it I also added an option for soft shadows, to better fit with the soft dropshadows cast by NPCs.
Of course, I also had to add options for these features, and since the original launcher was not particularly extensible I replaced it with a new one. As a personal preference I also re-implemented options to be stored as XML rather than in a custom binary format, and added a lot of information about each option in order to hopefully make their impact more clear.
Finally, while playtesting the controls of the game always felt a bit “off” to me. Even though I was playing with an analog gamepad, movement was restricted to 8 directions, which in particular makes precise directional aiming (a significant gameplay component) more cumbersome than it needs to be. To solve this situation, I added support for analog directional controls for Xinput controllers.
The new version of Little King’s Story should perform significantly better on all systems, most sources of significant stutter should be eliminated, and the 60 FPS mode now provides an accurate (and smoother compared to 30 FPS) experience except in some scripting-related cases. Furthermore, the game now features additional graphics options to make better use of high-performance GPUs, and can be more precisely controlled with analog gamepads.
While I couldn’t achieve everything I initially wanted to – arbitrary FPS and even a completely perfect 60 FPS mode prove intractable for this game – I’m happy that XSEED gave me the chance to contribute a lot more directly and meaningfully to the quality of this PC port.
So Ken with XSEED again here. To celebrate this relaunch of Little King’s Story, we are running a week-long 40% off sale on Steam and The Humble Store starting right now. Though these enhancements only apply to the Steam build at the moment, we plan on applying them to our DRM-free and GOG Galaxy builds soon, so just hang tight for a little while longer and those builds will be updated too.
Thanks to everyone for your patience and ongoing support, and we hope you enjoy the new and improved Little King’s Story for Windows PC.