Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

13. September 2011

 

 

I was trying to figure out a way to work a “Johnny Five is Alive!” Short Circuit reference into the title and failed hard…  anyways, the next chapter/part of Game From Scratch C++ Edition is now live although I promise you I will be doing edits. 

 

 

In this part we create a game object manager, aptly called GameObjectManager to organize and manage game objects.  It may seem like a bit of a waste of time but trust me, in time this little class is going to seem exceptionally powerful!  On the bright side, it will give you more exposure to the standard library classes, especially std::map and std::for_each, both of which you will use over and over again from this point on.

 

 

Is it massive overkill for a pong clone?  Yes, very much so!  But truth told, this series is little about the actual game and more about how to create a “real” game instead of a demo.  So, even though this game is quite trivial in it’s scope doesn’t mean we can’t have a certain amount of complexity.  When we are done this process my ideal is you can walk away and make just about any type of game, not just a trivial pong clone.  This is why at times things may seem a bit overkilled.

 

Truth told, I don’t know if I blew the difficulty curve on this post.  I feel compared to the last post, I may have ramped up the difficulty and done a poor job of explaining things, please let me know if this is the case!  If things are confusing or unclear or just simply wrong, let me know and I will address them!

 

 

Well, without any further ado, I present Game From Scratch   C++ Edition     Part5.

Programming ,

5. September 2011

 

You may have noticed many times on my blog that I am not the biggest fan of C++.  I hands down believe that it is one of the dumbest languages a user could learn with.  A good majority of programmers should never be exposed to C++ and should be happy if fate affords them such a luxury.  I also think a lot of C++’s use in game programming is as much a matter of traction as any other logical reason.  So why the hell do I talk about it so much?

 

Well one of the reasons is because so many (new) developers give a lot of other new developers the horrid advice that they should start with C++ that you need to actively educate people why this is a mistake.  However, there is another reason for C++’s coverage… it is important and it’s importance is on the rise. Amazingly that rise in popularity has nothing to do with (specifically) game development!

 

You see, the revolution in mobile computing coupled with the rise in indy developers has created a perfect storm of sorts for C++ developers.  You see, of all the mobile platforms out there, they all support their own native language ( iOS = Objective C, Android = Java(ish), Palm == HTML5/Javascript while Windows Phone 7 == C#/Silverlight ) yet all of them support C++ ( although WP7 requires a special relationship with Microsoft for C++ access ), to say nothing of Symbian… mostly because it’s dying off. 

 

Therefore, if you want to write portable code that runs across most of the mobile phones on the market today, C++ is your go to language.  Operating in a resource constrained environment is exactly where C++’s strengths come into play.  Unfortunately you are going to end up doing some device specific code in whatever the native language is, but on all devices this amount of native code is getting smaller in size.  For the most part you can make 99% portable C++ code, something you can’t currently do for smartphones in Java, C# or ObjectiveC.

 

That said, if you are willing to spend money, you can use C# across platforms in the form of Unity or Monotouch/Monodroid but that requires additional expense.  Besides, I recently took a look at Monodroid and I simply cannot imagine how anybody is using that platform for production code, at least on Windows the developer experience was frankly atrocious.  If I was doing a cross platform 3D game ( that I expected would make at least 400$ ) I would be ( and am ) using Unity, but I can understand why you would choose otherwise, especially if you were working on a 2D project.

 

If you are a new developer, I still recommend you stay the hell away from C++.  I just wanted to make it clear C++ has it’s uses and in my opinion is only going to get more popular, a comment I would have never expected to have made just a few years ago! As I have said many times C++ is just another programming tool and sometimes that tool is the most appropriate one for the job.

 

Given it’s justified rise in popularity among indy developers, combined with the fact that beginning programmers are going to ignore my advice and start with C++ anyways, I am going to introduce a bit more C++ specific content on this site.  The C++ of today is much different than the C++ of 1983, yet unfortunately a great volume of the information on the internet doesn’t reflect this fact.  I hope to address that to the best of my (meager) ability.

Programming ,

25. August 2011

 

In putting together content for this site, I find myself working in Visual C++ which presented an unintended consequence, the project folder’s files are big, huge in fact!  Most of the problem boils down to the intermediate files that Visual C++ generates for intellisense and pre-compiled headers.

 

Therefore each time I wanted to post a code example to this site, I had to go through and delete all of these temporary files or my archives would be huge.  Worse still, every time I open up the solution, they would be regenerated.  ( Yes, you can move these files outside of your folder as a possible work around ).  I figured with the whole me being a programmer thing, I could throw together a program that did this work for me.

 

Therefore I present to you ProjectCleaner.  Aim it at a folder containing your project or sln file click “Clean Project” and it will go through and delete all the temporary cruft ready for you to zip up and share.  For the record, it deletes log, tlog, pch, pdb and obj files as well as the ipch folder.

 

image

 

 

Here are the results after applying to a relatively simple project folder:

image

 

As you can see, it results in a 37MB reduction in size, which saves more than just a small bit of bandwidth.

 

So, if you are finding yourself needing to shrink your Visual C++ projects down to share them, this tool may prove useful.  The source is exceedingly primitive.  It’s written in C#, requires .NET 4.

 

 

Files:

 

CleanProject.zip  -- program executable

CleanProjectSource.zip -- source code

Programming

25. August 2011

 

I am currently working on a beginner level tutorial using SFML and just ran into a show stopper that I want to share.  If you are already using SFML 1.6, this is probably old news to you, but it caused me enough pain that I want to share it here.  Maybe someone in the future will find this on Google and they wont end up wasting a couple hours like I just did.

 

Anyways, I was developing away at my game and doing most of my work on my portable laptop, which has an integrated Intel chipset.  On occasion I did a little bit of work on my primary development laptop which has a higher end Radeon GPU and everything works fine.  Anyways, earlier this week Deus Ex: Human Revolution came out and PC gaming being what it is, I had to download and install the latest drivers.  Fast forward to today, I load up the project make a few changes and:

 

image

 

Completely hung.  Zero response whatsoever.  If I run the same application outside of Visual Studio, it requires me to kill it in Task Manager.

 

So I jump to the logical conclusion and figure it was something I changed recently in my code, so I start hacking and slashing out the changes until I am back to nothing.  Still hangs.  WTF?  Now I start hacking even more until the point I get to my main() consisting of a single return statement and still it hangs!  WTF x2?  Obviously at this point it’s a linker problem, and my lost likely culprit is SFML, so off to Google I go!

 

End result, yes, the dynamically linked version of SFML apparently has a bug with the OpenGL implementation of modern ATI drivers.  Yay.  Apparently it is only in the dynamic version of SFML, so you can switch to static linking and it will go away, but when writing a tutorial, this kind of added complication simply isn’t realistic.  That said, there is a work around and there is a fix... of sorts.

 

Apparently the problem is caused in atigktxx.dll and you can grab a copy that works here ( along with additional explanation ).  I haven’t an actual clue what the bug itself is ( it’s wayyyyyy outside my code ), but by including this copy of atigktxx.dll in your executable folder, it overrides loading the one that is installed on your machine, thus preventing the bug.

 

Oh, and although that post was in February and the fix is “coming soon”, the problem still occurs.  I do however believe this is fixed in the 2.0 version of SFML, but please don’t quote me on that!

 

So, long story short, if you are using SFML 1.6 and you want to support ATI cards with recent drivers, ship your game with atigktxx.dll in your executable directory.

 

Oh and moral of the story…  don’t always go blaming your code first!  I kow have a ton of damage to undo that I needlessly caused!  Moral number two…  ATI still suck at making drivers!

Programming ,

15. August 2011

 

This began life as a post here but it became long enough and IMHO important enough, I am going to clean up the spelling a bit and repost it here.  It was in response to a fairly new developer with a question about class design.

 

 

This is one of those things that is nearly impossible to explain in a post, or hell, short of a small book.


But generally ( and yes, there are exceptions, thousands and thousands of exceptions ) you want to decouple your objects from each other as greatly as possible. You also want to keep code as self contained as possible, again, with thousands of exceptions.

 


A lot of the time when you are designing your classes ask yourself "If I changed this class, how many other aspects would need to be changed as well?" Then go about breaking those dependencies where possible. If two classes don't really need to know about each other, break that dependency. If two classes share 90% of their functionality, derive from a common base class.

 


On the other hand, you have to let common sense be a factor. One really common reason to abstract away your classes into engines and various components is so you can make switches later. For example, if you are using SDL, but want to be able to switch over to SFML at a later date, it's common to make a Renderer class, and an intermediary class over all the various objects like Bitmaps and Sprites, that both SDL and SFML provide so you can transparently change Renderers without making a code change. Reality is though, for 90+% of projects, this is just an added layer of complication and work that will never ever be used. This is where common sense has to come into play. Yes, from a purely object-oriented perspective, it is a very "pure" design that implementation details are abstracted away. From a practical and getting shit done sense, it's just a stupid waste of time.

 


This is where we get to the next sticking point and another area where new developers ( and experienced developers! ) get it really wrong most of the time. Global variables. See, when a new developer learns about global variables they seem like a godsend, as then you frankly don't have to design classes at all, just make everything globally available! This in a very short while makes extremely unreadable and maintainable code. Other new ( and experienced developers ) have heard about this and had it drilled into their heads that GLOBALS ARE BAD!!!! and react accordingly. Ironically enough, 9 times out of 10 this seems to always result in the same discovery... the Singleton. If you haven't yet, some day you will discover the singleton pattern and you will think it is the answer to your prayers. It's not a global, it's an object!!! Actually no, it really is just a global with a pretty layer of object oriented goop wrapped around it(**). Then you will encounter another group of people that will yell from the mountains SINGLETONS ARE BAD!!!! Which in the end leads you to engineering half a hundred "Manager" or "Adapter" classes to eliminate your dependencies on global variable and singletons. All the while, no work is getting done on your game.

 


Now it's time to let you in on a dirty little secret. Globals aren't bad, they are actually pretty frigging useful and important. The most important thing is, DO NOT ABUSE THEM. That is it. Chances are, you are going to have some form of global object, like perhaps a Game, App or World class, this is completely reasonable. On top of that you are going to run into code that needs to be globally accessed, such as your Audio class or Event class, which is also quite reasonable. It simply does not make sense to pass in an Audio class to say, a GameEvent, because that game event might on occasion need to play a sound. There are quite literally only a handful of things that should be made globally available but if it makes sense to be globally available, make it globally available.

 


But here is where the design gets tricky again, if you are making something globally available, do not make the relationship two-way, or at least not unless the two-way relationship is completely generic or via an interface. For example, if you have a game engine ( globally available ), and that game engine has a (globally available ) event queue, that at some point a game object needs to add events to, make sure that the event queue has the most absolutely minimal requirement to know anything about the game object and that the game engine itself needs to know absolutely NOTHING about the game object, as this is where your design can start to fall on it's face.

 


One last general rule of thumb when dealing with globally available classes, make them static whenever possible, it will lead to less potential hazards. Additionally, when make global objects provide access to other global object ( for example Game::SoundManager ), use accessor methods and const whenever possible. Keep all allocation and de-allocation specifically in the realm of the containing object.

 

 

 

 

 

 

 

 

 

 


(**) There are actually more to singletons than just object oriented globals. Yes, Singletons are global in scope but they have a couple very important properties. First of which is deferred allocation, meaning the Singleton isn't using memory until the first time it is used, unlike a traditional static variable. Additionally, a Singleton can be sub-classed as a mechanism of providing a single interface to potential disparate code bases, so for example you could have a Renderer::GetInstance(), which is sub-classed as OpenGLRenderer or DirectXRenderer, which will provide your code with a single global runtime determined instance. If you don't understand this paragraph, that’s completely fine, I'm just throwing it out there as a caveat so my over simplification of a Singleton isn't misleading... they do have their uses.

Programming, Design

Month List

Popular Comments