How to quit your game engine

Started by
16 comments, last by mrchrismnh 13 years, 6 months ago
Quote:Original post by Drathis
Quote:Original post by voguemaster

Its true that hardcore engine dev guys will stone you for even considering using exceptions but maybe this is an exception :)

Why would they stone you? What is wrong with exceptions?


There is nothig 'wrong' with exceptions but using them for this is the kind of thing people try to push against; exceptions are for exceptional situations, the kind of thing which shouldn't occur in normal operation but might and you want to handle gracefull. The clue is in the name really.

Exiting from a game is not, by any definition, an exceptional event which is why they are the wrong tool for the job.

Calling 'exit' would do nicely, as would posting the correct window message to shut down; how you get your game to call exit however is another matter but most likely you would have the code which handles any 'I want to exit' events call one central 'shut down' function and that does the Right Thing(tm) such as terminate message loops, close down threads, stop tasks or simply call 'exit' and let things die.

There is no good reason to use exceptions for this, doing so is just abusing them. Heck, its not even like you have to handle it from multiple points;
- alt-f4 handler on windows
- exit options from your GUI code
- clicking 'close window' button in windowed mode.

Not the most taxing of things to handle...
Advertisement
Quote:Original post by voguemaster
I know its considered blasphemy in game development circles but that is exactly why they invented exceptions :).
Why blasphemy? It is what exceptions are for. :-)

Quote:... overhead ...
Zero or close to, unless terribly abused. Not in any relation to the benefits if used properly, anyway.

Quote:Exiting from a game is not, by any definition, an exceptional event which is why they are the wrong tool for the job.
Though the OP said "suddenly a null pointer is acquired", which is why the game needs to shut down. And this is the whole point of exceptions. Throwing an exception kind of is the right thing. Or it may be

In most cases the exception will just terminate the process, or otherwise quit the application. However, you might be able to do something useful to fix whatever the problem is, and continue. Or, you might shut down the application in a more graceful way which maybe doesn't cause corrupt files and such.
The answer seems super simple to me. When the module acquires the null pointer just return 0 and structure your main loop like this:

int MainLoop(){    while (m_isRunning)    {        if(!UpdateFrame()) retun 0;        if(!DrawFrame()) retun 0;    }    retun 1;}


Problem solved!
Exceptions are suppose to be used for terrible bad things like on the new and delete functions. new and delete can throw exceptions, but they do this when they cannot allocate more memory ... something very serious. You would not, for example, throw an exception if you attempt to load a file and the file cannot be found. You would handle that within your code without the exception. Exceptions are for very very very serious things..... .. .
Wisdom is knowing when to shut up, so try it.
--Game Development http://nolimitsdesigns.com: Reliable UDP library, Threading library, Math Library, UI Library. Take a look, its all free.
Quote:Original post by smasherprog
Exceptions are suppose to be used for terrible bad things like on the new and delete functions. new and delete can throw exceptions, but they do this when they cannot allocate more memory ... something very serious. You would not, for example, throw an exception if you attempt to load a file and the file cannot be found. You would handle that within your code without the exception. Exceptions are for very very very serious things..... .. .
Exceptions are not necessarily terrible or bad.

Exceptions are for situations that:
a) occur "exceptionally", i.e. rarely
b) can possibly be handled in a graceful way

The mere fact that many programmers don't handle exceptions (does not apply to Java programmers) and so any exception just ends up killing the application doesn't mean that it always has to be that way.

Take your memory allocation example. The purpose of this exception is not to kill the application. You could get that much easier.
The purpose is to give the application an opportunity to fix the problem. You can free some memory that you maybe don't need any more (a cached item?) inside the handler and simply redo the allocation, and it will work. Nobody will know that you just ran out of memory, the program will continue to work -- which admittedly is quite cool.

It very much depends, but even in your "file not found" example, an exception could probably make sense in some situations, such as when a file actually cannot possibly be missing, so you don't want to clutter your code with a lot of useless error handling. But then again a foolish user might delete the file (1 in 1 million chance) and you don't want the application to hard crash in that case.
Or maybe, if that file is missing, you need to discard the present file reader instance and construct a different one for some other file or whatever. Throwing an exception can be a totally valid and elegant thing to do in this case.
Quote:Original post by samoth
Quote:... overhead ...
Zero or close to, unless terribly abused. Not in any relation to the benefits if used properly, anyway.
It's been discussed over and over again on the forums... but depending on the platform, execptions may cause significant overhead.
Even just enabling exception handing (or not disabling exception handing in the compiler's settings) could potentially cause enough code bloat to add large amounts of cache-misses to each frame.

These days, on PC, it's not much of an issue -- but the hesitance to use exceptions in game did[ come from well founded observations, which in certain circumstances are still entirely warranted.
Quote:Original post by smasherprog
Exceptions are suppose to be used for terrible bad things like on the new and delete functions. new and delete can throw exceptions, but they do this when they cannot allocate more memory ... something very serious. You would not, for example, throw an exception if you attempt to load a file and the file cannot be found. You would handle that within your code without the exception. Exceptions are for very very very serious things..... .. .

Huh? Isn't a missing file pretty serious situation? How can you possibly recover from that in code? The usual case for me would be to throw an exception and handle it on some higher layer that can display an error message to user. Or is this about some configuration file missing and you would just create a default file for it?
Quote:Original post by Drathis
Huh? Isn't a missing file pretty serious situation? How can you possibly recover from that in code? The usual case for me would be to throw an exception and handle it on some higher layer that can display an error message to user. Or is this about some configuration file missing and you would just create a default file for it?


It depends on your program's assumed stable state. Is the existance of the file in question an integral part of your application? Throw an exception. Can the file be replaced by a default template? Catch the exception and create a default file. Is the file optional? Maybe you should check with FileExists() first. ;)

I always treat exceptions that way: Is a function not able to do what it is supposed to do? Throw an exception. Of course "supposed to do" must be well defined. Ideally you can deduce that from the functions name, else put it in the documentation.

The good thing about exceptions is that they allow you to write clean code to recover from exceptional situations. If you discover you need to catch a specific exception later in development you can just add the try-catch block to a suitable place in your code. had you used return values instead, you would have to retrofit if/elses in a lot of places.

[Edited by - Madhed on October 24, 2010 7:32:39 AM]
Well if you catch a null pointer, and on top of that you have to exit in the middle of a frame, I would call that an exceptional situation and that'd totally warrant the use of an exception.

Exceptions have performance issues when you enter a try block, because your program must write pointers to a jump table. Try to not enter too many try/catch blocks. No try/catch blocks in your Draw functions, for example. For my game editor in C# (I assume the "under the hood" exception mechanics in C# are not too different from C++) I had a try/catch block in the drawing routine, and that routine was called *at least* 900 times per refresh. (Once for every tile.) As a result, I had a *significant* loss of performance due to this. When I took it away from the drawing routine and made it so that the editor only enters a try/catch block once per refresh, it was far, far better.

Exceptions are also slow when you actually throw the exception because the program must allocate the exception and figure where to jump. If you follow the guidelines and only use them in exceptional situations, then this should only happen when something goes extremely wrong, and in those cases you probably want to abort your game anyway, so you don't care about performance there. If you don't throw anything, there is no loss of performance beyond entering a try block. So if you want to throw an exception in your Draw calls when it's called before your engine is initialized, do it because normally that should never happen.

The only thing is that exceptions increase your code size, but in my opinion, this is not a big issue. See this if you want details on how exception really work.
When I read "how to quit your game engine" I expected something along the lines of "should I throw my computer against the wall or burn all my programming books".
"It's like naming him Asskicker Monstertrucktits O'Ninja" -Khaiy

This topic is closed to new replies.

Advertisement