godot-genre-sports

$npx mdskill add thedivergentai/GD-Agentic-Skills/godot-genre-sports

Build sports games with physics-based ball interaction and team AI.

  • Prevents ball tunneling through goals with continuous collision detection.
  • Depends on Godot 4.7+ RigidBody3D and apply_central_impulse() for ball physics.
  • Recommends realistic dribble physics by keeping ball as standalone RigidBody3D.
  • Delivers expert anti-patterns and patterns for sports game development.

SKILL.md

.github/skills/godot-genre-sportsView on GitHub ↗
---
name: godot-genre-sports
description: "Expert blueprint for sports games (FIFA, NBA 2K, Rocket League, Tony Hawk) covering physics-based ball interaction, team AI formations, contextual input, and match umpire/score authority. Broadcast framing routes to godot-camera-systems. Use when building soccer, basketball, hockey, racing sports, or arcade sports games. Keywords ball physics, magnus effect, formation AI, team tactics, contextual controls, steering behaviors."
---

## 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.

# Genre: Sports

## NEVER Do (Expert Anti-Patterns)

### Physics & Ball Interaction
- NEVER parent the ball directly to a player Transform; strictly keep it a standalone `RigidBody3D` and use `apply_central_impulse()` for **realistic dribble physics**.
- NEVER allow the ball to "Tunnel" through goals; strictly enable **Continuous CD** (`continuous_cd = true`) on the ball's properties for high-velocity validation.
- NEVER scale a `CollisionShape3D` non-uniformly; strictly adjust the resource radius to preserve the internal **moment of inertia**.
- NEVER apply impulses in `_process()`; strictly use `_physics_process()` or `_integrate_forces()` to prevent visual jitter.
- NEVER use a single collision shape for characters; strictly use **layered shapes** for Head, Torso, and Legs to enable headers and chest-traps.

### Match & Team AI
- NEVER allow all AI to chase the ball ("Kindergarten Soccer"); strictly implement **Formation Slots** (Defense/Attack) where only the closest 1-2 players engage.
- NEVER use perfect goalkeeper reflexes; strictly add a **Reaction Delay** (0.2s-0.5s) and an "Error Rate" based on shot angle and velocity.
- NEVER ignore **Root Motion** for movement; strictly use `AnimationTree` with root motion to ensure momentum and turns are visually grounded.
- NEVER trust client-side goal validations; strictly require the **Authoritative Server** to validate physics and score logic.

### Implementation & Sync
- NEVER rely on the default physics tick rate (60 TPS) for fast-moving ballistics; strictly increase **physics_ticks_per_second** (e.g., to 120 or 240) to prevent tunneling.
- NEVER leave **Physics Interpolation** disabled if you want broadcast-quality smoothness; enable it in Project Settings to smooth ball transforms between ticks on high-refresh monitors.
- NEVER skip **vector normalization** on joystick input; strictly normalize to prevent diagonal movement from being 1.4x faster.
- NEVER handle contextual buttons with `is_action_pressed()`; strictly use a **ContextManager** to determine if Button A means "Pass", "Tackle", or "Switch".
- NEVER evaluate an `Area3D` goal trigger immediately; strictly `await get_tree().physics_frame` to allow the Physics Server to sync.

## Ball Possession Decision Tree

| Feel | Approach | Rule |
|------|----------|------|
| **Arcade / magnetic** | Soft follow or short-range spring toward feet | Still **never** reparent the ball to the player Transform; keep `RigidBody3D` authoritative |
| **Sim / impulse dribble** | Kick slightly ahead with `apply_central_impulse()` each touch | Prefer **MANDATORY** ball scripts below; enable `continuous_cd` |

Default for this skill: **impulse dribble**. Magnetic stickiness is a last resort for pure arcade genres and must remain a free RigidBody.

---

## 🛠 Expert Components (scripts/)

> **MANDATORY** — read the script that matches the task before coding:
> - Goals / match phases → [sports_umpire_logic.gd](scripts/sports_umpire_logic.gd)
> - Full flight model (drag + Magnus via `_integrate_forces`) → [sports_ball_physics.gd](scripts/sports_ball_physics.gd)
> - Lean Magnus-only curve (simpler attach) → [magnus_ball_physics.gd](scripts/magnus_ball_physics.gd) — choose **one** ball script, not both
> - Formations / kindergarten-soccer fix → [team_manager.gd](scripts/team_manager.gd)
> - Temporary buffs / powerups → [stat_modifier_powerup.gd](scripts/stat_modifier_powerup.gd)
> - Shared impulse/score helpers → [sports_patterns.gd](scripts/sports_patterns.gd)
>
> **Broadcast camera**: not implemented in this skill’s `scripts/`. Use peer [godot-camera-systems](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-camera-systems/SKILL.md) for broadcast framing / zoom-on-action.
>
> **Do NOT Load** every sports script for one task.

### Ball Physics (pick one)
- [sports_ball_physics.gd](scripts/sports_ball_physics.gd) - High-fidelity Magnus + air drag via custom integrator (`continuous_cd` ready).
- [magnus_ball_physics.gd](scripts/magnus_ball_physics.gd) - Leaner Magnus-only force helper when drag is handled elsewhere.

### Match / Team / Meta
- [sports_umpire_logic.gd](scripts/sports_umpire_logic.gd) - Goal Area3D + match state machine (PRE_GAME / ACTIVE / POST_GOAL).
- [team_manager.gd](scripts/team_manager.gd) - Formation Slots and team strategy switching.
- [stat_modifier_powerup.gd](scripts/stat_modifier_powerup.gd) - Temporary player/stat modifiers for arcade powerups.
- [sports_patterns.gd](scripts/sports_patterns.gd) - Physics-safe impulses and authoritative scoring helpers.

---

## Skill Chain

| Phase | Skills | Purpose |
|-------|--------|---------|
| 1. Physics | `godot-physics-3d` | Ball bounce, friction, player collisions |
| 2. AI | `godot-state-machine-advanced`, `godot-navigation-pathfinding` | Formations, marking, avoidance |
| 3. Anim | `godot-animation-tree-mastery` | Blended running, shooting, tackling |
| 4. Input | `godot-input-handling` | Contextual buttons (Pass/Tackle share button) |
| 5. Camera | `godot-camera-systems` | Broadcast view / zoom-on-action (**peer skill**, not local scripts) |

## Architecture Overview

### 1. The Ball (Physics Core)
The most important object. Must feel right.

```gdscript
# ball.gd
extends RigidBody3D

@export var drag_coefficient: float = 0.5
@export var magnus_effect_strength: float = 2.0

func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
    # Apply Air Drag
    var velocity = state.linear_velocity
    var speed = velocity.length()
    var drag_force = -velocity.normalized() * (drag_coefficient * speed * speed)
    state.apply_central_force(drag_force)
    
    # Magnus Effect (Curve)
    var spin = state.angular_velocity
    var magnus_force = spin.cross(velocity) * magnus_effect_strength
    state.apply_central_force(magnus_force)
```

### 2. Team AI (Formations)
AI players don't just run at the ball. They run to *positions* relative to the ball/field.

```gdscript
# team_manager.gd
extends Node

enum Strategy { ATTACK, DEFEND }
var current_strategy: Strategy = Strategy.DEFEND
var formation_slots: Array[Node3D] # Markers parented to a "Formation Anchor"

func update_tactics(ball_pos: Vector3) -> void:
    # Move the entire formation anchor
    formation_anchor.position = lerp(formation_anchor.position, ball_pos, 0.5)
    
    # Assign best player to each slot
    for player in players:
        var best_slot = find_closest_slot(player)
        player.set_target(best_slot.global_position)
```

### 3. Match Manager
The referee logic.

```gdscript
# match_manager.gd
var score_team_a: int = 0
var score_team_b: int = 0
var match_timer: float = 300.0
enum State { KICKOFF, PLAYING, GOAL, END }

func goal_scored(team: int) -> void:
    if team == 0: score_team_a += 1
    else: score_team_b += 1
    current_state = State.GOAL
    play_celebration()
    await get_tree().create_timer(5.0).timeout
    reset_positions()
    current_state = State.KICKOFF
```

## Key Mechanics Implementation

### Contextual Input
"A" button does different things depending on context.

```gdscript
func _unhandled_input(event: InputEvent) -> void:
    if event.is_action_pressed("action_main"):
        if has_ball:
            pass_ball()
        elif is_near_ball:
            slide_tackle()
        else:
            switch_player()
```

### Steering Behaviors
For natural movement (Seek, Flee, Arrive).

```gdscript
func seek(target_pos: Vector3) -> Vector3:
    var desired_velocity = (target_pos - global_position).normalized() * max_speed
    var steering = desired_velocity - velocity
    return steering.limit_length(max_force)
```

## Godot-Specific Tips

*   **NavigationServer3D**: Essential for avoiding obstacles (other players/referee).
*   **AnimationTree (BlendSpace2D)**: Crucial for sports. You need smooth blending between Idle -> Walk -> Jog -> Sprint in all directions.
*   **PhysicsMaterial**: Tune `bounce` and `friction` on the Ball and Field colliders carefully.

## Common Pitfalls

1.  **AI Bunching**: All 22 players running at the ball (Kindergarten Soccer). **Fix**: Use Formation Slots. Only 1-2 players "Press" the ball; others cover space.
2.  **Magnetic Ball**: Ball sticks to player too perfectly. **Fix**: Use a "Dribble" mechanic where the player kicks the ball slightly ahead physics-wise, rather than parenting it.
3.  **Unfair Goalies**: Goalie reacts instantly. **Fix**: Add a "Reaction Time" delay and "Error Rate" based on shot speed/stats.


## Advanced Sports Meta-Systems

Professional implementation of animation synchronization, spatial intelligence, and collision filtering.

### 1. Root-Motion-Transition (AnimationTree)
Utilize the `AnimationMixer` class (and its derivatives like `AnimationTree`) to extract root motion from complex animations. This ensures that the character's physical displacement is driven directly by the animation data, preventing "skating" and ensuring momentum is visually grounded during high-speed turns or shots.

```gdscript
class_name SportsCharacter extends CharacterBody3D

@onready var anim_tree: AnimationTree = $AnimationTree

func _physics_process(_delta: float) -> void:
    # Extract root motion from the current animation state
    var root_motion := anim_tree.get_root_motion_position()
    # Apply to velocity for physics-synced movement
    velocity = (global_transform.basis * root_motion) / _delta
    move_and_slide()
```

### 2. Contextual-Pass-Prediction (Raycasts)
To predict if a passing lane is clear, configure a `PhysicsRayQueryParameters3D` object and use `PhysicsDirectSpaceState3D.intersect_ray()`. This allows the AI or player assist to verify unobstructed paths to teammates before committing to an action.

```gdscript
class_name PassPredictor extends Node3D

func is_lane_clear(target_pos: Vector3) -> bool:
    var space_state := get_world_3d().direct_space_state
    var query := PhysicsRayQueryParameters3D.create(global_position, target_pos)
    query.collision_mask = 1 # Environment/Opponents
    
    var result := space_state.intersect_ray(query)
    return result.is_empty() # Path is clear if no collision
```

### 3. Layered-Hitbox Pattern
Configure `Area3D` nodes with specific `collision_layer` and `collision_mask` properties to filter interactions. By assigning different layers for the ball and specific body parts (Head, Torso, Legs), you can accurately detect contextual overlaps for headers, chest-traps, or slide tackles.

```gdscript
class_name BodyPartHitbox extends Area3D

enum Part { HEAD, TORSO, LEGS }
@export var part_type: Part

func _on_ball_entered(ball: RigidBody3D) -> void:
    match part_type:
        Part.HEAD:
            apply_header_force(ball)
        Part.TORSO:
            apply_chest_trap(ball)
        Part.LEGS:
            apply_kick_force(ball)
```

**Expert Tip**: For the "Root Motion" system, ensure the `AnimationTree` property `deterministic` is set to true to ensure consistent displacement across different hardware.


## Deep recipes (on demand)

| Topic | Reference / script |
|-------|-------------------|
| Skill chain & phase routing | [skill-chain.md](references/skill-chain.md) |


## Reference

> Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice.

### Official Documentation
- [Physics introduction](https://docs.godotengine.org/en/stable/tutorials/physics/physics_introduction.html) — Collision layers/masks, continuous CD, and when RigidBody vs CharacterBody fits sports players and balls.
- [Using RigidBody](https://docs.godotengine.org/en/stable/tutorials/physics/rigid_body.html) — Impulse/force timing, custom integrators, and contact monitoring for kick/dribble without parenting the ball.
- [RigidBody3D](https://docs.godotengine.org/en/stable/classes/class_rigidbody3d.html) — `continuous_cd`, damp, and `apply_central_impulse` / force APIs for high-speed ballistics.
- [PhysicsDirectBodyState3D](https://docs.godotengine.org/en/stable/classes/class_physicsdirectbodystate3d.html) — `_integrate_forces` state for Magnus/drag custom forces without fighting the solver.
- [PhysicsMaterial](https://docs.godotengine.org/en/stable/classes/class_physicsmaterial.html) — Bounce/friction overrides for ball and pitch surfaces.
- [Collision shapes (3D)](https://docs.godotengine.org/en/stable/tutorials/physics/collision_shapes_3d.html) — Correct sphere/capsule sizing so inertia and layered hitboxes stay physically valid.
- [Physics interpolation](https://docs.godotengine.org/en/stable/tutorials/physics/interpolation/physics_interpolation_introduction.html) — Broadcast-smooth ball/player transforms between elevated physics ticks.
- [Idle and physics processing](https://docs.godotengine.org/en/stable/tutorials/scripting/idle_and_physics_processing.html) — Keep impulses and match rules in `_physics_process` / integrate paths to avoid jitter.
- [Ray-casting](https://docs.godotengine.org/en/stable/tutorials/physics/ray-casting.html) — Pass-lane and tackle assist queries via `PhysicsDirectSpaceState3D`.
- [Using AnimationTree](https://docs.godotengine.org/en/stable/tutorials/animation/animation_tree.html) — BlendSpace locomotion and root-motion extraction for grounded cuts and shots.
- [Controllers, gamepads, and joysticks](https://docs.godotengine.org/en/stable/tutorials/inputs/controllers_gamepads_joysticks.html) — Normalized stick axes, device IDs, and vibration for contextual Pass/Tackle/Switch.
- [High-level multiplayer](https://docs.godotengine.org/en/stable/tutorials/networking/high_level_multiplayer.html) — Authoritative goal validation and unreliable movement sync for competitive matches.

### Related Skills

#### Prerequisites
- [godot-project-foundations](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-project-foundations/SKILL.md) — Autoloads, physics tick/interpolation project settings, and scene layout before ball/team systems land.
- [godot-physics-3d](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-physics-3d/SKILL.md) — RigidBody3D, layers/masks, and continuous collision patterns the ball and layered hitboxes depend on.
- [godot-input-handling](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-input-handling/SKILL.md) — Action maps and device routing so one button can mean Pass, Tackle, or Switch by context.

#### Complements
- [godot-animation-tree-mastery](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-animation-tree-mastery/SKILL.md) — Root-motion BlendSpaces and deterministic mixer setup for sprint/shot/tackle without skating.
- [godot-camera-systems](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-camera-systems/SKILL.md) — Broadcast framing, zoom-on-action, and follow rigs for pitch-scale presentation.
- [godot-navigation-pathfinding](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-navigation-pathfinding/SKILL.md) — NavigationAgent/mesh avoidance so formation runners do not stack through teammates.
- [godot-state-machine-advanced](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-state-machine-advanced/SKILL.md) — Match phases (kickoff/play/goal/end) and per-player chase vs formation states.
- [godot-raycasting-queries](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-raycasting-queries/SKILL.md) — Masked space queries for clear passing lanes and tackle prediction.
- [godot-multiplayer-networking](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-multiplayer-networking/SKILL.md) — Server-authoritative score RPCs and transfer modes for fast sports snapshots.
- [godot-adapt-single-to-multiplayer](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-adapt-single-to-multiplayer/SKILL.md) — Authority split and reconciliation when promoting local kickabouts to online matches.
- [godot-signal-architecture](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-signal-architecture/SKILL.md) — Goal, possession, and UI event buses without coupling umpire logic to every player node.
- [godot-3d-world-building](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-3d-world-building/SKILL.md) — Stadium collision, pitch surfaces, and LOD props around the playable field.

#### Downstream / consumers
- [godot-monte-carlo-balancer](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-monte-carlo-balancer/SKILL.md) — Simulate player/attribute asymmetry, keeper reaction error bands, and rubber-band AI so match outcomes stay competitive.
- [godot-genre-racing](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-genre-racing/SKILL.md) — Adjacent high-speed physics genre patterns when the sport leans vehicle/arcade (e.g. Rocket League-style).

#### Master
- [godot-master](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-master/SKILL.md) — Library router and mirrored module entry; open when discovering which Domain Skill owns a cross-cutting sports concern.

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-ability-systemExpert 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-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.