godot-genre-shooter
Expert blueprint for FPS/TPS shooter games (Call of Duty, Counter-Strike, Apex Legends, Fortnite) covering weapon systems, recoil patterns, hitscan vs projectile, aim assist, multiplayer prediction, and gunplay feel. Use when building competitive shooters, battle royales, or tactical FPS games requiring responsive combat. Keywords hitscan, recoil pattern, aim assist, client prediction, weapon archetype, projectile physics, hit registration.
What this skill does
# Genre: Shooter (FPS/TPS)
Gunplay feel, responsive combat, and competitive balance define shooters.
## Available Scripts
### [advanced_weapon_controller.gd](scripts/advanced_weapon_controller.gd)
Expert pattern for recoil, bloom, and dual hitscan/projectile systems with object pooling notes.
## Core Loop
`Engage → Aim → Fire → Kill Confirm → Acquire Next`
## NEVER Do (Expert Anti-Patterns)
### Gunplay & Hit Registration
- NEVER use `_process()` for hit detection; strictly use **`_physics_process()`** to maintain frame-rate independent accuracy (aiming/firing are physics events).
- NEVER apply recoil solely to the weapon model transform; strictly apply it to **Camera Rotation (kick)** and **Weapon Bloom (spread)**.
- NEVER use `Area3D` overlap for high-speed hit detection; strictly use **`PhysicsDirectSpaceState3D.intersect_ray()`** for 100x better performance.
- NEVER trust the client for hit registration in multiplayer; strictly use **Server-Authoritative** validation using lag compensation (rewinding).
- NEVER synchronize every bullet over the network; strictly use **Client-Side Prediction** for visual tracers and only send the initial "Fire" event.
- NEVER forget to exclude the player's own RID from hitscan raycasts; strictly use **`add_exception()`** to prevent shots colliding with the weapon barrel.
- NEVER use exact floating-point equality (==) for bullet damage or health; strictly use **`is_equal_approx()`** to mitigate precision loss.
### Performance & Architecture
- NEVER hardcode weapon statistics (Damage, Recoil) inside logic; strictly use **Resource-based WeaponData** for rapid balancing.
- NEVER use a single `AudioStreamPlayer` for gunfire; strictly use **Layered Audio** (Mechanical + Shot + Reverb Tail) for punchy feedback.
- NEVER instantiate and `free()` hundreds of projectile nodes; strictly use **Object Pooling** or the `PhysicsServer3D` API for stability.
- NEVER use `Sprite3D` for bullet impacts on surfaces; strictly use the **Decal** node for conforming, perspective-correct projection.
- NEVER use absolute pixel positioning for crosshairs; strictly rely on **Anchors & RectCenter** to ensure accuracy across resolutions.
- NEVER scale `CollisionShape3D` non-uniformly; strictly scale the **Internal Shape Resource** to maintain valid physics calculations.
- NEVER use TCP for multiplayer shooter synchronization; strictly use **ENet (UDP)** with unreliable transfer modes to avoid latency spikes.
---
## 🛠 Expert Components (scripts/)
### Original Expert Patterns
- [advanced_weapon_controller.gd](scripts/advanced_weapon_controller.gd) - Professional-grade weapon system with deterministic recoil, bloom, and dual firing modes.
### Modular Components
- [shooter_patterns.gd](scripts/shooter_patterns.gd) - Reusable patterns: Server-bypassing hitscan, random spread, and ShapeCast3D explosions.
---
## Weapon System Architecture
```gdscript
class_name Weapon
extends Node3D
@export_group("Stats")
@export var damage: int = 20
@export var fire_rate: float = 0.1 # Seconds between shots
@export var magazine_size: int = 30
@export var reload_time: float = 2.0
@export var range: float = 100.0
@export_group("Recoil")
@export var base_recoil: Vector2 = Vector2(0.5, 2.0) # X, Y degrees
@export var recoil_recovery_speed: float = 5.0
@export var max_spread: float = 5.0
@export_group("Type")
@export var is_hitscan: bool = true
@export var projectile_scene: PackedScene
var current_ammo: int
var can_fire: bool = true
var current_recoil: Vector2 = Vector2.ZERO
var current_spread: float = 0.0
signal fired
signal reloaded
signal ammo_changed(current: int, max: int)
```
---
## Hitscan vs Projectile
### Hitscan (Instant Hit)
```gdscript
func fire_hitscan() -> void:
if not can_fire or current_ammo <= 0:
return
current_ammo -= 1
ammo_changed.emit(current_ammo, magazine_size)
var camera := get_viewport().get_camera_3d()
var ray_origin := camera.global_position
var ray_direction := -camera.global_basis.z
# Apply spread
ray_direction = apply_spread(ray_direction)
var space := get_world_3d().direct_space_state
var query := PhysicsRayQueryParameters3D.create(
ray_origin,
ray_origin + ray_direction * range
)
query.collision_mask = collision_mask
var result := space.intersect_ray(query)
if result:
var hit_point: Vector3 = result.position
var hit_normal: Vector3 = result.normal
var hit_object: Object = result.collider
spawn_impact_effect(hit_point, hit_normal)
if hit_object.has_method("take_damage"):
var hit_zone := determine_hit_zone(result)
var final_damage := calculate_damage(damage, hit_zone)
hit_object.take_damage(final_damage, hit_zone)
apply_recoil()
start_fire_cooldown()
fired.emit()
func determine_hit_zone(result: Dictionary) -> String:
# Use collision shape name or bone detection for hitboxes
if "headshot" in result.collider.name.to_lower():
return "head"
elif "chest" in result.collider.name.to_lower():
return "chest"
return "body"
func calculate_damage(base: int, zone: String) -> int:
match zone:
"head": return int(base * 2.5)
"chest": return int(base * 1.0)
_: return int(base * 0.8)
```
### Projectile (Physical Bullet)
```gdscript
class_name Projectile
extends CharacterBody3D
@export var speed := 100.0
@export var damage := 20
@export var gravity_affected := true
@export var lifetime := 5.0
var direction: Vector3
var shooter: Node3D
func _ready() -> void:
await get_tree().create_timer(lifetime).timeout
queue_free()
func _physics_process(delta: float) -> void:
if gravity_affected:
velocity.y -= 9.8 * delta
velocity = direction * speed
var collision := move_and_collide(velocity * delta)
if collision:
var collider := collision.get_collider()
if collider != shooter and collider.has_method("take_damage"):
collider.take_damage(damage)
spawn_impact(collision.get_position(), collision.get_normal())
queue_free()
```
---
## Recoil System
Three types of recoil working together:
```gdscript
class_name RecoilSystem
extends Node
var visual_recoil: Vector2 = Vector2.ZERO # Camera kick
var pattern_offset: Vector2 = Vector2.ZERO # Deterministic pattern
var spread_bloom: float = 0.0 # Accuracy loss
@export var recoil_pattern: Array[Vector2] # Predefined spray pattern
var pattern_index: int = 0
func apply_recoil(weapon: Weapon) -> void:
# 1. Visual recoil - camera kick
visual_recoil.y += weapon.base_recoil.y * randf_range(0.8, 1.2)
visual_recoil.x += weapon.base_recoil.x * randf_range(-1.0, 1.0)
# 2. Pattern recoil - learnable spray
if pattern_index < recoil_pattern.size():
pattern_offset += recoil_pattern[pattern_index]
pattern_index += 1
# 3. Spread bloom - reduced accuracy
spread_bloom = min(spread_bloom + 0.5, weapon.max_spread)
func recover_recoil(delta: float, recovery_speed: float) -> void:
visual_recoil = visual_recoil.lerp(Vector2.ZERO, recovery_speed * delta)
pattern_offset = pattern_offset.lerp(Vector2.ZERO, recovery_speed * delta)
spread_bloom = lerp(spread_bloom, 0.0, recovery_speed * delta)
if visual_recoil.length() < 0.01:
pattern_index = 0 # Reset pattern
func get_spread_direction(base_direction: Vector3) -> Vector3:
var spread_angle := deg_to_rad(spread_bloom)
var random_offset := Vector2(
randf_range(-spread_angle, spread_angle),
randf_range(-spread_angle, spread_angle)
)
return base_direction.rotated(Vector3.UP, random_offset.x).rotated(Vector3.RIGHT, random_offset.y)
```
---
## Aim Assist (Controller Support)
```gdscript
class_name AimAssist
extends Node3D
@export var assist_range := 50.0
@export var assist_angle := 15.0Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.