Jump to content
  • Advertisement
Sign in to follow this  
origil

Unique units - data types in an RTS game

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

Hey! I am in the design process of a flexible real time strategy game, in which the units will vary in AI, movement, abilities and etc... For example, a tank's movement routine will differ from a spaceship's movement routine in more than just the speed variable - it will be coded differently. In short, each unit will be unique, meaning different units will have different functions/methods to perform similar tasks. Now the question that comes to mind is which approach to take? Should I have a unit class that will contain all unit variables and a pointer to the 9 different movement methods [one for each unit]? Is this approach valid? Will having a unit class with 20 sets of methods for each task slow down the game drasically? Should I create a basic unit class and create a different subclass for each unit eventhough unit "ONE" can share its movement method with unit "TWO" and its shooting method with unit "THREE"? In case I haven't clearly expressed my problem, I'll just ask: Could having a class loaded with about 100 methods slow down the game? How would this affect the RAM? Should there be a larger amount of class types for different but similar units w/o class inheritance? - Might be good for programs but is it slower/faster for games? Input will be greatly appreciated.

Share this post


Link to post
Share on other sites
Advertisement
You could use a base class like this:


class MovableObject : public Object
{
public:
bool move( const Vector2D& targetLocation ) = 0;
bool attack( const Object& target ) = 0;
virtual ~MovableObject(){}
};



And then derive your Unit's classes from this base class and implement the routines. The MovableObject class is a derived class ob a base class called Object, because your game will contain different types of objects.

It's only a short example how you could approach your problem.

Another possibility is to script your units behaviour, but there you need a basic interface, too.

Share this post


Link to post
Share on other sites
How many different movement types can you possibly have?! O_o

Here's two alternate ways I can think of doing it: give each unit type a vector of "terrain attributes" - ie, how many movement points it costs to move on each type of terrain.

Alternatively, you could just give each unit a movement type flag, and work from there. Both of these methods, however, only have one move(..) function.

As per your questions about memory usage - member functions are not stored in class data, rather they act just like static functions except they get a this pointer automagically pushed onto the stack. Ergo, a billion instances' member functions will take up the same amount of memory as having only one.

The way I addressed obsenely large classes for instances of units in my never-made RTS was to divide up the stats of each unit into two classes: CUnitInstance and CUnitArchetype. CUnitArchetype contained all the data that was the same for every unit, like what kind of land it could go over, base attack, max HP etc.

Each CUnitInstance, therefore, was given a pointer to its appropriate CUnitArchetype. CUnitInstance referred to a specific unit in the game, thus it contained the HP/MP (current, not max), where it was, what it was doing, etc. Pretty much everything that changed. All the static information was stored in CUnitArchetype.

Personally, I thought this was a good solution because it took all of the redundant variables out of CUnitInstance, and since you only have 1 instance of CUnitArchetype per unit type per player, it saved a lot of memory, especially with a large amount of active units.

But then again, if you wanted each unit to have drastically different stats (ie, RPGRTS) this method probably wouldn't work to well. My RTS was modelled after Starcraft where each instance of a unit had the same attributes.

Whatever works. Good luck [wink]

Share this post


Link to post
Share on other sites
Is this game written in C++?

You could still use "traits" to define your behaviors, and have your Unit class instanciate these traits and forward the calls to them... example :

typedef CVehicle<CMoves360, CTurns360, CFires360> Tank;
typedef CVehicle<CMovesForward, CTurns360, CFiresForward> Jet;
typedef CHuman<CMoves360, CTurns360, CFiresForward> Civilian;

This is just an example...

and have something like :

template <typename Movement, typename Rotation, typename FireDirection> class CVehicle
{
protected:
Movement m_MovementController;
Rotation m_RotationController;
FireDirection m_FireController;
}

etc...

This way you let the template build all that messy code for you, and you only write and use specific classes without having to think about the exponential explosion of cases.

Hope this helps and that I was clear enough :/

Eric

Share this post


Link to post
Share on other sites
No, I believe it would take sizeof(class)*nrofinstances....

but check out virtual functions as the second poster suggested... they are exactly what you need! :)

Share this post


Link to post
Share on other sites
If I'm not mistaken, a class's functions aren't duplicated, but obviously the member variables are. So the "Move" function for an entity class is in memory only once, but the vectors for position is duplicated for each "entity" in memory.

Share this post


Link to post
Share on other sites
Thanks, everybody ;p.
Seem I'll have to use a bit of each - or a lot of each :).

Quote:
Original post by Mushu
As per your questions about memory usage - member functions are not stored in class data, rather they act just like static functions except they get a this pointer automagically pushed onto the stack. Ergo, a billion instances' member functions will take up the same amount of memory as having only one.


It's good to know the methods are not duplicated - that will save me a lot. About variables, for the first version I'll keep the classes packed so that a human could have a "fuel" variable eventhough it's not a vehicle... After all, I need to balance my spare time and efficiency as much as possible.

Quote:
Original post by xEricx
You could still use "traits" to define your behaviors, and have your Unit class instanciate these traits and forward the calls to them... example :

typedef CVehicle<CMoves360, CTurns360, CFires360> Tank;
typedef CVehicle<CMovesForward, CTurns360, CFiresForward> Jet;
typedef CHuman<CMoves360, CTurns360, CFiresForward> Civilian;

I think I'll use some of this for the AI, though that's still to come, I need to learn some more about templates, though it doesn't seem complex.

Quote:
Original post by Mushu
The way I addressed obsenely large classes for instances of units in my never-made RTS was to divide up the stats of each unit into two classes: CUnitInstance and CUnitArchetype. CUnitArchetype contained all the data that was the same for every unit, like what kind of land it could go over, base attack, max HP etc.


I guess it'd make the code easier to read, though I don't have time for these decisions now because I'm trying to go with flexibility rather than constant classes - I'll credit you on the second version of this game ;) when it's more organized after basing it on my experience from version 1 and when my children call me dad [assuming version 2 is years away]...

Anyhow, it's good to know the stream of advice flows rapidly and that the people on this community are always eager to help.
Thanks again all - And back to the code... ;)

Share this post


Link to post
Share on other sites
Humans don't need a fuel value.
If you have a RTSUnit class with things like speed etc as members, then you can derive a RTSVehicleUnit and a RTSPedestrianUnit for isntance. Each can then have the specialised member variables which it needs, and those virtual methods mean you can still work efficiently. Then you don't have members which have no meaning (like fuel for a foot-soldier), which shows bad design to anyone seeing your code.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!