Token导航 LogoToken导航

Agent Skill · 开发

godot-genre-shooter-fps(戈多类型射击游戏 fps)

godot-genre-shooter-fps 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

godot-genre-shooter-fps 是开发类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在开发类的 21,746 个 Skill 里排第 15,051。

总安装 635周安装 27GitHub Stars 138下载 222核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:godot-genre-shooter-fps(戈多类型射击游戏 fps)
来源仓库:https://github.com/thedivergentai/gd-agentic-skills
仓库路径:skills/godot-genre-shooter-fps
安装命令:
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-genre-shooter-fps
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-genre-shooter-fps

这个 Skill 是做什么的

开发类 Skill 面向写代码、改代码和排查问题,一般会读写仓库文件,部分还会执行构建或测试命令。

godot-genre-shooter-fps 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中围绕仓库状态、代码变更或协作事项进行整理。

适用于戈多类型 FPS 射击游戏的开发流程管理,协助跟踪 Issue 与代码合并进度。通过 npx skills add 命令从指定仓库安装,需确保宿主平台支持相关功能。安装前请核实仓库是否仍在维护,并检查其安全策略与权限要求。该技能可能涉及网络请求或文件系统访问,建议评估影响后谨慎部署。

来源仓库内路径:skills/godot-genre-shooter-fps

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

godot-genre-shooter-fps 怎么安装?

在终端执行 npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-genre-sho…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

godot-genre-shooter-fps 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

godot-genre-shooter-fps 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

godot-genre-shooter-fps 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

godot-genre-shooter-fps 用的人多吗?

公开数据是累计安装 635 次,近一周安装 27 次,下载 222 次,GitHub 138 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

godot-genre-shooter-fps 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理开发类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

开发类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
skill-vetter

技能审查员 · OpenClaw

8,779,018986操作浏览器MIT-0通过
ontology

本体论 · OpenClaw

6,636,960576只读MIT-0通过
entra-app-registration

内部应用程序注册 · Codex、Claude

6,631,872764接触敏感数据未明确通过
entra-app-registration

内部应用程序注册 · Codex、Claude

3,757,680201接触敏感数据未明确通过
nano-banana-pro

纳米香蕉专业版 · OpenClaw

3,526,898364接触敏感数据MIT-0有提醒
godot-genre-shooter-fps

戈多类型射击游戏 fps · 本页

635138需要联网未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Genre: Shooter (FPS/TPS)

Gunplay feel, responsive combat, and competitive balance define shooters.

NEVER Do (Expert Anti-Patterns)

Gunplay & Hit Registration

  • NEVER use _process() for hit detection; strictly use _physics_process() to maintain frame-rate independent accuracy.
  • NEVER apply recoil to the physical weapon model; strictly apply it to Camera Rotation (kick) and Weapon Bloom (spread).
  • NEVER trust the client for hit registration in multiplayer; strictly use Server-Authoritative validation with lag compensation.
  • NEVER synchronize every bullet over the network; strictly use Client-Side Prediction and send only initial "Fire" events.
  • NEVER use Area3D or move_and_collide() for high-speed ballistics; strictly use PhysicsDirectSpaceState3D.intersect_ray() for 100x better performance.
  • NEVER forget to exclude the player's own RID from hitscan raycasts; otherwise, shots will collide instantly with the barrel.
  • NEVER use exact floating-point equality (==) for weapon cooldowns or timers; strictly use is_equal_approx().

Performance & Polish

  • NEVER use a single AudioStreamPlayer for gunfire; strictly use Layered Audio (Mechanical + Shot + Reverb Tail).
  • NEVER instantiate and free() hundreds of projectile nodes; strictly use Object Pooling or the RenderingServer.
  • NEVER use Sprite3D or QuadMesh for bullet impacts; strictly use the Decal node for surface-conforming texture projection.
  • NEVER leave decals in the scene indefinitely; strictly implement a fade-out and cleanup cycle.
  • NEVER use Transform3D.looking_at() for forward shooting vectors; strictly extract the direction from -transform.basis.z.
  • NEVER multiply velocity by delta before move_and_slide(); the method internalizes the timestep automatically.

Input & Architecture

  • NEVER poll mouse motion inside _physics_process(); strictly use _input() for zero-latency camera look.
  • NEVER accumulate mouse rotation directly onto a Transform3D; strictly store Yaw/Pitch variables to avoid gimbal lock.
  • NEVER hardcode weapon statistics (Damage, Recoil) inside logic; strictly use Resource-based WeaponData for balancing.
  • NEVER tightly couple damage logic to specific classes; strictly use Duck-Typing (has_method("take_damage")) for environment interactivity.
  • NEVER use standard Strings for high-frequency state identifiers; strictly use StringName (e.g., &"reloading").
  • NEVER use the ! (NOT) operator in AnimationTree expressions; strictly use is_firing == false.
  • NEVER connect weapon signals via string-based calls; strictly use Signal-Object syntax (fired.connect).

🛠 Expert Components (scripts/)

Original Expert Patterns

Modular Components


Core Loop

Engage → Aim → Fire → Kill Confirm → Acquire Next


Weapon System Architecture

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)

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)

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:

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)

class_name AimAssist
extends Node3D

@export var assist_range := 50.0
@export var assist_angle := 15.0  # Degrees
@export var friction_strength := 0.3  # Slowdown near targets
@export var magnetism_strength := 0.1  # Pull toward targets

func apply_aim_assist(look_input: Vector2, camera: Camera3D) -> Vector2:
    var target := find_closest_target(camera)
    if not target:
        return look_input

    var to_target := target.global_position - camera.global_position
    var camera_forward := -camera.global_basis.z
    var angle := rad_to_deg(camera_forward.angle_to(to_target.normalized()))

    if angle > assist_angle:
        return look_input

    # Friction - slow movement near targets
    var friction := 1.0 - (friction_strength * (1.0 - angle / assist_angle))
    look_input *= friction

    # Magnetism - subtle pull toward target
    var target_screen_pos := camera.unproject_position(target.global_position)
    var screen_center := get_viewport().get_visible_rect().size / 2
    var pull_direction := (target_screen_pos - screen_center).normalized()
    look_input += pull_direction * magnetism_strength * (1.0 - angle / assist_angle)

    return look_input

func find_closest_target(camera: Camera3D) -> Node3D:
    var closest: Node3D = null
    var closest_angle := assist_angle

    for target in get_tree().get_nodes_in_group("enemies"):
        var to_target := target.global_position - camera.global_position
        var angle := rad_to_deg((-camera.global_basis.z).angle_to(to_target.normalized()))

        if angle < closest_angle and to_target.length() < assist_range:
            if has_line_of_sight(camera.global_position, target.global_position):
                closest = target
                closest_angle = angle

    return closest

Weapon Feel Polish

Camera Effects

func on_weapon_fired() -> void:
    # Screen shake
    camera_shake(0.1, 0.05)

    # FOV punch
    camera.fov += 2.0
    await get_tree().create_timer(0.05).timeout
    camera.fov -= 2.0

    # Muzzle flash
    muzzle_flash.visible = true
    await get_tree().create_timer(0.02).timeout
    muzzle_flash.visible = false

func on_weapon_reloaded() -> void:
    # Lock controls during reload
    can_fire = false
    can_aim = false

    play_animation("reload")
    await get_tree().create_timer(reload_time).timeout

    current_ammo = magazine_size
    can_fire = true
    can_aim = true

Audio Layering

@export var fire_sounds: Array[AudioStream]  # Random selection
@export var tail_sound: AudioStream           # Reverb/echo
@export var mechanical_sound: AudioStream     # Gun mechanism

func play_fire_audio() -> void:
    # Main shot
    var shot := fire_sounds.pick_random()
    fire_audio_player.stream = shot
    fire_audio_player.play()

    # Mechanical click
    mechanical_player.play()

    # Tail (delayed reverb)
    await get_tree().create_timer(0.1).timeout
    tail_player.play()

Weapon Selection Decision Tree

When designing weapon balance:

  • High fire rate (SMG) = Low damage per shot, rewards tracking aim
  • Low fire rate (Sniper) = High damage, rewards precision
  • Shotguns = Spread pattern (5-8 pellets), effective range <10m
  • ARs = Jack-of-all-trades, medium everything

Technical implementation:

  • Pistol/AR: Hitscan (instant feedback)
  • Rocket/Grenade: Projectile with gravity
  • S niper: Hitscan with tracer visual

Multiplayer Client Prediction Pattern

# CLIENT: Instant feedback, no waiting for server
func fire_client() -> void:
    play_effects_immediate()  # Muzzle flash, recoil, audio
    local_hitscan_visual()    # Visual blood splatter only
    rpc_id(1, "server_validate_shot", camera.global_transform)

# SERVER: Authoritative damage
@rpc("any_peer")
func server_validate_shot(shooter_transform: Transform3D) -> void:
    var hit = perform_server_hitscan(shooter_transform)
    if hit and is_valid_shot(hit):
        rpc("confirm_hit", hit.victim_id, hit.damage)

# EDGE CASE: What if client's visual hit doesn't match server?
# SOLUTION: Server wins. Client shows "no reg" indicator if mismatch.

Common Pitfalls & Expert Fixes

  • Weak bullet impact → Triple-layer audio (shot+tail+mechanical) + screen shake + blood VFX + damage number
  • Guns feel identical → Unique recoil patterns (SMG: tight vertical, AK: strong horizontal kick)
  • No skill ceiling → Learnable spray patterns (CS:GO style), not pure RNG spread
  • Controller aim frustration → Friction (0.3 slowdown near targets) + subtle 0.1 magnetism

Godot-Specific Tips

  1. Raycasts: Use PhysicsRayQueryParameters3D with proper layer masks
  2. Projectiles: CharacterBody3D or RigidBody3D depending on physics needs
  3. Audio: Multiple AudioStreamPlayer3D for layered gun sounds
  4. Animations: AnimationTree for weapon state machines (idle, aim, fire, reload)

Reference

平台分布

Codex

36.24%
按下载量换算80

Claude

30.99%
按下载量换算69

Cursor

20.18%
按下载量换算45

Gemini CLI

9.94%
按下载量换算22

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills