godot-ability-system

$npx mdskill add thedivergentai/GD-Agentic-Skills/godot-ability-system

Implements RPG ability systems with cooldowns, combos, and skill trees.

  • Solves designing unlockable abilities and character progression in Godot.
  • Depends on Godot 4.7+ and scene-scoped ability managers.
  • Recommends patterns based on cooldown strategies and prerequisite logic.
  • Delivers reusable scripts and architecture for ability execution and upgrades.

SKILL.md

.github/skills/godot-ability-systemView on GitHub ↗
---
name: godot-ability-system
description: "Expert patterns for RPG/action ability systems including cooldown strategies, combo systems, ability chaining, skill trees with prerequisites, upgrade paths, and resource management. Use when implementing unlockable abilities, character progression, or complex skill systems. Trigger keywords: PlayerAbility, AbilityManager, cooldown, SkillTree, SkillNode, prerequisites, can_use, execute, ComboSystem, ability_chain, global_cooldown, charge_system, upgrade_path."
---

## Godot 4.7 Baseline

- Expert patterns in this skill target **Godot 4.7+** (stable, 2026-06-18).
- Consult the [Godot 4.7 migration guide](https://docs.godotengine.org/en/4.7/tutorials/migrating/upgrading_to_godot_4.7.html) when upgrading projects from 4.6.
- **NEVER** assume 4.6 defaults (stretch mode, audio area_mask, RichTextLabel percent flags) without checking 4.7 migration notes.

# Ability System

Resource abilities + scene-scoped managers — not AbilityManager / skill-tree novels.

## Architecture Decision: Where Does the Manager Live?

| Scope | Policy | Script |
|-------|--------|--------|
| Per character / enemy / turret | **Scene-scoped manager as child** (default) | [ability_manager.gd](scripts/ability_manager.gd) or composition [ability_container.gd](scripts/ability_container.gd) on the entity |
| Shared unlock / loadout catalog across scenes | Autoload **catalog / progression only** (ranks, unlock flags) — not live cast state | Thin Autoload data; casts still go through the entity manager |
| Global "cast any ability anywhere" Autoload | **Avoid** | Breaks encapsulation and multiplayer authority |

**Resolved policy:** Live cooldowns, GCD, and `execute()` run on a **scene-scoped** AbilityManager / AbilityContainer under the caster. Autoloads may store unlock ranks; they must not be the combat cast oracle. Skill-tree UI reads/writes progression data, then calls into the caster’s manager — never `/root/AbilityManager.use_*` for combat.

## NEVER Do

- **NEVER tick cooldowns / status durations in `_process()`** — Use `_physics_process(delta)` or one-shot Timers so cooldowns stay deterministic under frame spikes.
- **NEVER forget global cooldown (GCD)** when design needs anti-spam — Small shared lock (0.5–1.5s) between casts when required.
- **NEVER hardcode ability effects in the manager** — Strategy: each ability is a Resource / node with `execute()` ([ability_resource.gd](scripts/ability_resource.gd)).
- **NEVER allow casts during animation lock** — Gate on `is_casting` / anim signals.
- **NEVER save remaining cooldown floats without time normalization** — Persist absolute end timestamps (`Time.get_unix_time_from_system() + remaining`).
- **NEVER put live combat cast state in a global Autoload** — Scene-scoped manager (see decision table). Progression Autoloads are fine.
- **NEVER blindly ban or blindly require object pools** — GDScript refcounting makes pool-optional for light VFX; **do** pool when spawn/despawn of projectiles/AoE is high-frequency or allocation shows up in the profiler. Prefer instantiate/`queue_free` until measured otherwise.
- **NEVER grow deep ability inheritance trees** — Compose Resources + containers ([godot-composition](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-composition/SKILL.md)).

---

## Golden Path (MANDATORY)

1. [ability_resource.gd](scripts/ability_resource.gd) — data + virtual `execute()`
2. [ability_manager.gd](scripts/ability_manager.gd) **or** [ability_container.gd](scripts/ability_container.gd) — scene-scoped cast/cooldown
3. [buff_stat.gd](scripts/buff_stat.gd) — when buffs/modifiers exist
4. Damage resolution → [godot-combat-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-combat-system/SKILL.md)

**Do NOT** paste inline AbilityManager / ComboSystem / SkillTreeManager novels into scenes. Skill trees are progression UI + prerequisite graphs that grant Resources to the caster’s container.

## Available Scripts

- [ability_resource.gd](scripts/ability_resource.gd) — **MANDATORY** before new abilities
- [ability_manager.gd](scripts/ability_manager.gd) — **MANDATORY** Resource-driven cooldown registry (scene-scoped)
- [ability_container.gd](scripts/ability_container.gd) — **MANDATORY** alternative: node/Timer composition per ability
- [buff_stat.gd](scripts/buff_stat.gd) — modular buff stats (Do NOT Load if no buffs)
- [combo_tracker.gd](scripts/combo_tracker.gd) — windowed combo chains → finisher abilities
- [charge_ability.gd](scripts/charge_ability.gd) — multi-charge recharge (Flash-style)
- [skill_node.gd](scripts/skill_node.gd) / [skill_tree_manager.gd](scripts/skill_tree_manager.gd) — prerequisite graphs + point spend (progression only)
- [status_effect.gd](scripts/status_effect.gd) / [status_effect_manager.gd](scripts/status_effect_manager.gd) — ticking DoTs/buffs (`duplicate(true)` required)
- [ability_caster_network.gd](scripts/ability_caster_network.gd) — predict locally, authority validates RPC shell

## Cooldown & Status Timing Contract

- Cooldown registry updates and status `process_tick` must use **physics-frame** delta (`_physics_process`) or `Timer` nodes owned by the container.
- Hit detection from abilities stays on the physics tick when applying impulses / queries.
- UI may read cooldown progress in `_process`; it must not own the truth.

## Expert Techniques (short)

- **Dependency injection:** parents inject caster context; abilities do not `get_node("/root/Player")`.
- **Duck-typed hits:** `has_method(&"take_damage")` / combat DamageData — see combat skill.
- **AoE:** `call_group` or space queries; do not scan the whole tree each cast.
- **Networking:** predict locally, authority validates `can_use` + costs ([godot-multiplayer-networking](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-multiplayer-networking/SKILL.md)).
- **Skill-tree visualizer:** `@tool` GraphEdit for design-time graphs; runtime still grants Resources to scene managers.

## Status Effects & Combos (critical WHY)

> **CAUTION:** Status/buff templates applied at runtime **must** use `duplicate(true)`. One poisoned `.tres` mutates every character sharing that asset — see [status_effect_manager.gd](scripts/status_effect_manager.gd).

- **Combos:** [combo_tracker.gd](scripts/combo_tracker.gd) — sequence window + recipe table; finishers remain normal `AbilityResource` entries.
- **Charges:** [charge_ability.gd](scripts/charge_ability.gd) — recharge ticks belong on `_physics_process`, not UI `_process`.
- **Skill trees:** [skill_tree_manager.gd](scripts/skill_tree_manager.gd) grants abilities to the **caster's** scene manager — progression Autoloads hold ranks only.
- **Save cooldowns:** persist **absolute end timestamps** (`Time.get_unix_time_from_system() + remaining`), not raw remaining floats — prevents clock/load exploits.

> **MANDATORY** for combos/charges/skill-tree/status/network depth beyond bullets above: [elite-ability-patterns.md](references/elite-ability-patterns.md). **Do NOT Load** for a first AbilityResource + AbilityManager pass.

## Reference

> **Progressive disclosure:** Skim Official Documentation only for the APIs you are implementing (Resources, timers, signals, save, multiplayer). Open Related Skills when wiring adjacent systems—do not preload the whole lattice.

### Official Documentation
- [Resources](https://docs.godotengine.org/en/stable/tutorials/scripting/resources.html) — Ability definitions, buffs, and status effects should be `Resource` data (not hardcoded manager switches) so designers can author and share assets.
- [Resource](https://docs.godotengine.org/en/stable/classes/class_resource.html) — Use `duplicate(true)` when applying a status/buff template at runtime so one character’s ticking state cannot mutate the shared `.tres` for everyone.
- [GDScript exports](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_exports.html) — `@export` / `@export_group` power Inspector-tuned costs, cooldowns, prerequisites, and effect arrays on ability Resources.
- [Using signals](https://docs.godotengine.org/en/stable/getting_started/step_by_step/signals.html) — Emit `ability_cast`, `ability_ready`, and cooldown lifecycle signals so UI and VFX subscribe without coupling to AbilityManager internals.
- [Scene organization](https://docs.godotengine.org/en/stable/tutorials/best_practices/scene_organization.html) — Keep “signals up, calls down”: parents/UI listen; managers call into ability Resources/nodes rather than reaching globally for combat state.
- [Idle and Physics Processing](https://docs.godotengine.org/en/stable/tutorials/scripting/idle_and_physics_processing.html) — Tick cooldowns and GCD in `_physics_process` (fixed delta); avoid `_process` for cooldown math that desyncs under frame spikes.
- [Timer](https://docs.godotengine.org/en/stable/classes/class_timer.html) — One-shot `Timer` children are a clean composition pattern for per-ability cooldowns in container-style managers.
- [SceneTreeTimer](https://docs.godotengine.org/en/stable/classes/class_scenetreetimer.html) — `create_timer()` / await patterns fit cast times and short buff durations without adding persistent Timer nodes for every cast.
- [Groups](https://docs.godotengine.org/en/stable/tutorials/scripting/groups.html) — AoE abilities should `call_group` (or query groups) instead of hand-rolled scene scans for every hit target.
- [Time](https://docs.godotengine.org/en/stable/classes/class_time.html) — Persist cooldown *end* timestamps (`get_unix_time_from_system()` + remaining), not raw remaining floats, across save/load.
- [Saving games](https://docs.godotengine.org/en/stable/tutorials/io/saving_games.html) — Serialize ability unlock ranks and absolute cooldown end times with the rest of player progression data.
- [High-level multiplayer](https://docs.godotengine.org/en/stable/tutorials/networking/high_level_multiplayer.html) — Authoritative cast validation + `@rpc` confirmation/cancel is the engine baseline for predicted ability casts.

### Related Skills

#### Prerequisites
- [godot-resource-data-patterns](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-resource-data-patterns/SKILL.md) — Abilities, buffs, and skill-tree nodes are Resource-first; load this before inventing custom serialization or inheritance trees for ability data.
- [godot-signal-architecture](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-signal-architecture/SKILL.md) — Cast/ready/cooldown signals and UI hooks depend on disciplined signal ownership so AbilityManager stays decoupled from characters and HUD.
- [godot-composition](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-composition/SKILL.md) — Prefer AbilityContainer / component nodes over deep `BaseAbility → MagicAbility → FireAbility` inheritance for runtime behavior.
- [godot-gdscript-mastery](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-gdscript-mastery/SKILL.md) — Virtual `execute()` / `can_cast()`, typed Resources, and await-on-timer cast flows assume solid GDScript patterns.

#### Complements
- [godot-combat-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-combat-system/SKILL.md) — Damage, hit reactions, and targeting pipelines consume ability `execute()` results; keep DamageData separate from ability metadata.
- [godot-rpg-stats](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-rpg-stats/SKILL.md) — Mana/stamina costs, stat bonuses from skill ranks, and buff multipliers need a consistent stats/modifier layer.
- [godot-input-handling](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-input-handling/SKILL.md) — Hotbar / action-map input should call `can_use` / `use_ability` rather than embedding cooldown logic in input callbacks.
- [godot-animation-player](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-animation-player/SKILL.md) — Animation lock and cast telegraphs gate ability spam; wire AnimationPlayer start/finish into `is_casting`.
- [godot-state-machine-advanced](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-state-machine-advanced/SKILL.md) — Cast, channel, and interrupt states belong in a character state machine that asks the ability manager, not the other way around.
- [godot-save-load-systems](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-save-load-systems/SKILL.md) — Skill ranks, unlock flags, and absolute cooldown end times must round-trip through the project save schema.

#### Downstream / consumers
- [godot-monte-carlo-balancer](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-monte-carlo-balancer/SKILL.md) — After cooldowns, costs, and damage/effect Resources are tunable, Monte Carlo loadout sims prove ability DPS/uptime bands before shipping curves.
- [godot-multiplayer-networking](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-multiplayer-networking/SKILL.md) — Predicted casts, authority checks, and rollback of failed RPCs build on the ability manager’s can_use / execute split.
- [godot-genre-action-rpg](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-genre-action-rpg/SKILL.md) — Action-RPG skill bars, skill trees, and ability chaining assemble this skill with combat, stats, and progression genre glue.
- [godot-inventory-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-inventory-system/SKILL.md) — Consumable scrolls, skill books, and equipment that grants abilities bridge inventory grants into AbilityManager registration.

#### Master
- [godot-master](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-master/SKILL.md) — Library router and mirrored module entry; use when discovering peer skills or syncing shared script mirrors after Domain Skill edits.

More from thedivergentai/GD-Agentic-Skills

SkillDescription
godot-2d-animationExpert patterns for 2D animation in Godot using AnimatedSprite2D and skeletal cutout rigs. Use when implementing sprite frame animations, procedural animation (squash/stretch), cutout bone hierarchies, or frame-perfect timing systems. Trigger keywords: AnimatedSprite2D, SpriteFrames, animation_finished, animation_looped, frame_changed, frame_progress, set_frame_and_progress, cutout animation, skeletal 2D, Bone2D, procedural animation, animation state machine, advance(0).
godot-2d-physicsExpert patterns for Godot 2D physics including collision layers/masks, Area2D triggers, raycasting, and PhysicsDirectSpaceState2D queries. Use when implementing collision detection, trigger zones, line-of-sight systems, or manual physics queries. Trigger keywords: CollisionShape2D, CollisionPolygon2D, collision_layer, collision_mask, set_collision_layer_value, set_collision_mask_value, Area2D, body_entered, body_exited, RayCast2D, force_raycast_update, PhysicsPointQueryParameters2D, PhysicsShapeQueryParameters2D, direct_space_state, move_and_collide, move_and_slide.
godot-3d-lightingExpert patterns for Godot 3D lighting including DirectionalLight3D shadow cascades, OmniLight3D attenuation, SpotLight3D projectors, VoxelGI vs SDFGI, and LightmapGI baking. Use when implementing realistic 3D lighting, shadow optimization, global illumination, or light probes. Trigger keywords: DirectionalLight3D, OmniLight3D, SpotLight3D, shadow_enabled, directional_shadow_mode, directional_shadow_split, omni_range, omni_attenuation, spot_range, spot_angle, VoxelGI, SDFGI, LightmapGI, ReflectionProbe, Environment, WorldEnvironment.
godot-3d-materialsExpert patterns for Godot 3D PBR materials using StandardMaterial3D including albedo, metallic/roughness workflows, normal maps, ORM texture packing, transparency modes, and shader conversion. Use when creating realistic 3D surfaces, PBR workflows, or material optimization. Trigger keywords: StandardMaterial3D, BaseMaterial3D, albedo_texture, metallic, metallic_texture, roughness, roughness_texture, normal_texture, normal_enabled, orm_texture, transparency, alpha_scissor, alpha_hash, cull_mode, ShaderMaterial, shader parameters.
godot-3d-world-buildingExpert patterns for 3D level design using GridMap with MeshLibrary, CSG constructive solid geometry, occlusion, and runtime GridMap builders. Use when building 3D levels, modular tilesets, or BSP-style geometry. For sky/fog/Environment recipes, route to godot-3d-lighting. Trigger keywords: GridMap, MeshLibrary, set_cell_item, get_cell_item, map_to_local, local_to_map, CSGCombiner3D, CSGBox3D, CSGSphere3D, CSGPolygon3D, OccluderInstance3D, bake CSG.
godot-adapt-2d-to-3dExpert patterns for migrating 2D games to 3D including node type conversions, camera systems (third-person, first-person, orbit), physics layer migration, sprite-to-model art pipeline, and control scheme adaptations. Use when porting 2D projects to 3D or adding 3D elements. Trigger keywords: CharacterBody2D to CharacterBody3D, Area2D to Area3D, Camera2D to Camera3D, Vector2 to Vector3, collision_layer migration, sprite to MeshInstance3D, 2D to 3D conversion.
godot-adapt-3d-to-2dExpert patterns for simplifying 3D games to 2D including dimension reduction strategies, 2.5D fake-depth, isometric ports, camera flattening, physics conversion, 3D-to-sprite art pipeline, and control simplification. Use when porting 3D to 2D, building 2.5D / isometric / fake-depth gameplay, creating 2D versions for mobile, or prototyping. Trigger keywords: CharacterBody3D to CharacterBody2D, Camera3D to Camera2D, Vector3 to Vector2, flatten Z-axis, 2.5D, isometric, fake depth, Y-sort, simulated Z, orthogonal projection, 3D to sprite conversion, performance optimization.
godot-adapt-desktop-to-mobileExpert patterns for porting desktop games to mobile including touch control schemes (virtual joystick, gesture detection), UI scaling for small screens, performance optimization for mobile GPUs, battery life management, and platform-specific features. Use when creating mobile ports or cross-platform mobile builds. Trigger keywords: TouchScreenButton, virtual_joystick, gesture_detector, InputEventScreenTouch, InputEventScreenDrag, mobile_optimization, battery_saving, adaptive_performance, MOBILE_ENABLED.
godot-adapt-mobile-to-desktopExpert patterns for scaling mobile games to desktop including mouse/keyboard controls, increased resolution and graphical fidelity, expanded UI layouts, settings menus, window management, and platform-specific features. Use when creating desktop ports or cross-platform releases. Trigger keywords: mouse_controls, keyboard_shortcuts, resolution_scaling, graphics_settings, fullscreen_toggle, window_modes, Steam_integration, desktop_optimization.
godot-adapt-single-to-multiplayerExpert patterns for adding multiplayer to single-player games including client-server architecture, authoritative server design, MultiplayerSynchronizer, lag compensation (client prediction, server reconciliation), input buffering, and anti-cheat measures. Use when retrofitting multiplayer, porting to online play, or designing networked gameplay. Trigger keywords: MultiplayerPeer, ENetMultiplayerPeer, SceneMultiplayer, MultiplayerSynchronizer, rpc, rpc_id, multiplayer_authority, client_prediction, server_reconciliation, lag_compensation, rollback.