So, we have a good deal of framework code down now. We have some nice player-interaction code, some behaviour interaction code. That should be enough to get us started. There will probably be a lot more framework stuff to come, but if we tidy this up, and design how we go ahead, we should be able to keep these things working well.
So, what’s left to do with this framework stuff? Very little actually. There’s a few things which could be tidied up. The message system could now, for example, use the hash algorithm in the Util namespace. We could go through things and rename things to something more sensible (rather than TutorialBehaviour for example).
One thing to mention at this point is debugging. For now, I’ll only cover debugging on windows with Visual C++ but you should be able to debug on any OS.
To begin with, with “normal” Visual Studio development, you code a bit, then hit debug and it runs your executable with a debugger attached. Unfortunately, this isn’t really possible with a Maratis game, at least at this point, because we’re building it as a DLL. We can, however, fiddle around with Visual Studio and Maratis in order to get it to work. Potentially, you could copy the player source code into your project and build the player, possibly with your game code built in. If you use the player code, you would have to make your entire project GPL, or you could use the Manual Use example. Either way, that’s a lot of hassle.
The quickest way to test debugging is to fire up the Maratis editor and, before you do anything else, in Visual Studio, look in the Debug menu for Attach to Process, then find Maratis.exe there. Now, when you load the project, you can put breakpoints in the project source and debug like normal. This is probably fine for most debugging at this stage, but further down the line, just pressing F5 to start a debug session is probably something that is wanted, rather than having to restart the editor, attach to it, then start debugging. For this, we have to tell Visual Studio to run a different executable to debug. Unfortunately, I can’t find a way within premake4 to do that, but once the project file has been created, you can set this.
To do this, right click on the project in the Solution explorer (called Game) and head over to it’s properties. For the most part, premake4 should fill all this out. Anything you change in here will probably be overridden every time you rerun premake4, so for this stuff, you’re probably going to have to remember what to put, and set it up every time. Once you’ve got the “Game Property Pages” open, head over to Debugging in it and set it up as follows:
Once you have the debugger set up, all you need to do is hit F5 and your game should fire up with debugging connected directly.
One thing that might want to be a consideration at this point, if you’re working on what might potentially become a larger game with multiple developers is documentation. What I mean to say is, you should document your work anyway. There are those who say “if it was hard to write, it should be hard to understand” but, much as I sort of agree with that, it never helps, in 2 weeks time you could come back and not have a clue what your own work did. Programmers, however, are notoriously bad at writing documentation. I am no exception. One reason for my own lack of documentation is that writing documentation is usually a totally different mindset to programming. I can easily sit down and code for 2 hours without writing a single comment. If I start writing comments, my productivity starts dropping considerably. I have found a way to get around this. If anyone keeps an eye on the github repository for this tutorial, they will often see one or more commits with little to no comments, followed by one commit a day later or so with the whole section commented, but almost no code, apart from possibly minor refactoring to clarify. So the way I do this is that I set a goal, say the complete functionality for this tutorial I’m writing, I code it all, however long it takes, then the next time I come to it, I spend time adding documentation. That way, I don’t lose the concentration when I’m coding, but I still get a reasonable amount of comments written as close to when I coded as possible.
If you will have more than, say 2 people looking at your code eventually, I would strongly suggest formalising a comment standard. This could be as simple as saying “every class and non-trivial functions should have a brief description of it’s role written before it’s definition” Depending on the size of the project, I would definitely consider using something such as doxygen. Much as it’s probably overkill for most small projects, it does provide a prewritten standard, so you don’t have to worry about writing one yourself, but also, you can very simply generate comprehensive documentation from it.
One other thing we can do to tidy up our code is look to see if there are any parts of code where we will be constantly writing the same code in future. One thing to definitely look at right now is the standard MBehavior code we had to write. There will likely be a lot of framework stuff we can either push down into our custom Behaviour class, or just wrap up in macros.
I won’t go into detail about what you can do in here, I will leave it as an exercise to the reader to work out what might be the best way to do things (or look at the github repository later and see what I ended up doing). I will, however, outline a couple of issues and roughly suggest as to how you could tidy them up.
The first and most obvious one is the destroy/getNew/getCopy functions. These can’t be moved down to our Behaviour wrapper as they need to be implemented by the class (well, destroy doesn’t need to be). What we can quite easily do is add it to the macros we already have defined in BehaviourDB.h. We can add the function prototypes to DECLARE_BEHAVIOUR and then add the implementation to IMPLEMENT_BEHAVIOUR. As we’re using these 2 macros anyway, in future behaviours, we won’t have to worry about writing these each time.
Secondly, the whole variable system I think could be tidied up a bit. Currently, if you want to expose a new variable to the editor, you have to make the member variable as normal, then add it to getVariable, then increase the amount in getVariablesNumber. Now, there are 2 ways I can see this working. The first is to implement a list within Behaviour of MVariables. You can then add something like a protected template<typename T> void EditorExposeVariable(T var, const char* name) to Behaviour which will push back new variables onto the list. You then only have to maintain the one list of variables that you want to expose, for us this would probably best be done within TutorialBehaviour::Setup. Behaviour itself could then implement getVariablesNumber and just return the size of the list and getVariable to access the list. If you wanted to extend this a bit further, you get my second suggestion, which is to create a class within Behaviour, say template<typename T> class Behaviour::Variable, which would implicitely add itself to the list within the Behaviour. You would have to implement all the normal operators for Variable so you could use it interchangably with normal types without noticing.
These things aren’t by any means necessary. They won’t make the game run any faster. They might however make writing code a bit faster and less painful, once they’re in place.
Edit: I’ve just been fiddling with things and, probably for the first time, ran the tutorial twice from the editor in one session. It crashed. That reminded me of something I wanted to do in the message system but forgot to mention. It is currently unsafe. When the game ends, the objects are destroyed, however, they don’t automatically unregister any subject/observer stuff on destruction. The solution, during AttachObserver, we also register the subject back into the observer, then on destruction, we automatically unregister the observer. This should fix the crash easily.
As always, if you have any feedback, maybe some suggestions for how to clean things up, hop onto the forum and leave a message.