Sync paint strokes across the network via command replication

Replicate brush strokes as self-contained commands instead of texture
pixels: the owner emits each committed stamp (local placement plus brush
state, byte-quantized) and remotes replay it through the same draw path,
reproducing identical maps without streaming megabytes.

- MeshPainter.Net.cs: PaintStampNet serializable stamp, OnStampCommitted
  owner-capture event (no-op without listener), ApplyNetworkStamp remote
  replay, seedable spray for deterministic speckle.
- MeshPainter.cs: emit stamp after drawing, seed spray only when synced.
- PlayerPaintSync.cs: NetworkBehaviour batching owner stamps reliably
  (ServerRpc -> ClientRpc) with echo guard; remote disables local painting.
- Player/Hider/Hunter prefabs: PlayerPaintSync plus NGO GlobalObjectIdHash.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 4.8 committed 2026-06-27 15:02:33 +02:00
1 parent 7f2f4e5999
commit 69e185d969
8 files changed
+285 -6

No files matched your search

+9 -2
View File
@@ -704,12 +704,19 @@ public partial class MeshPainter : MonoBehaviour
return;
// Pick what this stamp paints with: a fresh random spray pattern, or the resolved
// standard mask. Both backends read it through the _stamp* fields.
if (spray) BuildSprayStampMask();
// standard mask. Both backends read it through the _stamp* fields. When this stamp is
// being replicated (networked owner), the spray is seeded so remotes scatter identically.
if (spray)
{
if (WantsStampCapture) { _lastSpraySeed = Random.Range(1, int.MaxValue); BuildSprayStampMaskSeeded(_lastSpraySeed); }
else BuildSprayStampMask();
}
else UseResolvedStampMask();
if (_gpuActive) DrawBrushGpu(pLocal, radiusLocal, u, v, nLocal);
else PaintStamp3D(pLocal, radiusLocal, u, v, nLocal);
EmitStamp(pLocal, radiusLocal, u, v, nLocal);
}
/// <summary>