Game/MonolithNet.cs
namespace Monolith;

/// <summary>
/// All monolith networking as static RPCs.
///
/// Instance RPCs and [Sync] both require the GameObject to be NetworkMode.Object, which means
/// spawning and owning a networked object just to shuttle voxel edits. Static RPCs have no
/// such requirement, so the shared world needs no networked GameObject at all. Every method
/// here is a thin shim onto <see cref="MonolithManager.Instance"/>.
/// </summary>
public static class MonolithNet
{
	/// <summary>Client asks the host to blast. Only the host actually decides what happens.</summary>
	[Rpc.Host]
	public static void RequestBlast( int vx, int vy, int vz, float radius, bool isCharge )
	{
		MonolithManager.Instance?.HostHandleBlast( vx, vy, vz, radius, isCharge, Rpc.CallerId );
	}

	/// <summary>Host mirrors an applied blast to everyone. Unreliable: a lost one self-heals
	/// on the next snapshot, and dropping the odd effect is better than stalling the stream.</summary>
	[Rpc.Broadcast( NetFlags.HostOnly | NetFlags.Unreliable )]
	public static void ApplyBlast( int vx, int vy, int vz, float radius, bool isCharge, Guid causedBy, int removed )
	{
		MonolithManager.Instance?.ClientApplyBlast( vx, vy, vz, radius, isCharge, causedBy, removed );
	}


	// ---------------------------------------------------------------- snapshots

	[Rpc.Host]
	public static void RequestSnapshot()
	{
		MonolithManager.Instance?.HostQueueSnapshot( Rpc.Caller );
	}

	[Rpc.Broadcast( NetFlags.HostOnly )]
	public static void SnapshotHeader( int sx, int sy, int sz, int tier, long initial )
	{
		MonolithManager.Instance?.ClientSnapshotHeader( sx, sy, sz, tier, initial );
	}

	[Rpc.Broadcast( NetFlags.HostOnly )]
	public static void SnapshotChunk( int index, string payload )
	{
		MonolithManager.Instance?.ClientSnapshotChunk( index, payload );
	}

	[Rpc.Broadcast( NetFlags.HostOnly )]
	public static void SnapshotComplete()
	{
		MonolithManager.Instance?.ClientSnapshotComplete();
	}

	[Rpc.Broadcast( NetFlags.HostOnly )]
	public static void MonolithCleared( int nextTier )
	{
		MonolithManager.Instance?.ClientMonolithCleared( nextTier );
	}

	/// <summary>A Slag-bought Fracture. Sent as a seed, not as several million voxels.</summary>
	[Rpc.Host]
	public static void RequestFracture( float fraction )
	{
		MonolithManager.Instance?.HostHandleFracture( fraction, Rpc.CallerId );
	}

	[Rpc.Broadcast( NetFlags.HostOnly )]
	public static void ApplyFracture( float fraction, int seed, Guid causedBy, int removed )
	{
		MonolithManager.Instance?.ClientApplyFracture( fraction, seed, causedBy, removed );
	}

	/// <summary>The shared Monolith has been destroyed. Everyone evaluates their own share.</summary>
	[Rpc.Broadcast( NetFlags.HostOnly )]
	public static void MonolithFelled( long totalCubes )
	{
		MonolithManager.Instance?.ClientMonolithFelled( totalCubes );
	}
}