跳到正文
cccskills
免费在 GitHub 公开

game-networking

Use when touching multiplayer code - authoritative server, client prediction and reconciliation, interpolation, lockstep and rollback, server-side validation of every RPC per engine (Netcode, Unreal replication, Godot multiplayer, Colyseus, Bevy crates), bandwidth and versioned messages.

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(1)

  • SKILL.md7.5 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Game Networking

Overview

In a multiplayer game every client is running on a machine you do not control. Whatever a client can send, a cheater will send — teleports, infinite ammo, a hit on someone behind a wall, a purchase with money they do not have. The server (or host) owns the truth; clients send what the player wants to do and render what the server says happened, predicting locally so it still feels instant.

Core principle: Clients send inputs and intents, never outcomes. The authority validates every message before it changes state.

Pick the model the design needs (the repository has usually picked already)

ModelFitsCost
Authoritative server + client prediction + reconciliation + interpolation of othersShooters, action, most online gamesServer hosting; prediction code
Deterministic lockstep (send only inputs)RTS with thousands of unitsEvery peer must simulate bit-identically; latency = slowest peer
Rollback (predict remote inputs, rewind and re-simulate on correction)Fighting games, precise 1v1Fully deterministic, cheap-to-clone state
Listen server / host-authoritativeCo-op, small sessionsHost can cheat; host migration

Stacks: Unity — Netcode for GameObjects, Netcode for Entities, or the Mirror/FishNet/Photon the repo already uses; Unreal — built-in replication (Iris on newer projects that enabled it); Godot — high-level multiplayer (@rpc, MultiplayerSpawner, MultiplayerSynchronizer); web — Colyseus, or WebSocket/WebRTC servers; Bevy — lightyear, bevy_replicon, bevy_ggrs (rollback). Never add a second networking stack beside the one in use.

Validate on the authority — per engine

// Unreal: server RPC with validation; returning false from _Validate disconnects the caller
UFUNCTION(Server, Reliable, WithValidation)
void ServerFire(FVector_NetQuantize Origin, FVector_NetQuantizeNormal Direction, float ClientTime);

bool AShooterCharacter::ServerFire_Validate(FVector_NetQuantize Origin, FVector_NetQuantizeNormal Direction, float ClientTime) {
    return Direction.IsNormalized() && FMath::IsFinite(ClientTime);
}
void AShooterCharacter::ServerFire_Implementation(FVector_NetQuantize Origin, FVector_NetQuantizeNormal Direction, float ClientTime) {
    if (!Weapon->CanFire(GetWorld()->GetTimeSeconds())) return;                       // server's cooldown
    if (FVector::Dist(Origin, GetPawnViewLocation()) > MaxOriginError) return;        // origin near the server's view
    Weapon->FireServerAuthoritative(Origin, Direction);                               // server traces the hit
}
// Unity Netcode for GameObjects: only the owner may ask, and the server decides
[Rpc(SendTo.Server)]
void RequestMoveRpc(Vector2 input, RpcParams rpcParams = default) {
    if (rpcParams.Receive.SenderClientId != OwnerClientId) return;
    if (float.IsNaN(input.x) || float.IsNaN(input.y)) return;
    _pendingInput = Vector2.ClampMagnitude(input, 1f);                     // speed applied server-side in FixedUpdate
}
# Godot 4: any peer may call it, so check who did
@rpc("any_peer", "call_remote", "reliable")
func request_buy(item_id: StringName) -> void:
    if not multiplayer.is_server():
        return
    var sender := multiplayer.get_remote_sender_id()
    var player := players.get(sender) as PlayerState
    if player == null or not Shop.has_item(item_id):
        return
    Shop.try_purchase(player, item_id)    # server checks its own balance, not the client's
// Colyseus: validate shape, range and rate before touching state
this.onMessage("move", (client, msg: unknown) => {
  const m = MoveSchema.safeParse(msg);                    // zod: finite numbers, |dir| <= 1
  if (!m.success || !this.rate.allow(client.sessionId)) return;
  this.state.players.get(client.sessionId)?.queueInput(m.data);
});

What "validate" covers: the sender owns the entity; numbers are finite (NaN and Infinity are classic exploits) and in range; enums are known values; array/string lengths are capped; message rate per client is limited; the action is legal now (cooldown, ammo, position, line of sight) according to server state.

Prediction and reconciliation (the local player)

  1. Client samples input each tick, tags it with a sequence number, applies it locally (prediction), stores it, and sends it.
  2. Server applies inputs in order on its fixed step and sends back the authoritative state plus the last processed sequence number.
  3. Client sets its state to the server's, drops acknowledged inputs, and re-applies the unacknowledged ones (reconciliation). Smooth small corrections visually; snap large ones.

Other players are rendered interpolated between two past server snapshots (about 100 ms behind), never extrapolated far. Hit detection on the server rewinds targets to what the shooter saw (lag compensation), within a capped window.

Bandwidth and messages

  • Budget bytes per client per second and per message; send state at a fixed rate (20–60 Hz), not every render frame.
  • Quantize (FVector_NetQuantize, half floats, angles as bytes), delta-compress against the last acknowledged state, and send only what is relevant to each client (interest management) — which also stops wallhacks from reading hidden enemies.
  • Unreliable channel for frequent state that will be superseded; reliable for events that must arrive (purchase, chat, match end).
  • Every message type carries a protocol version (or the handshake does); a client with a different version is refused with a clear reason, not decoded wrongly.
  • Loot, damage rolls and matchmaking randomness come from the server's RNG.

Testing

  • Server handlers are plain functions over state: unit-test them with a fake client — wrong owner, NaN, out-of-range, too fast, legal — and assert the state only changes for the legal case.
  • Prediction/reconciliation: simulate a client and server in one test with a fake transport, inject latency and a dropped packet, assert the client converges to the server state.
  • Determinism (lockstep/rollback): same input log on two simulations → same state hash every N ticks.
  • Manual: two local clients plus a server with simulated latency and loss (Unity Network Simulator, Unreal Net PktLag=150 / Net PktLoss=5, tc netem / Clumsy) — and say in the closing message which of these you could not run here.

Common Mistakes

  • A client RPC that applies damage, grants currency or sets position directly.
  • Trusting a client timestamp for anything except lag-compensation bounds.
  • Replicating everything every tick; sending hidden enemy positions to every client.
  • Spawning or destroying networked objects on a client.
  • Godot @rpc("any_peer") without checking get_remote_sender_id().

Red Flags

  • A server handler with no validation branch.
  • ServerXxx_Validate that always returns true for parameters a client controls.
  • Floats from the network used without a finiteness check.
  • A protocol change with no version bump.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases

中文简介正在准备中。当前显示原文说明。

makifbaysal/tasktrooper1172026年10月20日 更新

Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping

中文简介正在准备中。当前显示原文说明。

makifbaysal/tasktrooper1172026年10月20日 更新

Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal

中文简介正在准备中。当前显示原文说明。

makifbaysal/tasktrooper1172026年10月20日 更新

Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task

中文简介正在准备中。当前显示原文说明。

makifbaysal/tasktrooper1172026年10月20日 更新

How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.

中文简介正在准备中。当前显示原文说明。

makifbaysal/tasktrooper1172026年10月20日 更新

Use when the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here

中文简介正在准备中。当前显示原文说明。

makifbaysal/tasktrooper1172026年10月20日 更新

查看 makifbaysal 的全部技能

报告此技能的问题