godot-genre-tower-defense

安装量: 42
排名: #17427

安装

npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-genre-tower-defense
Genre: Tower Defense
Strategic placement, resource management, and escalating difficulty define tower defense.
Core Loop
Prepare
Build/upgrade towers with available currency
Wave
Enemies spawn and traverse path toward goal
Defend
Towers auto-target and damage enemies
Reward
Kills grant currency
Escalate
Waves increase in difficulty/complexity NEVER Do in Tower Defense Games NEVER make all towers equally viable — If Sniper = same DPS as Machine Gun, no strategic choice. Each tower MUST have distinct niche (AoE, slow, armor pierce, anti-air). NEVER use synchronous NavigationServer baking for mazing — NavigationRegion2D.bake_navigation_polygon() blocks main thread. Use NavigationServer2D.get_maps() + worker thread OR fixed paths. NEVER let players fully block the exit path — In mazing TDs, validate NavigationServer2D.map_get_path(start, goal) before tower placement. Empty path = illegal build. NEVER use Area2D.get_overlapping_bodies() every frame — 500 enemies × 60fps = 30k collision checks. Store bodies_entered in array, remove on body_exited . Query once. NEVER make early waves feel like busywork — First 3 waves should introduce mechanics, not bore. Start timer at 50% or give "early call" bonus to skip. NEVER allow death spirals without catch-up mechanics — 1 leaked enemy → less money → harder next wave → inevitable loss. Add interest on saved money OR discrete wave difficulty. Phase Skills Purpose 1. Grid/Path godot-tilemap-mastery , navigation-2d Defining where enemies walk and towers build 2. Towers math-geometry , area-2d Range checks, rotation, projectile prediction 3. Enemies path-following , steering-behaviors Movement along paths 4. Management state-machines , loop-management Wave spawning logic, game phases 5. UI ui-system , drag-and-drop Building towers, inspecting stats Architecture Overview 1. Wave Manager Handles the timing and godot-composition of enemy waves.

wave_manager.gd

extends Node signal wave_started ( wave_index : int ) signal wave_cleared signal enemy_spawned ( enemy : Node2D ) @ export var waves : Array [ Resource ]

Array of WaveDefinition resources

var current_wave_index : int = 0 var active_enemies : int = 0 func start_next_wave ( ) -> void : if current_wave_index

= waves . size ( ) : print ( "All waves cleared!" ) return var wave_data = waves [ current_wave_index ] wave_started . emit ( current_wave_index ) _spawn_wave ( wave_data ) current_wave_index += 1 func _spawn_wave ( wave : WaveResource ) -> void : for group in wave . groups : await get_tree ( ) . create_timer ( group . delay ) . timeout for i in group . count : var enemy = group . enemy_scene . instantiate ( ) add_child ( enemy ) active_enemies += 1 enemy . tree_exiting . connect ( _on_enemy_died ) await get_tree ( ) . create_timer ( group . interval ) . timeout func _on_enemy_died ( ) -> void : active_enemies -= 1 if active_enemies <= 0 : wave_cleared . emit ( ) 2. Tower Logic (State Machine) Towers act as autonomous agents. States : Idle , AcquireTarget , Attack , Cooldown . Targeting Priority : First , Last , Strongest , Weakest , Closest .

tower.gd

extends Node2D var targets_in_range : Array [ Node2D ] = [ ] var current_target : Node2D func _physics_process ( delta : float ) -> void : if current_target == null or not is_instance_valid ( current_target ) : _acquire_target ( ) if current_target : _rotate_turret ( current_target . global_position ) if can_fire ( ) : fire_projectile ( ) func _acquire_target ( ) -> void :

Example: Target closest to end of path

var
max_progress
=
-
1.0
for
enemy
in
targets_in_range
:
if
enemy
.
progress
>
max_progress
:
current_target
=
enemy
max_progress
=
enemy
.
progress
3. Pathfinding Variants
A. Fixed Path (Kingdom Rush style)
Enemies follow a pre-defined
Path2D
.
Implementation
:
PathFollow2D
as parent of Enemy.
Pros
Deterministic, easy to balance, optimized.
Cons
Less player agency in shaping the path.
B. Mazing (Fieldrunners style)
Players build towers to block/reroute enemies.
Implementation
:
NavigationAgent2D
on enemies. Towers update
NavigationRegion2D
(bake on separate thread).
Pros
High strategic depth.
Cons
Computationally expensive recalculation, needs anti-blocking logic (don't let player seal the exit).
Key Mechanics Implementation
Targeting Math (Projectile Prediction)
To hit a moving target, you must predict where it will be.
func
get_predicted_position
(
target
:
Node2D
,
projectile_speed
:
float
)
->
Vector2
:
var
to_target
=
target
.
global_position
-
global_position
var
time_to_hit
=
to_target
.
length
(
)
/
projectile_speed
return
target
.
global_position
+
(
target
.
velocity
*
time_to_hit
)
Economy
Money management is the secondary core loop.
Kill Rewards
Direct feedback for success.
Interest/Income
Rewarding saved money (risk/reward).
Early Calling
Bonus money for starting the next wave early.
Common Pitfalls
Death Spirals
If a player leaks one enemy, they lose money/lives, making the next wave harder, leading to inevitable failure.
Fix
Catch-up mechanics or discrete wave difficulty.
Useless Towers
Every tower type must have a distinct niche (AoE, Slow, Armor Pierce, Anti-Air).
Path Blocking
In mazing games, ensure players cannot completely block the path to the exit. Use
NavigationServer2D.map_get_path
to validate placement before building.
Godot-Specific Tips
Physics Layers
Put enemies on a specific layer (e.g., Layer 2) and tower "range" Areas on a different mask to avoid towers detecting each other or walls.
Area2D Performance
For massive numbers of enemies, avoid
monitorable/monitoring
on every frame if possible. Use
PhysicsServer2D
queries for optimization if enemy count > 500.
Object Pooling
Essential for projectiles and enemies to avoid garbage collection stutters during intense waves. Reference Master Skill: godot-master
返回排行榜