Refactor: extract shared helpers across scripts, trim remaining doc redundancy

Deduplication pass (44 extractions):
- New SmoothedLook: shared smoothed yaw/pitch look tick + view seeding
  (FirstPersonController, FreeCamController)
- New CharacterTeleport: disable-CC-around-teleport idiom (rescue,
  owner position apply, free-cam sync)
- New GeometryUtil: RescaleToUnitScale + TransformBounds (concealment
  meter/volume, skinned collider baker)
- Paint family: canonical map read/write shared between Net and
  Persistence, snapshot decode, backend stroke dispatch, RebuildBackend,
  ResolveSeed, chunked RPC send/gate/copy, CamoKnobs/HeightKnobs
  aggregates, SanitizeFileKey, NewMaskTexture, AdoptAlbedo, FindSlider
- Player/modes: GameMode SetPlayerControl/SetPainting/SetOrbitInputEnabled,
  InputUtil.GameplayKeyPressed, NearestClimbHit, ComputeXRay delegates to
  ComputeResolutionFreeze, FingerIK TryInPlaneAngle
- Match/misc: UnhookSessionCallbacks, SendEmptyNamedMessage, SwapScenes,
  RunSessionOpAsync, CovarianceEigen, CollectClusterPoints, MatchHud
  GUIStyle cache, HsvColorPicker rehook, VoxelCenter

Documentation pass: remove 6 triplicated doc blocks and 2 restating
inline comments left after the previous reduction.

Behavior-neutral; hot-path rasterizer loops intentionally untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Fable 5 committed 2026-07-02 12:33:48 +02:00
1 parent 066e308cde
commit 2243cc823e
40 files changed
+681 -724

No files matched your search

+41 -58
View File
@@ -233,20 +233,14 @@ public class PlayerPaintSync : NetworkBehaviour
// its own material via HUD + persistence).
if (!IsOwner && _camoApplyPending && _painter && _painter.IsReady)
{
Vector3 c = _camo.Value;
_painter.CamoHalfLambert = c.x;
_painter.CamoHalfLambertBrightness = c.y;
_painter.CamoSpecularDampen = c.z;
_painter.CamoKnobs = _camo.Value;
_camoApplyPending = false;
}
// Remote replica: apply the owner's painted-height knobs once the material exists / on change.
if (!IsOwner && _heightApplyPending && _painter && _painter.IsReady)
{
Vector3 h = _height.Value;
_painter.OcclusionThreshold = h.x;
_painter.HeightNormalIntensity = h.y;
_painter.ParallaxIntensity = h.z;
_painter.HeightKnobs = _height.Value;
_heightApplyPending = false;
}
@@ -274,11 +268,11 @@ public class PlayerPaintSync : NetworkBehaviour
// published (it would briefly flatten remotes' lighting until the real value lands).
if (_painter && _painter.IsReady)
{
var camo = new Vector3(_painter.CamoHalfLambert, _painter.CamoHalfLambertBrightness, _painter.CamoSpecularDampen);
Vector3 camo = _painter.CamoKnobs;
if (_camo.Value != camo)
_camo.Value = camo;
var height = new Vector3(_painter.OcclusionThreshold, _painter.HeightNormalIntensity, _painter.ParallaxIntensity);
Vector3 height = _painter.HeightKnobs;
if (_height.Value != height)
_height.Value = height;
}
@@ -365,20 +359,31 @@ public class PlayerPaintSync : NetworkBehaviour
[ServerRpc]
private void SubmitRestoreServerRpc(int seq, int id) => ApplyRestoreClientRpc(seq, id);
[ClientRpc]
private void ApplyStampsClientRpc(int seq, PaintStampNet[] stamps)
/// <summary>
/// Common gate for the replicated commands: the owner already applied them locally, so only remotes
/// (incl. the host's replica) proceed; during a snapshot transfer the event is buffered instead.
/// Returns true when the caller should apply the event live.
/// </summary>
private bool GateRemoteEvent(NetEvent ev)
{
// The owner already painted these locally; only remotes (incl. the host's replica) replay them.
if (IsOwner || !_painter)
return;
return false;
_seqHorizon = seq; // server replica tracks this as the snapshot cutoff source
_seqHorizon = ev.seq; // server replica tracks this as the snapshot cutoff source
if (_awaitingSnapshot)
{
_buffered.Add(new NetEvent { seq = seq, kind = NetKind.Stamps, stamps = stamps });
return;
_buffered.Add(ev);
return false;
}
return true;
}
[ClientRpc]
private void ApplyStampsClientRpc(int seq, PaintStampNet[] stamps)
{
if (!GateRemoteEvent(new NetEvent { seq = seq, kind = NetKind.Stamps, stamps = stamps }))
return;
for (int i = 0; i < stamps.Length; i++)
_painter.ApplyNetworkStamp(stamps[i]);
@@ -387,17 +392,9 @@ public class PlayerPaintSync : NetworkBehaviour
[ClientRpc]
private void ApplyCheckpointClientRpc(int seq, int id)
{
if (IsOwner || !_painter)
if (!GateRemoteEvent(new NetEvent { seq = seq, kind = NetKind.Checkpoint, id = id }))
return;
_seqHorizon = seq;
if (_awaitingSnapshot)
{
_buffered.Add(new NetEvent { seq = seq, kind = NetKind.Checkpoint, id = id });
return;
}
_painter.RemoteCommitCheckpoint(id);
LogSync($"committed checkpoint {id} (seq {seq})");
}
@@ -405,17 +402,9 @@ public class PlayerPaintSync : NetworkBehaviour
[ClientRpc]
private void ApplyRestoreClientRpc(int seq, int id)
{
if (IsOwner || !_painter)
if (!GateRemoteEvent(new NetEvent { seq = seq, kind = NetKind.Restore, id = id }))
return;
_seqHorizon = seq;
if (_awaitingSnapshot)
{
_buffered.Add(new NetEvent { seq = seq, kind = NetKind.Restore, id = id });
return;
}
// Reproduce the undo/redo from this peer's own history; if it doesn't hold that checkpoint (an
// undo past this peer's join point), fetch a fresh snapshot of the resulting state instead.
if (_painter.RemoteRestoreTo(id))
@@ -520,14 +509,20 @@ public class PlayerPaintSync : NetworkBehaviour
int xferId = ++_xferOut;
BeginSnapshotClientRpc(xferId, data.Length, capturedSeq, baselineId, send);
yield return SendChunked(data, (off, chunk) => SnapshotChunkClientRpc(xferId, off, chunk, send));
EndSnapshotClientRpc(xferId, send);
}
/// <summary>Feeds a blob chunk-wise into sendChunk(offset, chunk), throttled to snapshotChunksPerFrame.</summary>
private IEnumerator SendChunked(byte[] data, System.Action<int, byte[]> sendChunk)
{
int sentThisFrame = 0;
for (int off = 0; off < data.Length; off += snapshotChunkBytes)
{
int len = Mathf.Min(snapshotChunkBytes, data.Length - off);
var chunk = new byte[len];
System.Array.Copy(data, off, chunk, 0, len);
SnapshotChunkClientRpc(xferId, off, chunk, send);
sendChunk(off, chunk);
if (++sentThisFrame >= snapshotChunksPerFrame)
{
@@ -535,8 +530,6 @@ public class PlayerPaintSync : NetworkBehaviour
yield return null; // spread the burst so the reliable window does not overflow
}
}
EndSnapshotClientRpc(xferId, send);
}
[ClientRpc]
@@ -564,8 +557,14 @@ public class PlayerPaintSync : NetworkBehaviour
private void SnapshotChunkClientRpc(int xferId, int offset, byte[] chunk, ClientRpcParams p = default)
{
if (xferId != _activeXferId || _snapBuffer == null) return; // stale chunk from a superseded transfer
if (offset >= 0 && offset + chunk.Length <= _snapBuffer.Length)
System.Array.Copy(chunk, 0, _snapBuffer, offset, chunk.Length);
CopyChunkInto(_snapBuffer, offset, chunk);
}
/// <summary>Copies a received chunk into the reassembly buffer, ignoring out-of-bounds offsets.</summary>
private static void CopyChunkInto(byte[] buffer, int offset, byte[] chunk)
{
if (offset >= 0 && offset + chunk.Length <= buffer.Length)
System.Array.Copy(chunk, 0, buffer, offset, chunk.Length);
}
[ClientRpc]
@@ -611,22 +610,7 @@ public class PlayerPaintSync : NetworkBehaviour
private IEnumerator UploadSnapshot(byte[] data, int cutoff, int baselineId, bool broadcast, ulong target)
{
BeginUploadServerRpc(data.Length, cutoff, baselineId, broadcast, target);
int sentThisFrame = 0;
for (int off = 0; off < data.Length; off += snapshotChunkBytes)
{
int len = Mathf.Min(snapshotChunkBytes, data.Length - off);
var chunk = new byte[len];
System.Array.Copy(data, off, chunk, 0, len);
UploadChunkServerRpc(off, chunk);
if (++sentThisFrame >= snapshotChunksPerFrame)
{
sentThisFrame = 0;
yield return null; // spread the burst so the reliable window does not overflow
}
}
yield return SendChunked(data, (off, chunk) => UploadChunkServerRpc(off, chunk));
EndUploadServerRpc();
}
@@ -644,8 +628,7 @@ public class PlayerPaintSync : NetworkBehaviour
private void UploadChunkServerRpc(int offset, byte[] chunk)
{
if (_uploadBuffer == null) return;
if (offset >= 0 && offset + chunk.Length <= _uploadBuffer.Length)
System.Array.Copy(chunk, 0, _uploadBuffer, offset, chunk.Length);
CopyChunkInto(_uploadBuffer, offset, chunk);
}
[ServerRpc]