Sign in to follow this  

Creating a subclass in place of instantiating...

This topic is 2047 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

I'm working on a game where I will manually construct a large number of Ship objects (100+), each with their own unique stats, but, of course, sharing the same properties and methods.

Someone suggested I should create a sub-class for each different ship to accomplish this, but this goes against my intuition. However, I don't know what would be bad about this approach either. This approach is tempting because I would be able to quickly access a particular subclass object with my IDE's auto-fill feature when I begin typing its name.

Is there a performance cost or disadvantage to creating sub-classes in this manner, where I could just create instances of the same class instead?

Share this post


Link to post
Share on other sites
If the differences are small, then just a single Ship class with properties just as Speed, Firepower, etc would be fine. For the different types of ship you'd store a set of default attributes, for example an XML file containing the starting Speed, Firepower, Hitpoints, etc.

For bigger differences, if I recall correctly the tool to help you here is the Strategy Pattern:
[url="http://en.wikipedia.org/wiki/Strategy_pattern"]http://en.wikipedia.org/wiki/Strategy_pattern[/url]

You have a general Ship class which has methods like Move, Attack, Defend, Retreat, etc, and then you can assign what those methods actually do at run-time. That means that different types of ship can use completely different code to perform each action. Once again you would store ship info in some way, e.g. an XML file, including the name of the method to use to Move, Attack, etc.

Share this post


Link to post
Share on other sites
Thanks for the quick reply.

I'm sorry but I didn't fully understand your suggestions. It sounds like I shouldn't create sub-classes of the Ship class and instead store different ships' default values in an XML file, regardless of the class' complexity.

I'm curious, why do you recommend storing default values in an XML file? It seems more convenient to simply hard code the default values into the program.

And, is there anything bad about creating sub-classes in this case?

Share this post


Link to post
Share on other sites
Creating subclasses won't have noticable performance issues (if any). For hundreds of ships, the main problem will be writing and maintaining all of that unnecessary code.

I would personally have a single class, and hardcode the different stats in a big array-of-structs for the first implementation and change it only if necessary. Doing the simplest thing that could possibly work is generally a good idea.

Share this post


Link to post
Share on other sites
[quote name='genjihl' timestamp='1336367772' post='4937969']Someone suggested I should create a sub-class for each different ship to accomplish this, but this goes against my intuition. However, I don't know what would be bad about this approach either. This approach is tempting because I would be able to quickly access a particular subclass object with my IDE's auto-fill feature when I begin typing its name.

Is there a performance cost or disadvantage to creating sub-classes in this manner, where I could just create instances of the same class instead?
[/quote]Both approaches have their own pros. In general, if the fields to be changed are just data, then it would be ideal to load them from a file and push them to a ctor.
As you noted, it is very handy to have a simplified subclass, just to build it with less ctor parameters, such as
[CODE]
class BaseShip {
...
public:
BaseShip(int param, string name, Behaviour attitude, Job task) { ... }
};
class MinerShip : public BaseShip {
public:
MinerShip() : BaseShip(0, "miner", b_peaceful, j_mine) { ... }
};
[/CODE]
This benefit is short sighted. I'm not saying it's worth nothing, but you see already what's the best thing to do: load them up from a file.
You might consider JSON as well. I use jsoncpp.

However, there are issues. What to do if we need to actually provide more logic? In that case the options are[list=1]
[*]Go for a subclass
[*]Turn code into data by using scripting
[/list]
In general, rather than providing switches at a base class level, I strongly suggest to refactor in a more component-oriented approach, by breaking each ship in more basic components. Then a ship would be something like a collection of those components so instead of using the data directly, you would use it to instance objects to be used instead of the ifs involved in switching behaviour... I don't know if I'm able to convey the concept today.

Share this post


Link to post
Share on other sites
Firstly, let's check we're on the same page. Do you mean that each Ship is unique, or are there types of Ships? My mental picture was for example, you have a small Fighter type, a large Dreadnought type, etc. The XML file (or whatever) would contain one set of stats for a Fighter, and one for a Dreadnought. You could then instantiate 30 Fighters and 5 Dreadnoughts based on those stats.

XML isn't required, it's just sometimes more convenient to be able to tweak the game without re-building it.

The disadvantage of subclassing too much is that you can add a cool feature to one subclass and then suddenly realise that you want the same feature in 4 more subclasses. You could copy and paste, which is bad for maintainability. Or you could do refactoring so they have a shared base class e.g. BigShip and LittleShip. But that can get complicated quickly, and often impossible in languages that lack multiple inheritance.

Plus sublclassing is fixed at compile time. With the approach that I'm suggesting, you could create a new ship type that uses bits and pieces of other ships' logic just by editing an XML file and providing new graphics. If you have an artist or level designer on your team who's not a coder, they likely won't want to edit code files and recompile to test their changes.

Share this post


Link to post
Share on other sites
Thanks for the help everyone. I'm beginning to recognize the benefits to loading ships' data from a file. I admit I'm not used to working this way, but I realize storing/loading data from files an important skill to have, so it's about time I get used to it.

To answer your question, jefferytitan, all of the Ship types are the same. There won't be any differences in behavior, only properties (health, shields, etc.). The class (or classes) would be used to produce multiple instances each, as you described (e.g. 30 Fighters, 5 Dreadnoughts).

I will go with your suggestion and try using XML to supply my Ship objects with their default data.

Share this post


Link to post
Share on other sites
Good luck. Do keep in mind that later in development you may want to move the data from a separate XML file to something harder to edit so players can't cheat at the game. As long as you have a relatively centralised place to read from the files it should be easy.

Share this post


Link to post
Share on other sites

This topic is 2047 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