-
Notifications
You must be signed in to change notification settings - Fork 3
Ember Conflict Ability System
Attribs are float values, they have a readonly default value, the actually runtime value will be calculated from the default value, and the buffs applying to this particualar attrib.
All builtin attrib keys are defined in Battle/Common/Squads/SquadConfig.cs, the ones start with ATTRIB_SHARED_ are shared attribs, means the current value will be synchronized to the clients, the ones start with ATTRIB_SERVER_ will be only available on the server side. The fallback default values (if you didn't specify in the all_squads.json file) can be found in GetSharedAttribFallbacks() and GetServerAttribFallbacks(). You can give each squad type a different default value in the all_squads.json.
Buffs are the only way to change attribs' value in the system, each buff has following properties:
- key: a unique identifier for this key, note that only one buff can be added with same key
- attrib_key: which attrib value this buff is changing
- factor: default as 1
- delta: default as 0
The value of the attrib will be OLD_VALUE * factor + delta, Note that the order of current added buffs may change the value, also that if you just want a new value, you can use factor = 0, delta = NEW_VALUE
States are used for values that can be one of several states (Enum in C#)
All shared state keys are defined in Battle/Common/Squads/SquadData.cs the ones start with OWNER_STATE_ are only synchronized to the owner of the squad.
All server only state keys are defined in Battle/Server/Squads/SquadCharactor.cs
The type of states are important, it can only accept a valid value of that type.
Vars are used for other more flexible values, they can have any type, though in the ability system, only string and float types are used at the moment.
All shared var keys are defined in Battle/Common/Squads/SquadData.cs the ones start with OWNER_STATE_ are only synchronized to the owner of the squad.
All server only var keys are defined in Battle/Server/Squads/SquadCharactor.cs
Triggers are runtime concepts, similar to events, though they are specific related to the charactor simulation.
When something happened, a trigger can be fired with proper information, any logic that register itself as a trigger listener with this specific kind of trigger will be notified, so logic can be run accordingly.
All builtin trigger kinds are defined in Battle/Server/Squads/SquadConsts.cs
Builtin triggers are specific, developers will need to write codes to support them.
Custom triggers are generic, mainly watching attrib/state/var changes, designers can create custom triggers with the ability system, more details can be found in the Trigger Watcher section.
When an ability related trigger been fired, a list of squads will be identified (by Trigger Finders and Trigger Filters, see details below).
These squads will be used as the targets of spells in this ability.
Spells means a sequence of certain operation (sub tasks), e.g. a MeleeAttackSpell will change melee state to Striking, after proper delay, deliver the damage, change melee state to CoolingDown after proper dalay later.
Most of the squad runtime data will be only changed in spells in the current system (except updates by TickTasks, either caused by user input or AI behaviour)
All builtin spell keys are defined in Battle/Server/Squads/SquadConsts.cs
In ability system, only AbilitySpells can be used, the keys are defined in Battle/Server/Squads/AbilityConsts.cs
Skills are used to create special logic for specific squad type, it's the most powerful way, though it's the least flexible way at the same time, create new skill or modify existing skill must be implemented by developer individually, so we'll only create skills when a similar effect can not be archieved with more general way (with trigger/targets/spells)
Usually what's done in skills are creating ticktasks for periodical logic, and/or create custom trigger listener for event-based logic that require a specific trigger type.
In other cases, it's more suitable to create a spell type, and let the game designer to link trigger and targets to it.
"some_config_key": "{string}"
This format will be used for simple string value.
"some_config_key": {float}
This format will be used for simple float value.
"some_config_key": {int}
This format will be used for simple int value.
"some_config_key": {bool}
This format will be used for bool value, only true or false are valid values.
"some_config_key": "{attrib}"
"some_config_key": <attrib>
This format will be used for attrib/float value, if the value is a string, it will be treated as the attrib key, the attrib value will be used at runtime, it's the value is a float, it will be used directly.
"some_config_key": "{buff}"
[amount]: <amount>
This format will be used for amount value, which has two formats, can either has a amount, or a pair of averrage and range.
only
"amount": <attrib>
amount_value will be used as the amount.
"average": <attrib>
"range": <attrib>
A random value between average - range/2 and average + range/2 will be used as the amount.
"checks": [checks]
one example:
"checks": [{
"left": "OLD" or "NEW" or <attrib> or {float} or "{string}"
"op": "{op}"
"right": "OLD" or "NEW" or <attrib> or {float} or "{string}"
}]
The actual format of the value depends on the type of the value, e.g. it might be the name of states.
"op": "{op}"
"value": <value>
The actual format of the value depends on the type of the value
If the value type is followed by ?=, means this config is optional, the default value will be after e.g.
"one_config_key": {float} ?= 1.0
"another_config_key": <attrib> ?= "test"
Following is a full example of ability syntax, you can specify multiple abilities for one squad, see following sections for details.
For each ability, you don't need to define all sections, but each ability should has at least on of the following:
- overwrites
- defines
- skills
- triggers + targets + spells
"abilities": [{
"overwrite": {
"melee_mitigation": 0.5
},
"define": {
"doctor_heal_amount": 80
},
"skills": [{
"type": "repeat_trigger",
"interval": 2.0,
"kind": "doctor_heal"
}],
"triggers": [{
"type": "custom",
"kind": "doctor_heal"
}],
"targets": [{
"type" :"constant_sensor",
"radius": 4,
"side": "team"
},{
"type": "self"
},{
"type": "wounded"
}],
"spells": [{
"type": "heal",
"key": "doctor_heal",
"visual_key": "heal_aura",
"amount": "doctor_heal_amount",
}]
}]
"overwrite": {
"melee_mitigation": {float}
}
This is used to set a different value of attrib, technically a new buff will be created to ensure the new value is the result after applying that buff.
The key of each entry will be used as the attrib's key, the value should always be a valid float number.
Notes:
- A special buff key will be used for overwrite, if multiple overwrites exist for same attrib, the last one with be used.
- There is nothing to stop further buffs added later to change the attribute to other value, so be careful with other buffs on the same attrib. e.g. a spell triggered by some trigger can add a buff in the runtime.
"define": {
"doctor_heal_amount": {float}
}
This is used to create custom attrib, which can be used later in skills or spells, the most use cases will be to let other ability to apply buffs to this attribs, e.g. a special gear for doctor can boost the heal amount.
Only define attrib when you need, for the one time used abilities, probably the best way is to use direct float value instead.
The key of each entry will be used as the attrib's key, the value should always be a valid float number.
"key": "{string}" ?= "" //If you want to enable/disable this skill with spell, need to provide a unique key
"enabled": {bool} ?= true
"type": "repeat_trigger"
"interval": {float} //how many seconds between each trigger
"kind": "{string}" //this will be used as trigger_kind in trigger watcher
"number": {int} ?= -1 //the number of maximun number of triggers sent, < 0 means infinity
"delay": {float} ?= 0 //how many seconds before sending the first one
"type": "consume_soul"
"type": "leech_health"
[amount]: <amount> ?= 0.2 //factor of health got (multiple with the actual damage)
"kind": "{string}" //the trigger's kind
"type": "builtin"
only the trigger kinds defined in SquadConsts.cs can be used here.
"type": "spell"
Note that trigger_kind can only be one of the following value:
- "spell_start"
- "spell_end"
"type": "custom"
This should be used with custom triggers defined by other abilities, e.g. by Repeat Trigger Skill
"type": "melee_attack_state_changed"
"checks": [checks]
"type": "ranged_attack_state_changed"
"checks": [checks]
"type": "path_state_changed"
"checks": [checks]
"type": "bool_state_changed"
"key": "{string}" //key of the state
"checks": [checks]
"type": "float_var_changed"
"key": "{string}" //key of the var
"checks": [checks]
"type": "str_var_changed"
"key": "{string}" //key of the var
"checks": [checks]
"type": "attrib_changed"
"key": "{string}" //key of the attrib
"checks": [checks]
"type": "buff_added"
"key": "{string}" //key of the buff
"type": "buff_removed"
"key": "{string}" //key of the buff
"type": "line_distance"
"option": "{string}" //one of "travelled", "remaining", "target_remaining"
"checks": [checks]
"type": "self"
"type": "trigger"
"type": "constant_sensor"
"radius": {float}
"type": "dynamic_sensor"
"radius": "{attrib}"
"type": "remote_constant_sensor"
"radius": {float}
"type": "remote_dynamic_sensor"
"radius": "{attrib}"
"type": "wounded"
- TODO
- TODO
- TODO
- TODO
- TODO
- TODO
- TODO
- TODO
- TODO
- TODO
- TODO
- TODO
- Not Implemented
"key": "{string}" //spell key, only one instance of each key can be active at single time, need to be unique
"visual_key": "{string}" ?= "" //the key to use in client side to display visual effects, which will be defined in effects.json
"delay": <attrib> ?= 0.0 //How many seconds before the spell take effect
"type": "buff"
"key": "{buff}" //Note this will be used as both spell key and buff key
"attrib_key": "{attrib}"
"factor": <attrib> ?= 1.0
"delta": <attrib> ?= 0.0
"duration": <attrib> //How many seconds between add and remove
"type": "add_buff"
"buff_key": "{buff}"
"attrib_key": "{attrib}"
"factor": <attrib> ?= 1.0
"delta": <attrib> ?= 0.0
"type": "remove_buff"
"buff_key": "{buff}"
"type": "damage"
[amount]: <amount> //max damage
"type": "heal"
[amount]: <amount> //max health to heal
"type": "wear_cloak"
"type": "take_off_cloak"
"type": "enable_skill"
"skill_key": "{string}"
"type": "disable_skill"
"skill_key": "{string}"
"type": "skill_on"
"skill_key": "{string}"
"duration": <attrib> //How many seconds between enable and disable
"type": "skill_off"
"skill_key": "{string}"
"duration": <attrib> //How many seconds between disable and enable
"type": "enable_spell"
"spell_key": "{string}"
"type": "disable_spell"
"spell_key": "{string}"
"type": "mute_spell"
"spell_key": "{string}"
"duration": <attrib> //How many seconds between disable and enable