Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
The upgrade system
The basic idea
Upgrades are implemented by
- first identifying the actor which will be using the modifiable behavior.
- If the fundamental behavior is already implemented in an actor's trait, consider modifying the trait to work with the upgrade system. Otherwise create a new trait that will implement the fundamental and modified behavior using the upgrade system.
- The trait, that will define the upgradable behavior, will need to implement the
- The behavior of the upgradable trait is to be made dependent on some number (usually one, but may be more if deemed necessary) of non-negative (usually small) integer parameters. These parameters are called upgrades in the continuation. Upgradable traits may specify upper bounds for the upgrades to signal absence of modified behavior for out-of-bounds values. Note that these upper bounds are allowed to change in time.
As a simple example, consider implementing a trait that provides upgradable firepower for an armed unit. The used upgrade might be called
firepower and its upper bound set to
4. The trait would then use the current value of the upgrade
firepower to decide by how much to modify the unit's weapon's damage, e.g.
firepower == 0, do not modify;
firepower == 1, increase by 10%;
firepower == 2, increase by 15%;
firepower == 3, increase by 20%;
firepower == 4, increase by 30%;
For values of
firepower > 4 there would be no change of behavior with respect to the case
firepower == 4. Thus a constant upper bound should be used to signal the futility (or inability) of further trying to augment the upgrade.
Implementation: upgradable trait
The upgradable trait specifies the names of upgrades it wishes to use through the
UpgradeTypes property. It specifies the upper bounds for these upgrades during calls to the function
AcceptsUpgradeLevel by saying whether or not the proposed value (passed as an argument) for the upgrade is within the usable range. When any of the upgrades has its value changed, the trait is notified of changes through the
Note that upgrades are parameters defined on the actor level. Thus at a given point in time all upgradable traits using upgrades with the same name will see the same value of the upgrade (through the notification method).
Examples: upgrade consumers
Upgradable traits are also referred to as upgrade consumers.
firepowerexample is actually one taken from this trait. Similar functionality is present in this trait using the
This class is imagined as a base class for upgradable traits that might not wish to use the full parameter flexibility as described above, but only wish to depend
- either on a single non-negative bounded integer parameter defining the trait's modification level,
- or on a single Boolean parameter defining whether or not the trait is activated.
The trait's modification level is defined as the sum of values of all upgrades that the trait uses. The latter Boolean parameter is obtained as a function of the modification level. Normally an upper bound for the modification level is specified and is used to reject further increments of the individual upgrades.
UpgradeOverlay : UpgradableTrait
When enabled, changes the palette used to render the actor's sprites.
InvulnerabilityUpgrade : UpgradableTrait
When enabled, makes the actor invulnerable.
Cloak : UpgradableTrait
When enabled, makes the actor invisible.
DisableUpgrade : UpgradableTrait
When enabled, makes the actor immobile.
Implementation: upgrade manager
The upgrades' values are handled exclusively by the actor's
UpgradeManager trait. The upgradable traits attached to an actor without this trait will not be used and are considered bogus.
To change the value of an upgrade for an actor, it is necessary to call that actor's
UpgradeManager.RevokeUpgrade in order to increment or decrement, respectively, the upgrade's value. It is not possible for a calling object to revoke more upgrades than it had granted. Consequently, upgrades will never have negative values.
To temporarily increment the value of an upgrade for an actor, use
UpgradeManager.GrantTimedUpgrade. To receive notification on the remaining duration of the timed upgrade, use
To check if granting a certain upgrade would leave at least one upgrade consumer with non-violated corresponding upper bound, use
Examples: upgrade providers
Traits that interact with an actor's upgrade manager are called upgrade providers.
Defines a support power that, when charged, grants upgrades to targeted actors.
Makes the possessing actor grant upgrades to surrounding actors.
Grants upgrades to actors in the warhead's impact range.
Grants upgrades to possessing actor when certain tech tree prerequisites are met. Requires
GlobalUpgradeManagerto be defined on the