Sign in to follow this  
Decrius

Unity [C++] Exceptions using them right

Recommended Posts

Decrius    100
EDIT: seems like some questions below are answered here as well: http://www.gamedev.net/community/forums/topic.asp?topic_id=569089 I'm fairly new with exceptions, I don't use them much myself but I'd like some advice :) 1. Is it generally a good idea to put a throw specifier in a function definition? Like: void f() throw(std::bad_alloc); void f() {} 2. I guess it is, does it also make sense to set the throw specifier for functions that do not throw anything? 3. What to do when in debug build there's more throws then in release mode? Or is this a malformed design? Like when a function does throw in debug mode, but doesn't in release mode. How would you define the function prototype? Dependent on whether its debug/release? 4. Should I catch memory / third-party-library exceptions, handle them correctly and re-throw it? Or catch them and then throw my own exception class instead? 5. There's a difference between logging, warnings, fixable errors (like, when input is incorrect it could take a default sometimes) or regular errors. Which are best to be thrown? For debug? For release? Where do you make a distinction, or do you also use a second method for error reporting then exceptions? I generally feel like exceptions produce quite a bit of bloat in the executable. Of course, for debug mode this is no problem. In debug mode we want to debug and thus good error reporting. In release I suppose only critical errors are relevant... Thanks for the input!

Share this post


Link to post
Share on other sites
Bregma    9199
Quote:
Original post by Decrius
I'm fairly new with exceptions, I don't use them much myself but I'd like some advice :)
Use exceptions only in exceptional circumstances.
Quote:

1. Is it generally a good idea to put a throw specifier in a function definition? Like: void f() throw(std::bad_alloc); void f() {}
No. Avoid using throw specifiers in C++. They do not do what you think they do. They are a deprecated language feature. Do not use them.
Quote:

2. I guess it is, does it also make sense to set the throw specifier for functions that do not throw anything?
No, not at all.
Quote:

3. What to do when in debug build there's more throws then in release mode? Or is this a malformed design? Like when a function does throw in debug mode, but doesn't in release mode. How would you define the function prototype? Dependent on whether its debug/release?
This should not occur. Either you can handle an exception or you can't.
Quote:

4. Should I catch memory / third-party-library exceptions, handle them correctly and re-throw it? Or catch them and then throw my own exception class instead?
If you can't handle an exception, ignore it and let someone else handle it. That's the point of exceptions. If you can handle it, don't rethrow it, it's been handled.
Quote:

5. There's a difference between logging, warnings, fixable errors (like, when input is incorrect it could take a default sometimes) or regular errors. Which are best to be thrown? For debug? For release? Where do you make a distinction, or do you also use a second method for error reporting then exceptions?
Use exceptions only for exceptional circumstances. Input errors are not exceptional, they are expected.
Quote:

I generally feel like exceptions produce quite a bit of bloat in the executable.

Feelings should have little to do with it. Exceptions do not add bloat and they do not affect the nonexceptional execution path in any meaningful way. Applications that use exceptions correctly tend to be larger than those that do not handle errors at all, which is the usual comparison.

Do not confuse C++ with Java exceptions. Java exceptions are more akin to the C method of passing status values ads return values. They are two different paradigms.

Share this post


Link to post
Share on other sites
Antheus    2409
Quote:
Original post by Decrius

1. Is it generally a good idea to put a throw specifier in a function definition? Like: void f() throw(std::bad_alloc); void f() {}

2. I guess it is, does it also make sense to set the throw specifier for functions that do not throw anything?
No. These specifiers have always been somewhat problematic for no benefit.

Quote:
3. What to do when in debug build there's more throws then in release mode? Or is this a malformed design?
Yes. Interfaces should be consistent. There is no "debug mode" in C++, it's just a preselected set of compiler switches - application doesn't change.

Quote:
4. Should I catch memory / third-party-library exceptions, handle them correctly and re-throw it? Or catch them and then throw my own exception class instead?
It doesn't matter who throws it. If an exception can be handled, and cause of exception fixed, then code should do so when it can, otherwise pass the exception to propagate upwards.

Quote:
5. There's a difference between logging, warnings, fixable errors (like, when input is incorrect it could take a default sometimes) or regular errors. Which are best to be thrown?
Those that are exceptions.


Quote:
I generally feel like exceptions produce quite a bit of bloat in the executable.
Yes. If only we had more than 1TB drives and more than 4GB of RAM.

Quote:
In debug mode we want to debug and thus good error reporting. In release I suppose only critical errors are relevant...
This has nothing to do with exceptions. They are not error reporting tool, they are flow control. In some cases, an exception will be handled by logging the exception message.

And exceptions are not logs. They don't have different levels of severity. When an exception is throw, it indicates that catastrophic error has occurred, so bad, that there was simply no possible way for code to continue executing.

Share this post


Link to post
Share on other sites
Decrius    100
Quote:
Original post by Bregma
Quote:

3. What to do when in debug build there's more throws then in release mode? Or is this a malformed design? Like when a function does throw in debug mode, but doesn't in release mode. How would you define the function prototype? Dependent on whether its debug/release?

This should not occur. Either you can handle an exception or you can't.


Should not occur as in: there shouldn't be a difference between debug/release mode in what is thrown (this can make sense if it's only used for exceptional cases)? Or as in the function prototype definition, which is a non-issue when not using throw()-specifiers (which I don't plan to implement, after reading your and others their advice).

EDIT: Antheus clarified this: no difference between debug / release.

Quote:
Original post by Bregma
Quote:

5. There's a difference between logging, warnings, fixable errors (like, when input is incorrect it could take a default sometimes) or regular errors. Which are best to be thrown? For debug? For release? Where do you make a distinction, or do you also use a second method for error reporting then exceptions?

Use exceptions only for exceptional circumstances. Input errors are not exceptional, they are expected.


Sounds good. How would you handle expected errors then? What if someone passes raw pixels + width + height to a function, and for some reason the width / height is zero. How would you inform the caller that the input is wrong?

Quote:
Original post by Antheus
And exceptions are not logs. They don't have different levels of severity. When an exception is throw, it indicates that catastrophic error has occurred, so bad, that there was simply no possible way for code to continue executing.


I see, I used it way too much then all the time.

Thanks both.

Share this post


Link to post
Share on other sites
Hodgman    51224
Quote:
What to do when in debug build there's more throws then in release mode? Or is this a malformed design? Like when a function does throw in debug mode, but doesn't in release mode. How would you define the function prototype?
I only do this in code that is designed to not use exceptions at all -- I still use them in debug builds for assertion failures, which usually get thrown all the way back to main (or to a unit test handler).
It could be a hint of a malformed design...
It shouldn't affect the prototype though, because as mentioned in other posts, exception specifiers aren't a good idea anyway.
Quote:
5. There's a difference between logging, warnings, fixable errors (like, when input is incorrect it could take a default sometimes) or regular errors. Which are best to be thrown?
Logging, warnings and fixable errors definitely aren't good cases for exceptions. Errors that stop you from continuing are a maybe. In a game, there's not that many cases that should stop you from continuing though -- you should try to make as many of your errors "fixable" or "tolerable" as possible.
Quote:
Exceptions do not add bloat and they do not affect the nonexceptional execution path in any meaningful way. Applications that use exceptions correctly tend to be larger than those that do not handle errors at all, which is the usual comparison.
Unfortunately enabling exceptions does generate extra code - for all the stack-unwinding that wouldn't otherwise need to be there.
This isn't usually a problem (especially on the PC), but if you're targeting hardware with a tiny cache (or you have other space restrictions), then this can actually be a problem and you might want manual control of where the exit points of a function are instead of having the compiler insert them all over the place.
e.g. The Wii has 0.25MB of L2 Cache, the 360 has 2MB and some Core 2 Duos have 6MB. So, yeah, on your PC - probably not a problem.
Quote:
Original post by Decrius
How would you handle expected errors then? What if someone passes raw pixels + width + height to a function, and for some reason the width / height is zero. How would you inform the caller that the input is wrong?
If that situation can occur from someone feeding bad data into your program, then you should probably just return an error code (e.g. "This function will return NULL if the parameters fail the pre-conditions"), and then have the calling code check for failure (and perhaps log the error and continue).

Share this post


Link to post
Share on other sites
osmanb    2082
In addition to the memory issues, it's worth mentioning that most console platforms simply don't allow you to use exceptions, period. The vendors either strongly suggest you don't (because the compilers aren't optimized to deal with them), or they ship compilers that don't support them at all.

Share this post


Link to post
Share on other sites
the_edd    2109
Quote:
Original post by Decrius
4. Should I catch memory / third-party-library exceptions, handle them correctly and re-throw it? Or catch them and then throw my own exception class instead?


Just to add some extra stuff to this one.

Exceptions are part of an interface, even if throw specifiers aren't present (and it's generally accepted that they shouldn't be as others have noted). So it can be a good idea to document the exceptions that can be thrown by various parts of your code, even if it's just to say "all standard library and foolib exceptions may be thrown by this function".

So if you're creating a library or subsystem that uses another library internally, you might consider catching all exceptions thrown by that inner library and converting them to your own class(es) of exception.

If you don't do this, then you're exposing an implementation detail of your subsystem. Often this exposure isn't a big deal, but it's something to keep in mind if your writing what you hope will be a long-standing interface.

For example, if you write a class use the Xerces XML library to read a Collada file, should the user expect to have to catch exceptions defined by Xerces? Perhaps you'll change your XML library to RapidXML or something in future...

But in general, you should only catch exceptions if you can handle them in a useful way, or if you need to release resources in the case of an exception being thrown e.g.


thing *tp = new thing(x,y,z);

try
{
something_that_may_thrown();
}
catch (...)
{
delete tp;
throw;
}


A dumb example, but this is probably one of the few valid uses for "catch(...)", IMO. However, if you find yourself writing code like this, you could and probably should re-cast your code in such a way as to use RAII:


thing t(x,y,z); // morally equivalent to all of the above!


EDIT: and one final point on this. If you expect to be able to recover meaningfully from exceptions at various points in your application, you should make sure you write your code in an exception-safe way. This takes practice, patience and discipline but the code one ends up with is often much cleaner (anecdotally).

The RAII mechanism of C++ actually makes this a lot easier to do than in many other languages as you don't need IDisposable/using (C#), "with" statements (Python), or boilerplate "finally" blocks (many others). Though RAII won't solve all possible exception safety issues, it will at least prevent leaks.

Share this post


Link to post
Share on other sites
Decrius    100
Thanks the_edd. It sounds consistent to re-throw my own exception yeah. I also thought of a comment behind the prototype to document which exception might occur, good idea!

Also, for validating user / programmer input to a function; an alternative to Hodgman's return code method, would it be a good idea to do an assert on user input?

I read that asserts should be used for expressions that are always true to your believes (but sometimes turn out to be false -> useful debug information). How well would it be to use asserts for user-input validation?

Share this post


Link to post
Share on other sites
the_edd    2109
Quote:
Original post by Decrius
Also, for validating user / programmer input to a function; an alternative to Hodgman's return code method, would it be a good idea to do an assert on user input?

IMO, it would be a bad idea.

Quote:

I read that asserts should be used for expressions that are always true to your believes (but sometimes turn out to be false -> useful debug information).

Yes.

Quote:

How well would it be to use asserts for user-input validation?


Not well at all. Rule of thumb: asserts are for implementers, exceptions are for clients.

If an assert fails, your program will be aborted, it will not pass Go, it will not collect £200. On unexpected/inadequate user input, you presumably don't want that to happen. Instead return an error code or throw an exception and when the time is right, display a useful error message.

And of course, the assert macro provided with the C and C++ standard library is effectively removed at the pre-processing stage when the NDEBUG macro is defined.

Aside: some people create their own assert macros that allow execution to continue after reporting an error. Personally, I don't like that idea as it doesn't gel with the original idea behind an assertion. I would call such a macro "hope" rather than "assert".

Share this post


Link to post
Share on other sites
Bregma    9199
Quote:
Original post by Decrius
Thanks the_edd. It sounds consistent to re-throw my own exception yeah. I also thought of a comment behind the prototype to document which exception might occur, good idea!

There are a lot of problems with coding Java in C++. Java does not allow you to pass function pointers. Java requires throw specifications. C++ allows function pointers and does not implement Java-style throw specifications. As long as you write simple code, you can catch all contained exceotions and rethrow your own, but if you're providing any sort of customizable code (callbacks, delegates) you can not guarantee what code you call can throw. That means you're going to have to catch(...) and throw some sort of generic exception, just so you can act like Java.

If you never write code for others to extend, this is not a concern.
Quote:
Also, for validating user / programmer input to a function; an alternative to Hodgman's return code method, would it be a good idea to do an assert on user input?

I read that asserts should be used for expressions that are always true to your believes (but sometimes turn out to be false -> useful debug information). How well would it be to use asserts for user-input validation?

I have dealt with widely-available libraries (eg. OpenLDAP) that throw asserts in production code. I have cursed the authors of such code and their descendants to the seventh generation to eternal damnation in an inner circle of hell. Do not repeat their mistakes.

Share this post


Link to post
Share on other sites
Decrius    100
Quote:
Original post by the_edd
Not well at all. Rule of thumb: asserts are for implementers, exceptions are for clients.


Sorry, I should have been more clear. It looks like I meant program-user input, but since I write a library, the user is actually the library-user and thus the program-programmer.

But yeah, I agree. Program-user input is something you almost know for sure is wrong and thus not assert-material.

So to rewrite my question: how well can asserts be used to document function arguments (assert whether the argument is valid) called internally in the library or externally by the programmer (the library-user)?
Currently I'm throwing exceptions, but this is not really exceptional. Neither a return-type is always possible (some objects just don't have a NULL-state).

Quote:
Original post by Bregma
I have dealt with widely-available libraries (eg. OpenLDAP) that throw asserts in production code. I have cursed the authors of such code and their descendants to the seventh generation to eternal damnation in an inner circle of hell. Do not repeat their mistakes.


Hehe, that's a hell of a curse ;). Why was this such a problem? There shouldn't be any asserts in release-mode, and in debug mode it should give useful debug information. How did they abuse the asserts so badly?

Thanks for the answers guys, helps me constructing and verifying my thoughts ;)...eventually I might become a good programmer ^_^

Share this post


Link to post
Share on other sites
the_edd    2109
Quote:
Original post by Decrius
So to rewrite my question: how well can asserts be used to document function arguments (assert whether the argument is valid) called internally in the library or externally by the programmer (the library-user)?


I think that's fine. If you do use asserts in this way, just make sure to document the inputs that your function considers to be illegal.

If I see documentation that mentions a precondition for a library I'm using, I'll often add my own asserts before calling that function.

Ideally, you should use the type system as far as is practical to restrict the arguments to valid values. For example, if a pointer must be non-null, then you might change the argument to a reference instead.

Share this post


Link to post
Share on other sites
Decrius    100
Quote:
Original post by the_edd
Quote:
Original post by Decrius
So to rewrite my question: how well can asserts be used to document function arguments (assert whether the argument is valid) called internally in the library or externally by the programmer (the library-user)?


I think that's fine. If you do use asserts in this way, just make sure to document the inputs that your function considers to be illegal.

If I see documentation that mentions a precondition for a library I'm using, I'll often add my own asserts before calling that function.

Ideally, you should use the type system as far as is practical to restrict the arguments to valid values. For example, if a pointer must be non-null, then you might change the argument to a reference instead.


Thanks the_edd for the useful info :D, this will get me to finish v1 hehe

Share this post


Link to post
Share on other sites
Zahlman    1682
Quote:
Original post by Decrius
I'm fairly new with exceptions, I don't use them much myself but I'd like some advice :)


Read this.

Quote:
1. Is it generally a good idea to put a throw specifier in a function definition? Like: void f() throw(std::bad_alloc); void f() {}

2. I guess it is, does it also make sense to set the throw specifier for functions that do not throw anything?


No and no. C++ throw-specifications are damn near useless.

Quote:
3. What to do when in debug build there's more throws then in release mode? Or is this a malformed design? Like when a function does throw in debug mode, but doesn't in release mode. How would you define the function prototype? Dependent on whether its debug/release?


N/A because of the above.

Quote:
4. Should I catch memory / third-party-library exceptions, handle them correctly and re-throw it? Or catch them and then throw my own exception class instead?


If you've properly handled the exception, why would you need to re-throw anything? That said, there are plenty of reasons why you might want to catch an exception and throw an instance of your own back instead of the one you received. This is in order to "translate" the exception, and you'd do so for basically the same reasons you'd translate anything else.

Quote:
5. There's a difference between logging, warnings, fixable errors (like, when input is incorrect it could take a default sometimes) or regular errors. Which are best to be thrown? For debug? For release? Where do you make a distinction, or do you also use a second method for error reporting then exceptions?


Logging has nothing to do with exceptions. I don't know what you mean by "warnings". Otherwise, figuring what's "exceptional" is kind of an art form. Sorry.

Quote:
I generally feel like exceptions produce quite a bit of bloat in the executable. Of course, for debug mode this is no problem. In debug mode we want to debug and thus good error reporting. In release I suppose only critical errors are relevant...


This should not be a concern. The only time you would use exceptions in debug that aren't in release is where it helps you debug; but C++ doesn't expect you to use exceptions as a debugging tool (since there is static, manifest typing) but instead to handle things that couldn't be expected by the program (e.g. a missing file, insufficient memory).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Similar Content

    • By Jacob Laurits Besenbacher Kjeldsen
       
      Intro - "The challenges of dynamic system design"
      Custom Quest evolved during development, from a minor quest system used for our own needs in our own game production Quest Accepted, to something entirely more dynamic and customizable, now finally released, these are our thoughts on quest design and developing standalone subsystems. 
      Splitting what is a major production for a small indie team, into smaller installments such as a quest system was a good idea we thought, this way we can get some releases out there and fuel the development of our game. But building a system that works for yourself is one thing, building a unity plugin that will let other developers create quests, missions, and objectives, you would never have thought of is something else entirely.
      The first thing we had to realize was that when building a quest system, the task is not to design great quests, the task is to enable the users to create great quests.
      That still meant we had to find out what good quest design is and what a quest really is.
      Our task was to create a system where the user is free to create creative engaging and rewarding mission experiences for their players.
      What is a quest? - "Cut to the core"
      First off, we need to know what a quest really is.
      A quest is the pursuit, search, expedition, task or assignment a person(s) does in order to find, gain or obtain something.
      In games, quests and missions function in many different ways depending on the genre.
      A single game can contain a multitude of different types of quests put together in just as many ways. In an MMO, for instance, quests are vehicles for the story and the player's progression. In many cases they are formulaic and simple, some can even be repeated, there are hundreds of them and everyone can do them. In other games quests are for single player campaigns only, here they shape each level giving the player a sense of purpose.
      Quests can span the whole game or just be a minor optional task on the way, there are so many design philosophies and creative quest designs that we had to narrow it down and really cut to the core of what is needed for good quest design.
      What all quests have in common is the task, the criteria for successful completion of the quest, and the reward, the goal of the quest, what the player gets out of doing what we ask of him.
      Quests cover an incredible variety of tasks so it was important for us to base our decisions on thorough research. In our research, we found that there are three layers to quest design.
      The type, the pattern and the superstructure.
      Quest types exist within quest patterns and quest patterns exist within the quest superstructure.
      We found that there are 8 basic types of quests these are the various tasks/criteria the player must do in order to complete the specific quest.
      There are 12 quest patterns. These are ways designers can use their quests, connect multiple quests set them up in engaging ways or teach players how to interact with and get the most out of the game world creating variety and engaging the player.
      Enveloping the patterns is the quest superstructure, the overall structure of quests in the game, we found that there are two main ways of structuring your quests.
      Historically quest have a quest giver, an NPC or object that informs the player about the quest, what they need to do, the story behind it and perhaps even what their reward will be should they complete the quest.
      Quest types - "Do this, do that"
      The core task each quest consists of, the criteria for completing part of or all of a single quest. These are the actions we want Custom Quest to be able to handle.
      Kill
      Probably the most basic quest type, the task is to kill something in the game, for example; kill 10 goblins. Gather
      Again very simple, the task is to gather x things in the game world, collecting berries or the like. Escort
      The player must escort or follow a person or object from point A to B while keeping it safe. FedX
      The player is the delivery boy, they must deliver an item to a person or point. Defend
      The player has to defend a location from oncoming enemies, often for a set number of waves or time. Profit
      The player must have a certain amount of resources to complete the quest, contrary to gather quests these resources are resources the player would otherwise be able to use himself. Activate
      The player's task is to activate/interact with one or more objects in the game world or talk to a number of NPC’s. In some cases, this must be done in a certain order for a puzzle effect. Search
      Search an area, discover an area of the game world. This is useful for introducing areas of the map to the player and giving them a sense of accomplishment right off the bat, showing them a new quest hub or the like. Quest Patterns - "An engaging experience"
      Tasks are one thing, and in many games, that might be plenty but we wanted custom quest to let the users create chains of quests, specialize them and set them up in ways that draw the player into the experience, there are many ways to go about this.
       
      Arrowhead
      The most basic quest pattern, the quest chain starts out broad and easy, the player has to kill some low-level cronies. The next quest is narrower, the player must kill fewer but tougher enemies, lets say the boss' bodyguards. The last quest is the boss fight, the player has killed the gang and can now kill the boss. This quest pattern is very straightforward and works well, giving rewards either at every stage or only when the boss is dead.  
      Side stub 
      A side stub is an optional part of the overlapping quest. Lets say quest A leads to quest C but there is an option to complete a side objective B, which makes completing C easier or it changes the reward, for example. The player must escape prison, the side stub is “free the other prisoners” in this example escaping with all the prisoners is voluntary but it might make it easier to overpower the guards or the prisoners might reward the player when he gets them out. The side stub differs from a generic side quest in that it is tied to the main quest directly.  
      Continuous side-quests
      These are side-quests that evolve throughout the game, one unlocks the next, but they are also affected by external requirements such as story progress. This pattern is often found with party members in RPG games, where the player must befriend the party member to unlock their story quests.  
       
      Deadline
      As the name implies these quests are time sensitive. The task can be of any type, the important thing is that the quest fails if time runs out. This could also be used for a quest with a side quest where the side quest is timed for extra rewards but the main objective is not.  
       
      Deja-vu quests
      This kind of quest pattern gives the player a quest they have done or seen before. In some cases, this “new” quest will have a twist or something that sets it apart. It can also be the same sort of quest that exists in different areas of the game world, perhaps there is more than one goblin camp? or perhaps the player has to pick berries daily.  
       
      Delayed impact
      Delayed consequences of a previous decision. Often used in games where the story is important and the players’ choices matter. These quests are tied together without the player knowing. Let's say the player is set the optional task of giving a beggar some gold to feed himself. The player gives the beggar a few gold and is on his way. The next time he meets the beggar the beggar has become rich and rewards the player for his kindness with ten times what he gave.  
      One of many
      The player is presented with a number of quests, they have to choose which one to complete, they can only choose one. The others will not be available.  
       
      Hidden quests
      Hidden tasks that aren’t obviously quests at first glance or are hidden away for only the most intrepid players to find. This could be an item the player picks up with an inscription in it if the player then finds the person the inscription is about he can get a reward for delivering it. A good quest pattern for puzzles, these kinds of quests can really make the game world come alive and feel a lot more engaging, allowing the player to uncover secrets, Easter eggs and discover all of the world created for them   
      Moral dilemma
      Punish the bread thief who stole to feed his family? often used in games that have a good/ evil alignment level for the players, these kinds of quests make the player make a choice about what kind of character they want to play, they get to choose if their character is good or evil.  
       
      Side quests
      Optional quests, these quests are often found in level based games where the overall quest must be completed to get to the next level, the player can optionally do some extra tasks to get more points. The important part is that these are optional but they give the player a reward for, getting everything they can out of the game.  
       
      Tournament
      Tournament style quests, a series of quests that get harder as the player progresses. An example could be a gladiatorial arena if the player defeats five enemies one after the other he gets rewarded as the champion of the arena, but if for example, he fails at the third, the whole tournament is failed and he has to start all over from quest 1.  
       
      Vehicle missions
      Despite the name these quests are not confined to being about cars, these are simply quests where the players control scheme changes to complete the quest(s). An example could be; changing from running around in the game world to driving a tank to destroy a fort.  
      Quest superstructure - "The whole package"
      With quest superstructures, we are venturing into general game design. The superstructure is how the player is allowed to complete quests in the game world. It's basically a question of whether the game is “open world” or a linear experience.
       
      The diamond structure 
      The open world model, think games like The Elder Scrolls V: Skyrim, the player is introduced to the game through a quest, but after that, they can go wherever and do whatever quests they want. There are tons of quests of the above types and patterns, the player is free to pick and choose which to do, giving the player the illusion of freedom within the game world (the diamond). However, the game still ends by completing a quest that is locked and always a requirement to complete the game. This can, of course, be varied by different choices the player has made throughout the game or even have multiple endings. Quests can be concentrated into quest hubs, i.e. towns with lots to do or the like, but they don't have to be completed in a linear fashion  
       
       
      Linear hub structure
      This structure consists of a number of required “bridge” quests that need to be completed in order to unlock the next area or “hub”, each hub can have any number of quests, this could be a town full of people in trouble, each with their own quests and quest chains to complete, when they are all done, the player moves on to the next hub through another bridge quest. Limiting the quest size of the hubs will make the quest structure feel more linear and thereby the game linear, and creating larger more open hubs can make the player feel freer.  
       
      Outcome - "So many options!"
      The development of custom quest has been the quest to allow game developers to create quests and missions that use these types. However, no matter how well we have researched, some one will come up with a new and creative way of doing quests.
       
      The solution for us was to make the system more customizable. Letting users convert their quest prefabs to quest scripts that automatically inherits the core functionality, so the user can freely add their own additional functionality on top of the existing core
      Asset development as fuel - "A learning experience"
      Developing this way, splitting the production into sub systems that can function on their own and even be used by others is not something that should be taken lightly, but if you can build something lasting, something others can find value in using, then the final product will be all the better for it. Custom Quest started as a project we thought could be completed in a couple of months, it ended up taking 7.
      In part this is because we realised that if we were going to release the system, we might as well do it right, that meant creating a system that was customizable and robust, a system that can be added to the users game and not the other way around, a system we could be proud of.
      The experience of developing for other developers is quite different to developing a game. One that has made us much stronger as programmers and as a company, it forced us to think in new ways, in order to create a dynamic and customizable solution. Custom quest has evolved from an asset we could use in Quest Accepted, into a tool others can use to create a unique game experience. All in all, the experience has been a good one and Random Dragon is stronger for it, I would, however, recommend thinking about your plugin and extra time before you start developing.
       
       
      Sources:
      www.pcgamesn.com -"We know you aren't stupid" - a quest design master class from CD Projekt RED
      http://www.pcgamesn.com/the-witcher-3-wild-hunt/the-witcher-quest-design-cd-projekt-masterclass
      http://www.gamasutra.com/ - Game Design Essentials: 20 RPGs - http://www.gamasutra.com/view/feature/4066/game_design_essentials_20_rpgs.php?print=1
      Extra credits - Quest Design I - Why Many MMOs Rely on Repetitive Grind Quests https://www.youtube.com/watch?v=otAkP5VjIv8&t=219s
      Extra credits - Quest Design II - How to Create Interesting MMO and RPG Quests https://www.youtube.com/watch?v=ur6GQp5mCYs
      Center for Games and Playable Media - Situating Quests: Design Patterns for Quest and Level Design in Role-Playing Games - http://sokath.com/main/files/1/smith-icids11.pdf
      Center for Games and Playable Media - RPG Design patterns https://rpgpatterns.soe.ucsc.edu/doku.php?id=patterns:questindex
       
      Special thanks to Allan Schnoor, Kenneth Lodahl and Kristian Wulff for feedback, constructive criticism and background materials.
    • By ilovegames
      When we last saw the sunshine? ... It seems that ten years ago ...
      We both wanted to live under the warm sun, so we want to go ... 
      Having spent ten years in bins, people start an uprising. Rebellion for a place under the sun, which is now occupied by scary creatures .. When people are cornered, patience may be over. And it was over. Without hope of salvation without faith in victory, people are going to fight for own world 
      You - one of them, clean your city from hundreds of monsters and give of humanity hope of salvation on this night, full of hardcore and aggression!
      Download http://falcoware.com/NightAgression.php
       




    • By Ahrakeen
      Hello we are looking for a second coder to assit with our strategic roleplaying game. it's a unity based engine with the ORK framework.
      we hope to have someone help complete our prologue so we can turn this into a complete game.
       
      we are aiming for something close to children of zodiac or fire emblem. but heavily focused on magic and urban legends. 
      main issue we are facing is getting the combat aspects in place and tie it together with a visual novel package we aim to fit with this
    • By dobbey
      Who are you?
      We call ourselves Dobbey. Our team currently consists of two people.
      We are both early 20's and come from Germany. At the moment this is our hobby.
      What's the name of the game and what is it about?
      The game is called Insane and it is a 2D adventure puzzle game with horror elements.
      Insane is about a scientist who has been doing human experiments for years.
      His most successful experiment is number 73, which seems to be mentally labile.
      This experiment manages to flee one day but can't distinguish between reality and imagination.
      In this game you will find a creepy atmosphere with difficult and varied puzzles.
      What inspired you?
      The style of the game is inspired by Limbo. But we were also inspired by Jump 'n' Run games and movies.
      Of course, we have also our own elements like an inventory system, butterfly effect, the "INSANE" effect, using a QR-Code..
      Which program do you use to develop the game?
      We are programming it with Unity. In our opinion, it is the best program for indie games.
      And of course we are working with Photoshop to create the graphics.
      What platform will Insane be available on?
      For PC.
      How can I support you?
      Twitter:        http://bit.ly/20POkfM    
      YouTube:     http://bit.ly/2rLXoM0
      Instagram:   http://bit.ly/2qwU2bl
      Facebook:    http://bit.ly/2p3nwRQ
      Website:       http://bit.ly/2s8buqU
       

      Here you can see some of our screenshots.

       

      (You can find the animation on Twitter/Instagram.)
       

       

       

      (You can find the animation on YouTube.)

      What do you think about it?
       
      Yo can see more screenshots or videos on Twitter, Instagram or YouTube.
    • By Liquid1Phantom
      Hello, my name is Thomas and I am currently starting up a project. 
      The project is going to be a very hardcore, and tactical FPS that is similar to Escape from Tarkov. It will be made within Unity, and will be programmed in C#. Currently, I have a Unity project started, an organized Discord setup, and as well as a very organized Google Drive. The Google Drive has art references, and plenty of folders for organization. Lastly, the payment for this project will be solely rev-share as I have no money.
      I am looking for anyone who can contribute: 2D artists, 3D artists, composers, programmers, etc.
      If you would like to help out and be of use, please email me at: thomasmunson2277@gmail.com
      Alternatively, add my Discord: Thomas#3788
  • Popular Now