godot-genre-rts

Expert blueprint for real-time strategy games including unit selection (drag box, shift-add), command systems (move, attack, gather), pathfinding (NavigationAgent2D with RVO avoidance), fog of war (SubViewport mask shader), resource economy (gather/build loop), and AI opponents (behavior trees, utility AI). Use for base-building RTS or tactical combat games. Trigger keywords: RTS, unit_selection, command_system, fog_of_war, pathfinding_RVO, resource_economy, command_queue.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "godot-genre-rts" with this command: npx skills add thedivergentai/gd-agentic-skills/thedivergentai-gd-agentic-skills-godot-genre-rts

Genre: Real-Time Strategy (RTS)

Expert blueprint for RTS games balancing strategy, micromanagement, and performance.

NEVER Do

  • NEVER pathfinding jitter — Units pushing each other endlessly. Enable RVO avoidance (NavigationAgent2D.avoidance_enabled with radius).
  • NEVER excessive micromanagement — Automate mundane tasks (auto-attack nearby enemies, auto-resume gathering after drop-off).
  • NEVER _process on every unit — For 100+ units, use central UnitManager iterator. Saves massive function call overhead.
  • NEVER skip command queuing — Players expect Shift+Click to chain commands. Store Array[Command] and process sequentially.
  • NEVER forget fog of war — Unvisited areas should be hidden. Use SubViewport + shader mask for performance.

Available Scripts

MANDATORY: Read the appropriate script before implementing the corresponding pattern.

rts_selection_manager.gd

Mouse-box unit selection with shift-add. Camera projection for 3D units, command issuing with queue support (shift+right click).


Core Loop

  1. Gather: Units collect resources (Gold, Wood, etc.).
  2. Build: Construct base buildings to unlock tech/units.
  3. Train: Produce an army of diverse units.
  4. Command: Micromanage units in real-time battles.
  5. Expand: Secure map control and resources.

Skill Chain

PhaseSkillsPurpose
1. Controlsgodot-input-handling, camera-rtsSelection box, camera panning/zoom
2. Unitsnavigation-server, state-machinesPathfinding, avoidance, states (Idle/Move/Attack)
3. Systemsfog-of-war, building-systemMap visibility, grid placement
4. AIbehavior-trees, utility-aiEnemy commander logic
5. Polishui-minimap, godot-particlesStrategic overview, battle feedback

Architecture Overview

1. Selection Manager (Singleton or Commander Node)

Handles mouse input for selecting units.

# selection_manager.gd
extends Node2D

var selected_units: Array[Unit] = []
var drag_start: Vector2
var is_dragging: bool = false
@onready var selection_box: Panel = $SelectionBox

func _unhandled_input(event):
    if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
        if event.pressed:
            start_selection(event.position)
        else:
            end_selection(event.position)
    elif event is InputEventMouseMotion and is_dragging:
        update_selection_box(event.position)

func end_selection(end_pos: Vector2):
    is_dragging = false
    selection_box.visible = false
    var rect = Rect2(drag_start, end_pos - drag_start).abs()
    
    if Input.is_key_pressed(KEY_SHIFT):
        # Add to selection
        pass
    else:
        deselect_all()
        
    # Query physics server for units in rect
    var query = PhysicsShapeQueryParameters2D.new()
    var shape = RectangleShape2D.new()
    shape.size = rect.size
    query.shape = shape
    query.transform = Transform2D(0, rect.get_center())
    # ... execute query and add units to selected_units
    
    for unit in selected_units:
        unit.set_selected(true)

func issue_command(target_position: Vector2):
    for unit in selected_units:
        unit.move_to(target_position)

2. Unit Controller (State Machine)

Units need robust state management to handle commands and auto-attacks.

# unit.gd
extends CharacterBody2D
class_name Unit

enum State { IDLE, MOVE, ATTACK, HOLD }
var state: State = State.IDLE
var command_queue: Array[Command] = []

@onready var nav_agent: NavigationAgent2D = $NavigationAgent2D

func move_to(target: Vector2):
    nav_agent.target_position = target
    state = State.MOVE

func _physics_process(delta):
    if state == State.MOVE:
        if nav_agent.is_navigation_finished():
            state = State.IDLE
            return
            
        var next_pos = nav_agent.get_next_path_position()
        var direction = global_position.direction_to(next_pos)
        velocity = direction * speed
        move_and_slide()

3. Fog of War

A system to hide unvisited areas. Usually implemented with a texture and a shader.

  • Grid Approach: 2D array of "visibility" values.
  • Viewport Texture: A SubViewport drawing white circles for units on a black background. This texture is then used as a mask in a shader on a full-screen ColorRect overlay.
shader_type canvas_item;
uniform sampler2D visibility_texture; 
uniform vec4 fog_color : source_color;

void fragment() {
    float visibility = texture(visibility_texture, UV).r;
    COLOR = mix(fog_color, vec4(0,0,0,0), visibility);
}

Key Mechanics Implementation

Command Queue

Allow players to chain commands (Shift-Click).

  • Implementation: Store commands in an Array. When one finishes, pop the next.
  • Visuals: Draw lines showing the queued path.

Resource Gathering

  • Nodes: ResourceNode (Tree/GoldMine) and DropoffPoint (TownCenter).
  • Logic:
    1. Move to Resource.
    2. Work (Timer).
    3. Move to Dropoff.
    4. Deposit (Global Economy update).
    5. Repeat.

Common Pitfalls

  1. Pathfinding Jitter: Units pushing each other endlessly. Fix: Use RVO (Reciprocal Velocity Obstacles) built into Godot's NavigationAgent2D (properties avoidance_enabled, radius).
  2. Too Much Micro: Automate mundane tasks (auto-attack nearby, auto-gather behavior).
  3. Performance: Too many nodes. Fix: Use MultiMeshInstance2D for rendering thousands of units if needed, and run logic on a Server node rather than individual scripts for mass units.

Godot-Specific Tips

  • Avoidance: NavigationAgent2D has built-in RVO avoidance. Make sure to call set_velocity() and use the velocity_computed signal for the actual movement!
  • Server Architecture: For 100+ units, don't use _process on every unit. Have a central UnitManager iterate through active units to save function call overhead.
  • Groups: Use Groups heavily (Units, Buildings, Resources) for easy selection filters.

Reference

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

godot-master

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

godot-shaders-basics

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

godot-ui-theming

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

godot-particles

No summary provided by upstream source.

Repository SourceNeeds Review