Archived on 2026-10-24. The Godot rewrite is cancelled. Migration decisions and work checklists below are withdrawn. Original claims, code examples, file paths, and completion statements have not all been revalidated. Use the current documentation and issue register for maintenance decisions.
Ability System Analysis¶
Purpose¶
The current ability system determines which abilities a player has, when they activate, cooldown/stamina behavior, and the actual effects: dashes, shields, weapon changes, projectiles, buffs, companion spawns, and damage modifiers.
This is the most important system to redesign. The current AbilityHolder should not be copied directly.
Current Unity Implementation¶
Main scripts:
| Path | Script | Role |
|---|---|---|
Assets/Script/Game/Entities/Player/Core/AbilityHolder.cs |
AbilityHolder |
Per-player ability list plus most ability behavior. |
Assets/Script/Game/Utilities/AbilityFunction.cs |
AbilityFunction |
Singleton helper for adding/checking abilities, cooldown coroutines, effect/potion queues. |
Assets/Script/Shared/ScriptableObjects/Ability.cs |
Ability |
ScriptableObject with AbilityType, cooldown, stamina, and runtime cooldown fields. |
Assets/Script/Shared/ScriptableObjects/Upgrade.cs |
Upgrade |
Upgrade data can reference an Ability; EQUIPABILITY adds it to player list. |
Assets/Script/Game/GameSystem/Upgrades/UpgradeFunction.cs |
UpgradeFunction |
Hardcoded upgrade effects and ability registration. |
Assets/Script/Game/Entities/Player/Weapons/PlayerWeapon.cs |
PlayerWeapon |
Weapon firing and many ability hooks/attack modifiers. |
Assets/Script/Game/Entities/Player/Combat/PlayerAttack.cs |
PlayerAttack |
Projectile/hitbox damage behavior and ability flags. |
Assets/Script/Game/Entities/Player/Combat/PlayerAttackCarrier.cs |
PlayerAttackCarrier |
Carrier projectiles for bombs, rockets, airstrike, explosions. |
Assets/Script/Game/Resources/AbilityResources.cs |
AbilityResources |
Shared visual effect prefab references. |
Key Data¶
Ability ScriptableObject fields:
| Field | Meaning |
|---|---|
type |
AbilityType enum id. |
cooldownTime |
Base cooldown. Mutated by some runtime code. |
staminaCost |
Stamina cost. Mutated by dash runtime code. |
isOnCooldown |
Runtime cooldown flag stored on asset. |
currentCooldownTime |
Runtime cooldown timer stored on asset. |
AbilityHolder key fields:
abilities: unlocked ability list. Starts with character ability after player initialization.- Dash fields:
dashSpeed,dashForce,isDashing,dashAudio. - Character ability state groups:
- Knight:
knightProtoBarrier,KnightCurrentDmgThreshold,KnightLongSlashChance, etc. - Soldier:
soldierFrenzyEffect,SoldierFrenzyCDModif,SoldierDashReloadPercentage, etc. - Archer:
archerArtemisArrow,ArcherAttackToLusterBurstCount, etc. - Miner:
minerGem,MinerGroundBreaker*,MinerAssuredCrit*. - Star Wanderer:
zenovaStarBurstChargeIndicatorEffect,zenovaMissileCarrier,Zenova*. - Celestial: sword prefabs, rotator, sword counts, lightning behavior.
- Priestess: orb prefab, tidal veil object, orb/veil counters.
- General ability/effect state: shield objects, roll effects, rage/frenzy/focus/tactical flags, meditate state, war cry, airstrike, judgement, etc.
AbilityType enum contains over 90 entries. It covers dash, character abilities, special upgrades, boss upgrades, evolved upgrades, and in-progress abilities.
Runtime Flow¶
Registration¶
- Player prefab has an
AbilityHolderwith a serializedabilitieslist. AbilityHolder.Start()initializes many character/general ability fields to defaults.PlayerSettingsAbilityFirstTime()waits forGameInitialization.Instance.characterInit.- It adds the selected character's
Character.abilityto the player'sabilities. - It resets cooldown flags for all abilities in the list.
- It runs initial setup for abilities such as ProtoBarrier, SkyYingSword, and AbyssOrb.
- Later, upgrades add abilities through
UpgradeFunction.SelectUpgradewhen an upgrade entry isEQUIPABILITY. AbilityFunction.AddAbility(ability, abilities)appends theAbilityScriptableObject and resets its cooldown flags.
Activation¶
AbilityHolder.Update() polls many activators every frame:
- Dash input.
- Soldier Frenzy.
- Archer Artemis Burst.
- Knight ProtoBarrier.
- Star Wanderer Rocket Barrage.
- Celestial Yang Sword.
- Light Blessing.
- Ultra Magnet.
- Survival Instinct.
- Stellar Shield.
- Transcend/Eclipse.
- War Cry.
- Meditate.
Other activators are called from player/weapon/damage events:
PlayerWeapon.FireWeapon()calls ProtoSword, NeoSword, LusterBurst, GroundBreaker, CCombo, Assassination, Berserker Blood, SureFire, Unsteady Hand, BloodThirst, Rebuke, and weapon spawn modifiers.Player.TakeDamage()calls shield/block/reflect/revive/final form/first aid/flee boots/panic frenzy/ET armor/jet propulsion/enrage/emergency barrier logic.PlayerCollectItemcalls item and potion ability effects.
Cooldown¶
AbilityFunction.UseAbility:
- Finds the ability by
AbilityTypein the player'sabilities. - Returns if missing.
- Returns if on cooldown unless
bypassCooldownis true. - Starts
CooldownTimerunless bypassing. - Starts the ability coroutine.
CooldownTimer:
- Sets
ability.isOnCooldown = true. - Starts a
CurrentCooldownTimercoroutine that decrementscurrentCooldownTimeevery 0.1 seconds. - Waits 0.5 seconds, then waits
(ability.cooldownTime - 0.5) * CooldownModifier. - Sets
isOnCooldown = false.
Important issue: cooldown state is stored on Ability ScriptableObjects. If the same asset reference is shared between players, cooldown state can leak across players unless each player has unique runtime instances. Unknown / needs manual confirmation.
Ability Levels¶
There is no generic ability-level system in Ability.
Ability progression is handled through several indirect mechanisms:
- Upgrades can be taken multiple times using
Upgrade.maxUpgradeandupgrade.upgradeTaken. - Basic stat upgrades stack through
PlayerModifier. - Weapon level is tracked in
PlayerModifier.finalWeaponLeveland changed byUpgradeList.WEAPONLEVELUP. - Character weapon evolution is driven by
WeaponEvoData. - Some ability-specific counters live in
AbilityHolder, such asArcherAttackToLusterBurstAmount,MinerGroundBreakerAmount,CelestialYinSwordAmount,PriestessOrbAmount,stellarShieldBlock. - Evolution upgrades are handled by
UpgradeEvoFunctionwith counter/time conditions.
Upgrades Affecting Abilities¶
Upgrade effects are hardcoded in UpgradeFunction.SelectUpgrade.
Examples:
EQUIPABILITYadds an ability to the player'sAbilityHolder.abilities.RSis reduced if certain ability types are present, such as ProtoBarrier, GroundBreaker, RocketBarrage, SkyYingSword.WEAPONLEVELUPrunsWeaponEvoDatafunctions for the selected character.DRONEspawns a companion drone and sets its master.JETPROPstarts Jet Propulsion logic.REVIVEreactivates dead players, resets cooldown flags, and restores drone ownership.EVOUPGRADEstartsUpgradeEvoFunction.
Projectiles / Hitboxes / Damage¶
Main flow:
PlayerWeapon.CheckReadyFireWeapon()checks dashing, pause, target presence, attack range, character exceptions, ammo/reload, and attack timer.PlayerWeapon.FireWeapon()sets weapon animation/audio and runs ability-specific activation checks.SpawnAttack()pulls the selectedPlayerAttackprefab fromPoolManager.AttackModify()copies player reference, ability flags, damage, crit state, spell amp, hit count bonuses, CC flags, vampiric flags, and character-specific changes ontoPlayerAttack.PlayerAttack.OnTriggerEnter2D()applies damage/CC/effects, handles max hits, hit effects, explosions, ricochet, hydra splits, poison, vacuum, eclipse, vampiric healing, and sky sword marking.
Projectile behavior is therefore split between:
- Weapon firing logic in
PlayerWeapon. - Ability state in
AbilityHolder. - Hit/effect logic in
PlayerAttack. - Carrier behavior in
PlayerAttackCarrier. - Enemy response in
Enemy.TakeDamage.
Dependencies¶
AbilityHolderdepends onPlayer,GameManager,GameInitialization,InputManager,AbilityFunction,PoolManager,AudioResources,Game.Audio,UIResourceProvider,PlayerWeapon,PlayerAttack,PlayerAttackCarrier,GameEvents.AbilityFunctiondepends onAbility,Player,PoolManager,Items.ItemType.PlayerWeapondepends onAbilityHolder,PlayerModifier,AbilityFunction,PoolManager,GameManager,AudioResources.PlayerAttackdepends onEnemy,PoolManager,AbilityFunction,GameManager.
Problems / Risks¶
AbilityHoldercombines registry, runtime state, input, cooldown activators, behavior execution, character-specific logic, and VFX spawning.Abilityassets contain runtime cooldown state. This risks shared-state bugs.- Many abilities are activated by polling in
Update, even passive or event-driven abilities. - Ability logic is split unpredictably across
AbilityHolder,PlayerWeapon,PlayerAttack, andPlayer.TakeDamage. AbilityFunction.CheckAbilityscans a list each time. Many checks happen in hot paths.CoroutineWorkerkeys are based onCurrentCoroutine.ToString() + ability.ToString(), which is fragile.- Some cooldowns are manually started inside ability coroutines that were also started through
UseAbility, creating possible double-cooldown or timing confusion. AbilityHoldermethods include in-progress or placeholder behavior, such as emptyStarBurstShield.- There is no clear ability schema for level/scaling/stat formulas.
Migration Notes for Godot¶
Preserve:
- Ability ids and unlock conditions.
- Cooldowns, stamina costs, counters, and activation triggers.
- Character-specific play patterns:
- Knight shield/long slash/Neo Sword.
- Soldier Frenzy and dash reload.
- Archer Luster/Artemis burst.
- Miner Ground Breaker and Lucky Find.
- Star Wanderer charge/rocket barrage.
- Celestial sword/orb style companion logic.
- Priestess Abyss Orb/Tidal Veil.
- Projectile and hitbox effects: crit, poison, freeze, ricochet, explosion, vampiric, hydra split, vacuum, eclipse, shields.
Redesign target:
AbilityRegistry / AbilityRunner
- owns unlocked ability ids
- owns per-player runtime cooldown/state
- handles activation requests
- emits signals for UI
- does not contain all ability behavior
AbilityData / AbilityResource
- id/type
- name/icon/description key
- base cooldown/stamina
- tags
- base stats/scaling references
AbilityRuntimeState
- current cooldown
- stacks/counters
- active flag
- owner reference
AbilityBehavior
- one script per ability or reusable behavior family
- activation trigger: input, on_dash, on_fire, on_hit, on_damage_taken, on_level_up, timer
- executes effect using owner/context
UpgradeEffect
- modifies stats, unlocks abilities, changes ability parameters, or starts evolution conditions
- no giant switch in one file
Suggested Godot mapping:
| Unity Concept | Godot Direction |
|---|---|
Ability ScriptableObject |
AbilityResource with static data only. |
AbilityHolder.abilities |
AbilityRegistry with ids/resources and runtime states. |
AbilityFunction.UseAbility |
AbilityRunner.request_activation(ability_id, context). |
AbilityHolder methods |
Individual AbilityBehavior scripts or scenes. |
Ability flags on PlayerAttack |
Attack modifier/effect list applied to attack context. |
UpgradeFunction.EQUIPABILITY |
UnlockAbilityEffect. |
AbilityType enum |
Stable string ids or generated enum-like constants. |
Do not copy:
- One massive holder script.
- Runtime state on shared data resources.
- Polling all passive abilities every frame.
- Projectile effects as a large set of booleans on one attack class.
Open Questions¶
- Whether all
Abilityassets are unique per player at runtime or shared from ScriptableObject references. - Which
AbilityTypeentries are unused, deprecated, in development, or boss-only. - Exact intended cooldown behavior for abilities that start
CooldownTimermanually inside their coroutine. - Whether
Multishootis spelled intentionally in code while assets/text useMultishot. - Unknown / needs manual confirmation.