Token导航 LogoToken导航

Agent Skill · 研究检索

godot-adapt-single-to-multiplayer(godot 适应单人模式到多人模式)

godot-adapt-single-to-multiplayer 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

godot-adapt-single-to-multiplayer 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 37,324。

总安装 1,758周安装 74GitHub Stars 138下载 616核验 2026-05-01

安装说明

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

安装方式

通过对话安装

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

请帮我安装这个 Agent Skill:godot-adapt-single-to-multiplayer(godot 适应单人模式到多人模式)
来源仓库:https://github.com/thedivergentai/gd-agentic-skills
仓库路径:skills/godot-adapt-single-to-multiplayer
安装命令:
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-adapt-single-to-multiplayer
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

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

skills.shnpx skills
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-adapt-single-to-multiplayer

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

godot-adapt-single-to-multiplayer 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。适用于信息检索和筛选任务。通过关键词、任务场景或来源线索快速定位候选结果。

安装命令:npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-adapt-single-to-multiplayer。建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

来源仓库内路径:skills/godot-adapt-single-to-multiplayer

上手步骤

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-adapt-single-to-multiplayer 怎么安装?

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

godot-adapt-single-to-multiplayer 支持哪些 AI 工具?

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

godot-adapt-single-to-multiplayer 需要什么权限?

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

godot-adapt-single-to-multiplayer 是免费的吗?

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

godot-adapt-single-to-multiplayer 用的人多吗?

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

godot-adapt-single-to-multiplayer 安全吗?

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

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

值得选的地方

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

先想清楚的地方

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

适不适合你

更适合

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

不太适合

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

研究检索类 Skill 对比

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

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
godot-adapt-single-to-multiplayer

godot 适应单人模式到多人模式 · 本页

1,758138需要联网未明确通过

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

SKILL.md 原文

Adapt: Single to Multiplayer

Expert guidance for retrofitting multiplayer into single-player games.

NEVER Do (Expert Multiplayer Rules)

Security & Authority

  • NEVER trust client-reported state — Clients own their 'Input', NOT their 'Position' or 'Health'. Server must validate every coordinate and health change.
  • NEVER use get_tree() groups for authority checks — Use is_multiplayer_authority(). Group registration is non-deterministic in high-latency joins.
  • NEVER allow unrestricted RPC rates — A malicious client can call a 'FireWeapon' RPC 10,000 times per second. Always implement rate-limiting (net_rpc_rate_limiter.gd).

Movement & Lag

  • NEVER skip Client-Side Prediction — Movement without prediction feels 'heavy' and unresponsive. Predict movement locally, then correct only on server disagreement.
  • NEVER sync peers at 60Hz — Sending entire state every frame will saturate client bandwidth. Use a lower tick-rate (20-30Hz) and interpolate between packets.
  • NEVER snap peer positions — Abrupt position updates cause 'jitter'. Store a buffer of past states and lerp between them with a 100ms delay.

Bandwidth & Sync

  • NEVER sync 'Full Floats' if possible — Quantize Vector3 data (truncating decimals) to save 50%+ bandwidth. Use MultiplayerSynchronizer with delta-sync enabled.
  • NEVER ignore 'Late Joiners' — Players who join mid-game won't see existing environmental changes. Broadcast a full world-state 'Snapshot' on peer connection.
  • NEVER test on 0ms ping — Everything works on localhost. Use a simulator (net_latency_simulator.gd) with 150ms ping to identify sync bugs.

Available Scripts

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

net_prediction_reconciliation.gd

Expert CharacterBody3D prediction with input-buffer replaying for server reconciliation.

net_snapshot_interpolation.gd

Professional snapshot interpolation logic for smoothing peer movement via jitter buffers.

net_auth_server_validator.gd

Authoritative server validator for anti-cheat (Position, Speed, and Action checks).

net_rpc_rate_limiter.gd

Expert rate-limiter to prevent RPC flooding and macro-abuse by clients.

net_interest_management.gd

Distance-based visibility management to optimize binary bandwidth per-peer.

net_delta_compression_sync.gd

Expert quantization and significance-checking logic for delta-compression.

net_upnp_discovery_logic.gd

Robust script for P2P network discovery and automatic port forwarding via UPNP.

net_debug_overlay_monitor.gd

In-game diagnostic overlay reporting RTT (Ping), Packet Loss, and Jitter.

net_lobby_late_join_sync.gd

Professional state-initialization logic to bridge 'Late Joiners' into a synced session.

net_latency_simulator.gd

Editor-only tool for simulating high-ping and loss conditions for stress-testing.


Architecture Patterns

Pattern 1: Authoritative Server (Recommended)

# Server validates ALL gameplay logic
# Clients send inputs → Server processes → Server broadcasts state

# Pros: Secure, prevents cheating
# Cons: Requires server hosting, lag affects gameplay

# Use for: Competitive games, PvP, games with economies

Pattern 2: Peer-to-Peer (Lockstep)

# All clients run identical simulation
# Inputs synced, deterministic physics

# Pros: No dedicated server needed
# Cons: Vulnerable to cheating, desyncs common

# Use for: Co-op, casual games, small player counts (2-4)

Pattern 3: Hybrid (Authority Transfer)

# Host acts as server
# Authority can transfer between peers

# Use for: 4-8 player co-op, party games

Step-by-Step Migration

Step 1: Separate Input from Logic

# ❌ BAD: Input directly modifies state (single-player)
extends CharacterBody2D

func _physics_process(delta: float) -> void:
    var input := Input.get_vector("left", "right", "up", "down")
    velocity = input.normalized() * SPEED
    move_and_slide()

# ✅ GOOD: Input → Logic separation

extends CharacterBody2D

var current_input := Vector2.ZERO

func _physics_process(delta: float) -> void:
    # Only read input if this is OUR player
    if is_multiplayer_authority():
        current_input = Input.get_vector("left", "right", "up", "down")
        # Send input to server (if we're client)
        if multiplayer.get_unique_id() != 1:  # Not server
            rpc_id(1, "receive_input", current_input)

    # EVERYONE processes movement (server + all clients)
    _process_movement(delta, current_input)

func _process_movement(delta: float, input: Vector2) -> void:
    velocity = input.normalized() * SPEED
    move_and_slide()

@rpc("any_peer", "call_remote", "unreliable")
func receive_input(input: Vector2) -> void:
    # Server receives client input
    current_input = input

Step 2: Set Up Multiplayer Authority

# server_setup.gd
extends Node

const PORT = 7777
const MAX_PLAYERS = 4

func host_game() -> void:
    var peer := ENetMultiplayerPeer.new()
    peer.create_server(PORT, MAX_PLAYERS)
    multiplayer.multiplayer_peer = peer

    multiplayer.peer_connected.connect(_on_player_connected)
    multiplayer.peer_disconnected.connect(_on_player_disconnected)

    print("Server started on port %d" % PORT)

func join_game(ip: String) -> void:
    var peer := ENetMultiplayerPeer.new()
    peer.create_client(ip, PORT)
    multiplayer.multiplayer_peer = peer

    print("Connecting to %s:%d" % [ip, PORT])

func _on_player_connected(id: int) -> void:
    print("Player %d connected" % id)
    spawn_player(id)

func _on_player_disconnected(id: int) -> void:
    print("Player %d disconnected" % id)
    despawn_player(id)

func spawn_player(id: int) -> void:
    var player := preload("res://player.tscn").instantiate()
    player.name = str(id)  # CRITICAL: Name must be unique and match peer ID
    player.set_multiplayer_authority(id)  # Client owns their own player
    get_node("/root/World").add_child(player, true)  # true = replicate to all peers

Step 3: Add MultiplayerSynchronizer

# Scene structure:
# Player (CharacterBody2D)
#   ├─ Sprite2D
#   ├─ CollisionShape2D
#   └─ MultiplayerSynchronizer

# MultiplayerSynchronizer setup (in editor):
# - Root Path: "../"  (points to Player node)
# - Replication Interval: 0.05  (20Hz updates)
# - Public Visibility: true
# - Synchronized Properties:
#     - position
#     - rotation
#     - velocity (optional, for interpolation)

# No code needed! MultiplayerSynchronizer auto-syncs properties

Client Prediction & Server Reconciliation

Problem: Lag Makes Game Feel Unresponsive

# Without prediction:
# 1. Client presses W
# 2. Input sent to server
# 3. Server processes (50ms later)
# 4. Server sends back position
# 5. Client sees movement (100ms RTT)
# Result: 100ms delay between input and visual feedback

Solution: Client-Side Prediction

# player_controller.gd
extends CharacterBody2D

var input_buffer: Array = []
var server_state := {"position": Vector2.ZERO, "tick": 0}

func _physics_process(delta: float) -> void:
    if is_multiplayer_authority():
        var input := Input.get_vector("left", "right", "up", "down")

        # Client predicts movement IMMEDIATELY
        var tick := Engine.get_physics_frames()
        input_buffer.append({"input": input, "tick": tick})
        process_movement(input)

        # Send input to server
        if multiplayer.get_unique_id() != 1:
            rpc_id(1, "server_receive_input", input, tick)

    else:
        # Other players: just display synced position (no prediction)
        pass

@rpc("any_peer", "call_remote", "unreliable")
func server_receive_input(input: Vector2, client_tick: int) -> void:
    # Server processes input
    process_movement(input)

    # Send authoritative state back
    rpc_id(multiplayer.get_remote_sender_id(), "client_receive_state", position, client_tick)

@rpc("authority", "call_remote", "unreliable")
func client_receive_state(server_pos: Vector2, server_tick: int) -> void:
    # Reconciliation: check if prediction was correct
    var error := position.distance_to(server_pos)

    if error > 5.0:  # Threshold for correction
        # Snap to server position
        position = server_pos

        # Replay inputs that happened after server_tick
        for buffered_input in input_buffer:
            if buffered_input.tick > server_tick:
                process_movement(buffered_input.input)

    # Clean old inputs
    input_buffer = input_buffer.filter(func(i): return i.tick > server_tick)

func process_movement(input: Vector2) -> void:
    velocity = input.normalized() * SPEED
    move_and_slide()

Lag Compensation Techniques

Interpolation (Other Player Smoothing)

# Other players appear choppy due to packet loss/jitter
# Solution: Interpolate between received states

extends CharacterBody2D

var position_buffer: Array = []
const BUFFER_SIZE = 3  # Store last 3 positions

func _ready() -> void:
    if not is_multiplayer_authority():
        # Disable local physics, use interpolation
        set_physics_process(false)

func _process(delta: float) -> void:
    if not is_multiplayer_authority() and position_buffer.size() >= 2:
        # Interpolate between buffered positions
        var from := position_buffer[0]
        var to := position_buffer[1]
        var t := 0.2  # Interpolation speed

        position = position.lerp(to, t)

        if position.distance_to(to) < 1.0:
            position_buffer.pop_front()

# Called by MultiplayerSynchronizer when position updates
func _on_position_synced(new_pos: Vector2) -> void:
    position_buffer.append(new_pos)
    if position_buffer.size() > BUFFER_SIZE:
        position_buffer.pop_front()

Anti-Cheat Measures

Server-Side Validation

# server_validator.gd
extends Node

const MAX_SPEED = 300.0
const MAX_TELEPORT_DISTANCE = 50.0

@rpc("any_peer", "call_remote", "reliable")
func request_move(new_position: Vector2) -> void:
    var sender_id := multiplayer.get_remote_sender_id()
    var player := get_node("/root/World/" + str(sender_id))

    # Validate movement
    var distance := player.position.distance_to(new_position)
    var delta := get_physics_process_delta_time()
    var max_allowed := MAX_SPEED * delta

    if distance > max_allowed:
        push_warning("Player %d teleported %f units (max: %f)" % [sender_id, distance, max_allowed])
        # Reject movement, force server position
        rpc_id(sender_id, "force_position", player.position)
        return

    # Accept movement
    player.position = new_position

@rpc("authority", "call_remote", "reliable")
func force_position(server_position: Vector2) -> void:
    position = server_position

Bandwidth Optimization

Input Buffering

# ❌ BAD: Send input every frame (60 packets/s)
func _physics_process(delta: float) -> void:
    var input := get_input()
    rpc_id(1, "receive_input", input)

# ✅ GOOD: Send every 3rd frame (20 packets/s)
var input_timer := 0.0
const INPUT_SEND_RATE = 0.05  # 20 Hz

func _physics_process(delta: float) -> void:
    input_timer += delta
    if input_timer >= INPUT_SEND_RATE:
        var input := get_input()
        rpc_id(1, "receive_input", input)
        input_timer = 0.0

Testing Multiplayer Locally

# Launch multiple instances for testing
# Run from command line:

# Windows:
# Server: Godot.exe --path . res://main.tscn -- --server
# Client 1: Godot.exe --path . res://main.tscn -- --client
# Client 2: Godot.exe --path . res://main.tscn -- --client

# Parse arguments in code:
func _ready() -> void:
    var args := OS.get_cmdline_args()
    if "--server" in args:
        host_game()
    elif "--client" in args:
        join_game("127.0.0.1")

Decision Tree: Which Architecture?

FactorAuthoritative ServerP2P Lockstep
Player count8-100+2-4
Cheat preventionCriticalNot important
Server hostingAvailableNot available
Gameplay typePvP, competitiveCo-op, casual
Lag toleranceMedium (prediction helps)Low (desyncs)
Development complexityHighMedium

Reference

平台分布

Codex

38.37%
按下载量换算236

Claude

26.35%
按下载量换算162

Cursor

17.46%
按下载量换算108

Gemini CLI

9.64%
按下载量换算59

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

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

安装前确认

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

继续浏览同类 Skills