Install
$ agentstack add skill-devdavv-unity-ai-workflow-uw-network-setup ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Network Setup
Generate networking code adapted to the project's chosen package.
Before You Start
- Read
docs/ProjectConfig.yamlfor:
networking— the package name ("ngo","mirror","photon", or"none"). If"none", stop — do not generate networking code.architecture_pattern—"so-first"or"di-first"(affects how network services are wired).mcp.unity_mcp— iftrue, callrefresh_unityafter creating files.
- Read
docs/TDD_Template.mdfor the authority matrix (who owns what data). - Read
docs/CODING_STANDARDS.mdfor async patterns (Awaitable+CancellationToken) and class structure. - Read
docs/NAMING_CONVENTIONS.mdfor file/class naming.
Package Quick Reference
Each package has a detailed reference file. Read the relevant one before generating code:
- NGO (Netcode for GameObjects): [references/ngo.md](references/ngo.md) — Unity's first-party solution. Uses
NetworkVariable,[Rpc]attributes. - Mirror: [references/mirror.md](references/mirror.md) — Community open-source. Uses
[SyncVar],[Command]/[ClientRpc]. - Photon (PUN2/Fusion): [references/photon.md](references/photon.md) — Cloud-hosted. Uses
IPunObservable,[PunRPC].
Core Patterns (All Packages)
State Synchronization
Every package has a mechanism for syncing state from server/host to clients. The pattern is the same — only the syntax differs.
| Package | Sync Mechanism | Change Callback | Example | |---------|---------------|-----------------|---------| | NGO | NetworkVariable | .OnValueChanged += handler | _health.OnValueChanged += OnHealthChanged; | | Mirror | [SyncVar(hook = nameof(...))] | Hook method | [SyncVar(hook = nameof(OnHealthChanged))] | | Photon | IPunObservable | OnPhotonSerializeView | Manual read/write in serialize callback |
Remote Procedure Calls (RPCs)
RPCs let clients request actions on the server, or the server push updates to clients.
NGO:
[Rpc(SendTo.Server)]
public void RequestDamageServerRpc(int amount)
{
// Runs on server — validate before applying
if (amount MAX_DAMAGE) return;
_health.Value = Mathf.Max(0, _health.Value - amount);
}
[Rpc(SendTo.ClientsAndHost)]
public void PlayHitEffectClientRpc()
{
// Runs on all clients — visual/audio only, no game state
}
Mirror:
[Command]
public void CmdRequestDamage(int amount)
{
if (amount MAX_DAMAGE) return;
_health = Mathf.Max(0, _health - amount);
RpcPlayHitEffect();
}
[ClientRpc]
public void RpcPlayHitEffect()
{
// Visual/audio feedback on all clients
}
Photon:
public void RequestDamage(int amount)
{
photonView.RPC(nameof(RpcTakeDamage), RpcTarget.MasterClient, amount);
}
[PunRPC]
private void RpcTakeDamage(int amount, PhotonMessageInfo info)
{
if (!PhotonNetwork.IsMasterClient) return;
if (amount MAX_DAMAGE) return;
_health = Mathf.Max(0, _health - amount);
}
Network Object Spawning
Spawning networked objects follows the same principle: only the server/host creates the authoritative instance, and the network layer replicates it to clients.
NGO:
// Server only — spawn a networked prefab
var instance = Instantiate(_projectilePrefab, spawnPoint.position, spawnPoint.rotation);
instance.GetComponent().Spawn();
Mirror:
// Server only
var instance = Instantiate(_projectilePrefab, spawnPoint.position, spawnPoint.rotation);
NetworkServer.Spawn(instance);
Photon:
// Room owner or any client (Photon handles ownership)
PhotonNetwork.Instantiate(_projectilePrefabName, spawnPoint.position, spawnPoint.rotation);
Authority Matrix Template
Define who owns, reads, and writes each piece of networked state. Fill this in before writing code — it prevents authority bugs.
| Entity | Owner | Read | Write | Sync Method | Validation | |--------|-------|------|-------|-------------|------------| | Player Health | Server | Everyone | Server | NetworkVariable / SyncVar | Clamp 0-max, rate limit | | Player Position | Server | Everyone | Server | NetworkTransform | Speed cap, teleport check | | Player Input | Client | Server | Owner | RPC (client -> server) | Sanitize on server | | Chat Messages | Client | Everyone | Owner | RPC | Length limit, rate limit | | Game Timer | Server | Everyone | Server | NetworkVariable / SyncVar | Server-authoritative only | | Inventory | Server | Owner | Server | RPC + NetworkVariable | Validate item exists |
Abstraction Layer (Optional)
When the project might switch networking packages later, or when using DI (architecture_pattern: "di-first"), wrap networking behind an interface:
public interface INetworkService
{
bool IsServer { get; }
bool IsClient { get; }
bool IsConnected { get; }
void SendToServer(T message) where T : struct;
void SendToClients(T message) where T : struct;
}
Register the concrete implementation in the DI container (see uw-dependency-injection). Game systems depend on INetworkService, not the package directly. This makes testing easier too — mock the interface in EditMode tests.
Custom Type Serialization
When syncing custom structs over the network, each package has its own serialization approach:
NGO — implement INetworkSerializable:
public struct DamageEvent : INetworkSerializable
{
public int Amount;
public ulong AttackerId;
public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter
{
serializer.SerializeValue(ref Amount);
serializer.SerializeValue(ref AttackerId);
}
}
Mirror — implement custom Reader/Writer extensions or use [SyncVar] with supported types.
Photon — serialize manually in OnPhotonSerializeView or register custom types with PhotonPeer.RegisterType.
Client Prediction & Lag Compensation
For responsive gameplay (especially movement and shooting), client-side prediction avoids waiting for server confirmation:
- Client predicts — apply input locally immediately.
- Server validates — process the input authoritatively, send correction.
- Client reconciles — if server state differs from prediction, snap or interpolate to correct position.
This is complex. NGO has built-in NetworkTransform prediction. Mirror has community prediction examples. Photon Fusion has built-in state authority with rollback. For custom prediction, start with movement only and expand from there.
After Setup
- DI integration: If
architecture_pattern: "di-first", useuw-dependency-injectionto register network services in the container. - Write tests: Use
uw-unity-test-runner— test game logic in EditMode by mockingINetworkService. Test actual networking in PlayMode. - Authority matrix: Fill in
docs/TDD_Template.mdwith the authority matrix before writing any sync code.
Rules
- Server-authoritative unless
docs/TDD_Template.mdexplicitly specifies peer-to-peer. - Never trust client input — always validate on the server (bounds check, rate limit, permission check).
- Cache
NetworkBehaviourreferences inAwake()orOnNetworkSpawn()— neverGetComponentinUpdate. - Use
[SerializeField] privatefor prefab references and configuration — never public fields. - Check the package version in
ProjectConfig.yamlbefore using any API — breaking changes happen between major versions. - Use
AwaitablewithCancellationTokenfor async network operations (connection, scene loading) perCODING_STANDARDS.md. - All networking code must live inside an
.asmdef. - If
ProjectConfig.yaml -> mcp.unity_mcpistrue, callrefresh_unityafter creating files.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: devdavv
- Source: devdavv/unity-ai-workflow
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.