Wiebo de Wit's thoughts about game development and more…
Category Archives: How To
Ok, have you ever been in this situation? You are creating a game or application and all goes well. Still, testing new additions to the program takes more and more time, as you have to spend time to get to the new part or feature, and every little thing you change needs to be retested, so you re-compile, try and test, change, re-compile, etc. This gets more and more time consuming as your program grows. Wouldn’t it be great if you could test your new object type or changes without having to re-compile your game or application every single time? You can! With Unit Testing and TTD (Test Driven Development).
Before I go on: here is a great introduction to unit testing and test driven development in relation to games. Read it and then come back…
Back? Ok, let’s continue and let’s see how we can do all of this in Blitzmax.
First up we will need a framework to perform tests in. Luckily Brucey has something for everybody, so go get the bah.maxunit mod from here. Brucey also has a nice WIKI entry for this module, which gives you an introduction on how to use the unit test module.
There is one thing however to point out and this is what TTD comes down to, and what that WIKI entry does not do: In TTD you write the tests first, then you write the code to make the test pass. In his example Brucey writes code he knows is wrong and then writes a test for it. Using TTD you would write the test first, see it fail, and then you add code to your object to make the test pass.
This appears to be more work than just writing the program straight away, as you used to do. At first this may be the case to get you up and running but as more and more code is added to the project you will see the benefit.
There is one interesting problem though. Sometimes your object-to-be-tested needs image files or sounds, or other objects from your project to be constructed, but you don’t need those to test the code inside your object. This is where mocks come into play. A mock is an extended version of your test object which uses a different constructor or overridden methods to get around this problem.
Think of the test code as a bare-bones version of your application or game which is only used to run and confirm that your code works as intended. As you only run the code you want to test, you don’t need graphics modes and all that other stuff your game/application needs to run.
It’s a change of habit, a different mindset even, and not in the spirit of hobby and guerrilla coding but it works for me!
It might also be the solution to your development woes and the boost you need to get over that threshold to finally finish that project instead of being caught in endless bug hunting sessions. I will make some example posts if I get enough comments on this blog entry.
As you may have read (or not) I lost the source code of some past projects. Keeping your code on your own machine and doing your own backups is all good and if you have that in place that’s cool. It’s no insurance against dropping drives from the stairs though. I started thinking, and the idea of having a server which holds my code safe for me started to sound pretty handy. That and being able to reach it from anywhere.So I went looking. It turns out you basically can do three things with SVN:
- Create your own SVN server, and host the repository on that. You can install a server, or: Assembla offers a complete Vmware virtual machine (appliance) which you can run on your VMware hypervisor at home.
- Create a local repository on your development machine, or shared folder on the network.
- Use a hosted SVN repository.
Creating your own server is interesting, but I don’t want to have machines running when I’m not using them. So that’s not an option.
The documentation of most (if not all) SVN clients tells me that it is not a good idea to put your repository on a network folder. I actually tried to create a repository on my network SMB drive but it just won’t work. The thing is formatted with FAT32 and I get permission errors which I cannot fix right now. A local repository on my development machine is the other option, and it has the benefit of me having versioning, but it does not address the need of a separate place to store source code. I could put a scheduled task on my machine to copy the files from time to time, but it feels clunky.
It feels weird to put source on a site somewhere, but hey, let’s look at the hosted options:
- Google: free hosting for public, open source projects.
- Assembla: only hosts public projects with the free version
- XP-Dev: free hosting, private projects.
There are more hosted solutions, but XP-Dev seems to be the one to go for now. The big advantage of a hosted repository is that you can access your sources from anywhere. Also, it adds additional functionality like bug tracking. Commitment to a solution is a big thing, but as XP-Dev allows export of your repository at any time, you can get your data and version history and implement it somewhere else if you want to.
So, I went there, registered, created a repository, and now, which client to use? Lets look at the options:
- subversion: the command line tools.
- RapidSVN: graphical interface.
- TurtoiseSVN: graphical interface, with shell integration.
Again, there are more options but these represent the most different in features and functionality. The command line tools will do the trick, but I need something more visual. I prefer to use TurtoiseSVN. The added benefit of shell integration is that I can ‘see’ if my files are in sync with the repository or not. And if not, all I have to do is right-click and select Commit. No need for a repository browser or command line tools. Also, the ability to exclude files from the commit is nice.
I’m satisfied with this solution, and so far XP-Dev and TurtoiseSVN seem to offer all I need.
I recently had to build some modules for use in Blitzmax. Brucey has created an awesome set of modules which you can find on his google code page. Great stuff. BUT, these modules are not compiled and they include C++ code files. You can only compile these modules if you have a C/C++ compiler installed. Tip: You can compile modules which contain Blitzmax-only code without the need of an extra compiler.
Documentation on how to configure this all is vague and the tutorials on the Blitzmax site are a bit dated or buried so I thought I’d write a little tutorial on how to configure the compiler and the modules.
Install MinGW: You can download the latest version of the MinGW compiler from the sourceforge page, and install it on your machine. You only need the base files and the G++ compiler option. After the installation, make sure to add the install path to your system PATH variable, by adding ;minGWinstallpath\bin to the end of the variable. Example: If you installed MinGW in E:minGW you append ;e:\mingw\bin to the path variable.
Your C/C++ compiler is now set, now to properly install the module source so we can compile it.
Each module in Blitzmax lives in its own name space. This namespace is defined by the folder name in which the module resides. For the original modules this is brl.mod. Make sure to use the folder name specified by the module makers’ source when you install additional modules. For Brucey’s modules this name is bah.mod. In this name space the individual module folders are placed. Each module folder needs to have a .mod extension, so for example: the libxml folder is named libxml.mod and is placed in the bah.mod folder which resides in the blitzmax/mod/ folder… phew. Important: Only use lowercase characters in the folder names.
Now we can compile; open a new command line and go to your Blitzmax bin folder. Type bmk.exe makemods namespace.modulename
Example on how to compile the XML module: bmk.exe makemods bah.libxml
You should now see the compiler parsing the additional .c files as well, and the module is ready to use in Blitzmax. You should rebuild the docs now to get the extra documentation in the module to show up in your IDE. So start your IDE, and select Program > Rebuild Documentation. You’re all set now!
The title of this article is a little misleading as it also talks about programming your own game. OK, having a good and finished game will help you sell it more often too. :) Good read, make sure to check it out if you’re thinking of creating your own game (or if you are stuck in your own development hell)
One of the features of the 1.1 version of Thrust Xtreme is the inclusion of the object and world editors so you can create your own worlds!
Everything (apart from the font) you see in Thrust Xtreme is drawn using lines. The game does not contain sprites or images. Being lines, I can rotate and scale the objects as I please.
I also used these editors during development to create new content for the game. These game objects are created by drawing the lines in the Object Editor and saving them to disk in a .vob file (Vector OBject). I import this file in the game and code the behavior for it, which is how the guns, fuel canisters etc are being made.
I hear you say : ‘Wait a minute! Does this mean I cannot create my own unique child objects or enemies to be used in my world?’. Sadly, yes… I can not provide in all the logic you might need, and I haven’t included a script engine to provide you with the flexibility needed… You can of course change the appearance of the objects already in the game; load the .vob, change the object and save it under the same name…
Ok, let’s move on: A planet (or world) is also based on a vector object. A world is nothing more than a base vector object with child vector objects linked to it. Child objects have their position and rotation angle in the world and when the world object moves or rotates these positions and angles are changed with it. A world object can be flat or round. Asteroid worlds or small planets can be created this way. Round worlds can rotate, causing severe stress to the player :) .
There are some differences when creating a round or flat world: A round world is exited by traveling far enough from the world vector object radius. A flat world is exited by crossing the finish line which is placed in the sky. A round world does not need wrap lines while a flat world needs a wrap line on each side of the playable area to make sure that a player sees the side of the world vector object. Finish lines and wrap lines are child objects, just like checkpoints.
Creating a world therefore starts in the object editor where a main object is created and saved out. After starting the World Editor and selecting ‘new world’ a requester pops up asking you to select the base vector object for this new world. This new empty world is then displayed in the editor, ready to be filled with child objects.
Child objects are added by clicking on a button in the ‘Add’ region of the toolbar. Child objects can be positioned, named, given values and targets, angle and rotation speed. This way it’s easy to add buttons, link doors or lasers to it, link lasers to other lasers, place way points for our lost astronauts or tanks, etc. There are a lot of evil situations you can create for the victim, ehh player…
Like said earlier, a world can be round. An example is the world seen in the intro screen of the game. It slowly rotates showing parts of its surface. Round worlds must use the ‘to center’ gravity type though, causing the player to be always pulled to the planet core. Falling down into space would suck, imho.
After naming the world and setting its gravity type and amount the world is saved out as a .wob file (World OBject).
The world file name can be added to the file playlist.txt and that’s it! Your world is available in the game.