Kid Tripp  

Kid Tripp Nintendo Switch Development Blog

Phase 2

All is not lost!

At the end of my previous post I mentioned that I might not be as stuck without development hardware as I had initially thought. It occurred to me that any of the code samples that did not require graphics might well work just fine on my laptop. With this in mind, I tried out a couple of the samples, including one that plays audio, and they do work on the laptop, so my time on Crash Bandicoot was entirely wasted. Oh well.

I decided fairly quickly that there wasn't too much more to be gained by running more and more samples, I might as well just get on with Phase 2.

What is Phase 2?

The first area of the Nintendo Switch implementation of the engine at the core of Kid Tripp, the nagEngine, that I need to tackle is called nagEngineCore. This imaginatively named library is the core of the engine and provides the basic functionality that pretty much any application that might use the engine would need, whether that was a game or a command line tool to convert images into texture files for the renderer.

The Visual Studio project files

The first task is to set up a couple of Visual Studio project files. This should be a simple process, however Visual Studio has some strange ideas about folder structure. It likes to assume that you want your project files, all source code files, all config files, all temporary build files and the executables you build all pretty much in the same folder. Well, I don't. So I have to spend time keeping them neat.

The end result I get is a set of folders that contain the project files - one folder per build platform. I then have folders for the common source and one folder per platform for the hardware specific implementation source. Then there is a folder for the temporary build files and a folder for the final executables and libraries (each of these has sub-folders per platform). One of the big benefits of this is that it is really easy to remove all files that are generated during the various build processes if I ever need to and that it is also very easy to exclude those build folders from my source code repository.

The common source files

A good amount of the source for the engine is shared between all the supported platforms. C++ is supposed to be fairly portable and it is. This means that I can put these files directly into my new Switch project files and they will compile without any effort at all. Except that they don't. This is by design. Without going in to too much detail, source files reference header files. Header files describe what other functions are available for the source file to call. Some of the header files need to know what platform they are running on and I have made these files emit an error if they are referenced but don't recognise the platform for which they are being built.

The first file which gives this error is a header file designed purely to determine what the platform is which you are currently building for. Once this has been updated for Switch I now get similar errors in a lot more files, again this is expected. I now go through each of these files and fix them up to point to the new files that will be added for the Switch implementation.

How an engine works

The purpose of an engine is to abstract away any hardware or platform specific code so that platform agnostic code can be written that is more easily portable from one system to another. For example, if you are making a game that will run on a desktop computer and on a tablet, where the user clicks on objects on the screen, you don't want to have to litter the code with "if (onPc) getLeftButtonJustPressedIn(area) else if (onTablet) getUserTappedIn(area)" every time you want to work out if the user tapped or clicked in a particular area of the screen. You have an abstraction where you can call "getUserActivated(area)" and that function then calls the appropriate code depending on the platform. You could just abstract that out inside your game's code, but then you'd just have to copy it out to any future games. So you put it in one library and call it an engine. Then you give the engine a silly name.

Test driven development

Otherwise known as TDD, this is a development technique loved by some, hated by others. I'm in both camps, but it is incredibly useful for engines. TDD works like this: You decide what functionality you want, for example to read the contents of a text file into a memory string. You then write a test to see that you get the expected result, so you would create a text file that can be read by the test, put some text into it (for example 'hello') and write a test that calls something like 'string fileContents = readTextFileToString(filename); FAIL_IF(fileContents != 'hello');' This won't compile at this time, because you haven't written the definition of 'readTextFileToString' yet, but when you do you create it empty and just return an empty string. You run the test, the test fails, this is what you want. Now you write just enough code inside 'readTextFileToString' to get it to load that test file and return its contents. Now the test passes. You have written a minimal amount of code and you are sure it works correctly. Now if anyone messes with your 'readTextFileToString' function and changes what it does, your test fails and they know they have broken the code.

What has this got to do with nagEngineCore? Well, just about all the platform specific functionality in nagEngineCore is covered by tests. It is now very easy for me to create empty implementation files that return default values or do nothing and get the code compiling and linking in no time. I run the code and the failures tell me what I need to implement. So, that's what I've done. I now have a Nintendo Switch specific implementation of nagEngine core that I know will run on the actual hardware, when I get it, without errors.

End of Phase 2

The main bulk of the platform specific functionality in nagEngineCore is to do with data file reading and save data reading and writing. TDD paid off for me during this work, one of the tests I have in place covers what happens if you try to read past the end of a file. The Switch code did something I wasn't expecting so I had to make some changes to make it behave the same as the other platforms. Without the tests, it would have been easy to assume that the initial code that I wrote for reading from a file would have worked in all circumstances.

All in all a very productive Tuesday. I have one day left before I go on my travels for a couple of days. The next phases will cover the conversion of nagGame, which is currently the only other library in nagEngine and contains anything that would only really be useful in game projects, so graphics, audio and controller input. I guess audio will have to come first, since the other two will require the development hardware to test properly. Speaking of the development hardware, it is now here in the UK on its way to the delivery depot. I'm really hoping that this means that it will arrive on Wednesday as I am away Thursday and Friday.

Conversion Time

Time in this Phase: 6h 35m

Total Time: 9h 05m

More Pages

Phase 1
Phase 3
Phase 4
Phase 5
Phase 6