Generally in a rogue-like the actions of a unit can be modified so the gameplay is unique to the circumstances of that specific run. In Ransacked there are two types of gameplay modifiers: stat modifiers and attack modifiers. Modifications will generally come through items and abilities.

Stat Modifiers

Stat Modifiers are simple but give us a good scaffolding for building more complex mechanics. To leverage the systemic nature of the game's architecture, we want to be able to write the logic for the modifiers in any system.

Take for example, we have an item that adds to your unit's health. In the simplest possible way we can do this:

Notice how the parameter is the whole stat object. This allows us to make modifications from the base values as well.

To expand on the idea, let's say the item gives the unit a bonus to its health depending on how many other units have that item.

Stat Modifications are cached so we don't have to calculate the modified value every time we need it, only when it has been altered. If our item count has been changed, we raise a stat altered event like so:

To register and unregister these methods from the modifier stack we use these events

In both cases, the event's arguments include the entity whose stats are being modified and the method of modification. The registering event can also take an integer as shown here. This is a sorting index. With this we can dictate a method's position in the stack.

Attack Modifiers

Syntactically attack modifiers work nearly in the same way. Unlike stats, we're not just modifying a value, any kind of action can take place in the attack modifier stack. A few examples would be:

  • An item that gives a chance to shoot a rocket at a random enemy every attack.
  • An ability that gives you a temporary speed boost if you get a crit.
  • A shield item that shocks nearby enemies if you get hit.

These are incredibly varied actions but are very easy to implement with the modifier stack. To get these situtation based events, the modifying method is registered with two filtering variables: the attack source and the attack stage.

The attack source is a bitmask used to filter modifier methods based on where the attack is coming from.

The attack stage is used to separate the modifications into distinct timings.

The hit stage is also the on-hit stage for the target entity.

Putting it all together we can compound all kinds of effects and actions to make every run of the game different and exciting. We have the ability to make as large a system as we desire for any modification while keeping it organised and easy to test and integrate.