Sign in to follow this  

Design pattern implementation

This topic is 664 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys,

This is my first post here on this forum, I have a question on design pattern implementation for my current project

In my game, i have 100+ achievements defined in a controller class. The user can complete achievements and each achievement has a reward attached to it.
i also have a view/screen where i want to display information about each achievement.

Amongst others, i have the following types of achievements:
- FinishCampaignAchievement
- BuyItemsAchievement
Both achievements are extended from the AchievementBase class

The FinishCampaignAchievement is an achievement where you need to complete a campaign to complete the achievement and obtain the attached reward
The BuyItemsAchievement is an achievement where you need to buy a specific item an x amount of times to complete the achievement.

My problem is in the view class where i want to display information about each achievement, because the information to be shown about the achievements is quite different for each class.
The view class is initialized with a collection of all available achievements (a List of AchievementBase instances)

For each BuyItemsAchievement i want to display information about the item which the user needs to buy, so i would like to keep a reference to an item and in the view i need to obtain this reference.
In the FinishCampaignAchievement i do not want to keep a reference to such an item, for i dont need it there

Furethermore, when i ask for the class type in code, i just get 'AchievementBase' for both the BuyItemsAchievement and the FinishCampaignAchievement

I would think that the proper place to store a reference to the item would be in the BuyItemsAchievement, and not in the AchievementBase

I have been reading some about the statement 'favor composition over inheritance' and i think that i should use this approach here, but i am not sure what would be the proper way to implement it

So finally my question:
What would be the proper way to implement making the distinction between these types of achievements and how do i obtain the reference to the item in the BuyItemsAchievement?
 

I would love to hear about your oppinions on this topic

Share this post


Link to post
Share on other sites

Personally i wouldn't use derived classes to represent your achievements.

 

This to me seems like an ideal part of a game for using a data oriented design, where the definitions of the achievements, their triggers, names and rewards are stored in an external script or data file.

 

This means you can add and test achievements without recompiling your code, easier debug them, and localize them if you want to change the language your game is displayed in. It also means that you could release new achievements easily via an updater, or through the web (and possibly even fetch them via a simple HTTP library).

 

The thing you'll have to give most thought to is how you represent the triggers and rewards, and this might lead on to embedding a scripting language such as LUA into your game.

 

Hope this helps!

Share this post


Link to post
Share on other sites

I believe that the best solution here would be to create a view class for each achievement type. I would create a BaseAchievementView interface that provides methods needed to draw the achievement's information to the main view. Subclasses would inherit these methods and implement the way they would be drawn in the provided methods. For example, the BaseAchiementView interface would contain the method "draw" which would be used by the main view to draw the information to it. You would create a new class called BuyItemsAchievementView which implements BaseAchievementView, and in the draw method you would draw the item and other information you would provide to the user. You would follow this template for the other achievement types. Then in the main view, instead of holding a collection of achievement types, hold a collection of the BaseAchievementView interface. This would encapsulate the drawing of each achievement and separate the functionality from the main view.

Edited by baseball435

Share this post


Link to post
Share on other sites


This to me seems like an ideal part of a game for using a data oriented design, where the definitions of the achievements, their triggers, names and rewards are stored in an external script or data file.

 

you mean "data driven design" there don't you?

 

 

i think beseball435 is on the right track there. you'll need a display screen / dialog / viewer for each different type of achievement.

 

start with your list of achievements, and the data each must track.

 

sort them into piles, based on the data they must track. these are your different types of achievements. each type will have "a data structure, and code that operates on it" (sound familiar?), including code for a "viewer".

 

and then you'll have a list of achievements, which might be just a vector of object pointers. or it may have some additional data structures, and corresponding code.

Share this post


Link to post
Share on other sites

Quickly off the top of my head:

class Achievement
{
    // Achievement description
    public string Text;

    // For ones that consist of purchasing multiple items (if not, Item is null)
    public Item Item;
    public int Number;

    // Code to evaluate whether or not the achievement is satisfied, or to make it satisfied
    public IEvaluateAchievement AchievementLogic;

    // Type of view to instantiate to visualize this achievement 
    public Type View;
};

From your description, you just have two types of achievements (regular, and buying a certain number of items). So I don't know if that really merits a complex inheritance hierarchy. Just plop all that's needed into a single Achievement class.

 

Instead of specifying the View class to instantiate (as I implied above), you could leave that up to your UI code, which could inspect the type of Achievement it is and render it in the most appropriate way (e.g. if Item is not null, then use the "need to purchase n items" rendering path).

Share this post


Link to post
Share on other sites

Hi again guys,

I really appreciate all the answers given so far, they are all good in my opinion and gave me stuff to think about.

I think baseball's solution is the most clean, considering separation of view and controller and i am going to give it a try.

Phil, thanks for the code snippet. i do intend to make more types of achievements, but i wanted to keep the description of my problem to a minimum.
What i like most about your solution is that all information for a new type of achievement is kept together in one class

Thanks everyone!

Share this post


Link to post
Share on other sites

Quickly off the top of my head:

class Achievement
{
    // Achievement description
    public string Text;

    // For ones that consist of purchasing multiple items (if not, Item is null)
    public Item Item;
    public int Number;

    // Code to evaluate whether or not the achievement is satisfied, or to make it satisfied
    public IEvaluateAchievement AchievementLogic;

    // Type of view to instantiate to visualize this achievement 
    public Type View;
};

From your description, you just have two types of achievements (regular, and buying a certain number of items). So I don't know if that really merits a complex inheritance hierarchy. Just plop all that's needed into a single Achievement class.

 

Instead of specifying the View class to instantiate (as I implied above), you could leave that up to your UI code, which could inspect the type of Achievement it is and render it in the most appropriate way (e.g. if Item is not null, then use the "need to purchase n items" rendering path).

 

This would be a valid option but it couples the Achievement model with the controller and view. It's better to decouple them, following the MVC pattern, and encapsulate the functionality of each so that one isn't dependent on another.

 

Hi again guys,

I really appreciate all the answers given so far, they are all good in my opinion and gave me stuff to think about.

I think baseball's solution is the most clean, considering separation of view and controller and i am going to give it a try.

Phil, thanks for the code snippet. i do intend to make more types of achievements, but i wanted to keep the description of my problem to a minimum.
What i like most about your solution is that all information for a new type of achievement is kept together in one class

Thanks everyone!

 

Goodluck!

Edited by baseball435

Share this post


Link to post
Share on other sites

This topic is 664 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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