Skip to main content
GameDev.net gamedev.net
🔒 Locked

RTS Upgrade System

Started by tyggerr Dec 3, 2016 at 8:05 PM 2 replies 2.1k views
Original Post
tyggerr
tyggerr

Hi!

So as the title suggest I'm currently working on updating a RTS-style game (Its not pure RTS, but there's lots of mechanics from it). Actually, I'm in the process of overhauling the Tech Tree / upgrade system. However, I found out that the old system we use at the moment is hard-coded for everything. This means that if I want to increase damages for towers for example, I have to check if the player has a specific tech and then changes the values as I see fit.

Something like


if(hasTechnology(TechEnum.ARTILLERY) {
  damages += ARTILLERY_BONUS_DAMAGES;
}

There are some technologies that simply add modifiers but some also change the behaviors of units/structures. (Like unlocking the siege tank ability in StarCraft 2). So my question is how would you implement a system like this without having to hardcode techs/upgrades in the code? My initial idea was to create multiple Interfaces that I'd implement on the various Structures/Units and the techs would simply interact with these interfaces. My implementation didn't work too well since I ended up with a ton of interfaces and most of them were simply used for one specific line of code.

Thanks for your time :)

Tyggerr

TheChubu
TheChubu

A modifier can be as straightforward as a Consumer, where you would implement it like:


public enum UnitTech {

  IMPROVED_WEAPONS_1(u -> u.damage *= 1.05),
  IMPROVED_WEAPONS_2(u -> u.damage *= 1.15),
  IMPROVED_ARMOR_1(u -> u.defense *= 1.05),
  IMPROVED_ARMOR_2(u -> u.defense *= 1.10);

  private final Consumer<Unit> modifier;

  public UnitTech(Consumer<Unit> modifier){
    this.modifier = Objects.requireNonNull(modifier);
  }

  public final void apply(final Unit unit){
    this.modifier.accept(Objects.requireNonNull(unit));
  }
}

Then an Unit could have a list of modifiers or something like that, where you'd iterate over it and apply them.

Although thinking a bit, some modifiers with bigger scope (ie, "all ranged units have 10% more range), could be stored somewhere in a list of per-player modifiers, and applied when an unit gets created, rather than storing the same modifier in each unit all the time.

Then you'd have per-unit modifiers that are used when say, terrain gets rough, or some unit applies a negative effect on close enemies. Those would get added/removed on a per-unit basis.

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"   My journals: dustArtemis ECS framework and 
WoopsASword
WoopsASword

A basic "upgrade" can be made of basic inheritance and composition.

A class that holds your object:
class Something {

IMyObject _obj;

}

class First :IMyObject { ....} // This is the "first" level.

class Second : IMyObject {....} // This is the second level.

somewhere in the code:

_obj = new Second(); ...

// Over simplified by you get the point.

A second approach is to use decorators,

class Buff {

private :

Buff mDecoratorBuff;

void Apply(){

// Something

mDecoratorBuff.Apply();

}

}

So you can apply buffs (or upgrades) as you wish, and each applies its own properties.

These are just examples, apply them carefully to your situation.

tyggerr
tyggerr

Thanks for the input guys, I'm currently going with a system a bit similar to what TheChubu suggested, where units have a list of Modifiers that can be added/removed as I see fit and each of them can change values on the unit.

I never used Consumer before so I got lots of implementation ideas by looking at how it works, thanks a lot!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.