-
Notifications
You must be signed in to change notification settings - Fork 0
Designer: How Does Combat Work?
This page is under construction and subject to frequent change
TXEngine's Combat System is turn-based. Combat is highly configurable and supports a wide variety of effects.
There are several conceptual components that integral to TXEngine's Combat. Here we will go over the most important two.
All participants in Combat are known as Combat Entities. A Combat Entity has the following properties:
- A name
- A descriptions
- One or more Combat Resource
- An Inventory
- Zero or more pieces Equipment
- Zero or more Abilities
- Speed
- Level
- XP Yield
- A record of which Combat Effects have been applied to it
Combat must contain:
- The player
- One or more hostile Combat Entity
Combat may also optionally contain one or more friendly Combat Entity.
TXEngine's Combat System makes extensive use of Combat Effects. These effects are used to simulate a variety of in-game scenarios such as being burned, poisoned, or healed. Combat Effects are highly configurable and very flexible. There are even Combat Effects that can add or remove Combat Phases from a Combat Entity's turn!
A Combat Effect has the following properties:
- A trigger message
- A cleanup message
- A duration of either -1 or a number greater than 0
- Zero or more configuration values (determined explicitly by each specific type of Combat Event)
- A discrete executable function
- A trigger phase
A Combat Effect with a duration of -1 lasts indefinitely, while a Combat Effect with a duration greater than 0 may only trigger that many times before it is removed from the its owner.
There is a deterministic ordering to the way things happen in Combat. At the macro scale:
- Start of Turn Cycle
- Determine Turn Order
- Execute Turns
- Go to Step 1
Lets get into more detail.
Combat is an infinite loop that only terminates when at least one End Condition is met. The default End Condition is:
- Win: All hostile entities are dead
- Loss: The player is dead
Combat is sub-divided into turn cycles. Each turn cycle is further sub-divided into turns. The ordering of a turn cycle's turns is determined by the relative speeds of all Combat Entities participating in Combat. The Combat Entity with the highest speed goes first, while the Combat Entity with the lowest speed goes last.
Each turn is divided up into a discrete set of Phases. While these phases may be altered, the default ordering of the phases is:
- Turn Start Phase, Pre-Action Phase, Action Phase, Post-Action Phase, End-of-Turn Phase
Phases are very important to the way Combat Functions, as they control the timing for the execution of Combat Effects. A Combat Effect is triggered when the entity it's applied to (also known as that Combat Effect's owner) passes through a phase. For example, a Combat Effect with a trigger phase of Pre-Action executes when its owner reaches the Pre-Action phase during their turn.
The Action Phase is the most important Phase in Combat. Unlike any other Phase, the Action Phase is the one where each Combat Entity must choose what it wants to do during its turn. A Combat Entity may choose to use an Item, or use an Ability. If a Combat Entity cannot do either, its turn will simply be skipped. TXEngine supplies a built-in NPC AI.
Note that no Combat Effects, even if assigned, will trigger during the Action phase.
After making a choice as to what to do during the Action phase, the choice is then immediately executed. Any Ability selected is performed, and any Item selected is used.
TXEngine's combat math is fairly straight-forward. When used, an Ability's damage
values is used as our base damage value. Then, for each target we calculate total armor and total resistance to that Ability.
FINAL_DAMAGE = (DAMAGE - TOTAL_ARMOR) * (TOTAL_RESISTANCE)
TOTAL_ARMOR: The sum total of the damage resistance values of all `Equipment`
TOTAL_RESISTANCE: The rolling sum of all tag resistance values on all `Equipment`.
To calculate the rolling sum, obtain all resistance values and sort them in descending order.
SUM = RESISTANCES[0]
FOR EACH RESISTANCE IN RESISTANCES FROM 1 TO END:
SUM = SUM * (1 + RESISTANCE)
So for an Entity that has a valid tag resistance of [0.50, 0.20, 0.10]
the Total Resistance value is 50 + 10 + 6 = 66
.
Combat Effects can only be applied to a Combat Entity in two ways:
- If the entity is a target of an Ability
- If the entity is wearing equipment that contains a Combat Effect
When a Combat Effect is applied, it is stored inside the Combat Entity's data. That entity is then-on known as that Combat Effect's owner. During Combat Entity's turn, all Combat Effects that it owns are executed when the appropriate Turn Phase is reached. After a Combat Effect is triggered, it is checked to see if it has triggered its maximum number of times. If said Combat Effect has reached its maximum number of triggers, it is removed from its owner.
Note that an Ability only applies its Combat Effects to the target(s) of the ability. An Ability cannot apply its Combat Effects to its caster and some other specific target. For example, any Ability that has a target mode of "single hostile" will only ever apply Combat Effects to the hostile entity it targets, never to its caster.
After combat ends, there are several optional triggers including XP dispersment and item drops (known as loot).
Loot is governed by the LootableMixin
class and is generated in a two-step process.
-
How Many
Item
s are Dropped?The number of items dropped is determined by the
drop_table
. Thedrop_table
is essentially a list of1000
int
s, where a random int is selected from it to determine how many items are dropped. As the game designer, you need to designate the probability that a specific number of items will drop. For example:-
0 : 0.5
(500
instances of0
in the list) -
1 : 0.25
(250
instances of1
in the list) -
2 : 0.2
(200
instances of2
in the list) -
3 : 0.05
(50
instances of3
in the list)
At this point, a random number between
0
and999
is generated. This value is indexed against the list ofint
s that form thedrop_table
and the resulting number is how manyItem
s are dropped.Note: The resolution of the loot table is limited to 1/1000, so the smallest probability allowed is 0.001.
Note: The sum of the probabilities is exactly
1.0
. This is a requirement for the loot system to function properly. -
-
Which
Item
s are Dropped?This phase functions much the same as the previous, though instead of having a list of quantities we have a list of item IDs.
For each of the
n
Item
s dropped, select a random number from theloot_table
list. Theint
selected represents the ID of theItem
that should be looted.