Editor/Drivers/PerformanceAndPhysicsDriver.cs

Editor utility driver that inspects performance and physics in the active scene. It collects performance and networking metrics in ProfilePerformance, and audits ModelPhysics ragdolls and Rigidbody components for stretched joints, floor penetration, and extreme velocities in AuditPhysicsAndRagdoll, optionally applying a stress impulse.

NetworkingFile Access
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using Sandbox;
using Sandbox.Diagnostics;
using Sandbox.Physics;

namespace Editor.Mcp
{
	internal static class PerformanceAndPhysicsDriver
	{
		private static Scene? ResolveScene()
		{
			if ( Game.ActiveScene != null ) return Game.ActiveScene;
			var session = EditorRuntime.GetStaticProperty( "Editor.SceneEditorSession", "Active" );
			if ( session != null )
			{
				return EditorRuntime.GetMember( session, "Scene" ) as Scene;
			}
			return null;
		}

		public static ToolOutcome<object> ProfilePerformance()
		{
			try
			{
				var scene = ResolveScene();

				// Memory & Garbage Collection metrics
				var memoryMetrics = new
				{
					BytesAllocatedHotLoop = PerformanceStats.BytesAllocated,
					Gen0Collections = PerformanceStats.Gen0Collections,
					Gen1Collections = PerformanceStats.Gen1Collections,
					Gen2Collections = PerformanceStats.Gen2Collections,
					GcPauseDurationMs = PerformanceStats.GcPause,
					Exceptions = PerformanceStats.Exceptions,
					ProcessMemoryUsageMB = PerformanceStats.ApproximateProcessMemoryUsage / (1024f * 1024f)
				};

				// Network Host Telemetry
				object? networkStats = null;
				if ( Networking.IsActive )
				{
					networkStats = new
					{
						Networking.IsActive,
						Networking.IsHost,
						Networking.IsClient,
						InBytesPerSecond = Networking.HostStats.InBytesPerSecond,
						OutBytesPerSecond = Networking.HostStats.OutBytesPerSecond,
						NetworkFps = Networking.HostStats.Fps,
						ConnectedClients = Connection.All?.Count ?? 0
					};
				}

				// Scene Complexity
				var sceneStats = new
				{
					TotalGameObjects = scene?.GetAllObjects( false ).Count() ?? 0,
					Rigidbodies = scene?.GetAllComponents<Rigidbody>().Count() ?? 0,
					ModelPhysicsRagdolls = scene?.GetAllComponents<ModelPhysics>().Count() ?? 0,
					ModelRenderers = scene?.GetAllComponents<ModelRenderer>().Count() ?? 0,
					PointLights = scene?.GetAllComponents<PointLight>().Count() ?? 0
				};

				return ToolOutcome<object>.Ready( new
				{
					FrameTimeMs = PerformanceStats.FrameTime,
					GpuFrametimeMs = PerformanceStats.GpuFrametime,
					GpuFrameNumber = PerformanceStats.GpuFrameNumber,
					Memory = memoryMetrics,
					Network = networkStats,
					SceneComplexity = sceneStats,
					Status = "Performance and GPU timeline telemetry captured"
				} );
			}
			catch ( Exception ex )
			{
				return ToolOutcome<object>.Failure( null, ToolStatus.Failed, "performance.profile_failed", "Performance profiling failed.", ex );
			}
		}

		public static ToolOutcome<object> AuditPhysicsAndRagdoll(
			string? target = null,
			float maxBoneStretchPercent = 15.0f,
			float maxVelocity = 5000.0f,
			bool applyStressImpulse = false,
			float impulseForce = 500.0f )
		{
			var scene = ResolveScene();
			if ( scene == null )
			{
				return ToolOutcome<object>.Failure( null, ToolStatus.Unavailable, "physics.no_scene", "No active scene loaded." );
			}

			var ragdolls = scene.GetAllComponents<ModelPhysics>().ToArray();
			var rigidbodies = scene.GetAllComponents<Rigidbody>().ToArray();

			if ( !string.IsNullOrWhiteSpace( target ) )
			{
				ragdolls = ragdolls.Where( r => string.Equals( r.GameObject.Name, target.Trim(), StringComparison.OrdinalIgnoreCase ) ).ToArray();
				rigidbodies = rigidbodies.Where( r => string.Equals( r.GameObject.Name, target.Trim(), StringComparison.OrdinalIgnoreCase ) ).ToArray();
			}

			var stretchViolations = new List<object>();
			var penetrationViolations = new List<object>();
			var velocityViolations = new List<object>();
			var inspectedJointCount = 0;
			var inspectedBodyCount = 0;

			// Optional stress test impulse injection
			if ( applyStressImpulse )
			{
				foreach ( var r in rigidbodies )
				{
					r.ApplyImpulse( Vector3.Random * impulseForce );
				}
				foreach ( var mp in ragdolls )
				{
					mp.PhysicsGroup?.ApplyImpulse( Vector3.Random * impulseForce );
				}
			}

			// 1. Audit ModelPhysics Ragdoll Joints & Bodies via PhysicsGroup
			foreach ( var mp in ragdolls )
			{
				var group = mp.PhysicsGroup;
				if ( group != null )
				{
					if ( group.Joints != null )
					{
						foreach ( var j in group.Joints )
						{
							inspectedJointCount++;
							var b1 = j.Body1;
							var b2 = j.Body2;
							if ( b1 != null && b2 != null )
							{
								var currentDist = Vector3.DistanceBetween( b1.Position, b2.Position );
								if ( currentDist > 150f ) // Natural bone separation limit
								{
									stretchViolations.Add( new
									{
										Ragdoll = mp.GameObject.Name,
										BodyA = b1.ToString(),
										BodyB = b2.ToString(),
										Distance = currentDist,
										Issue = "Joint bone stretched beyond anatomical threshold"
									} );
								}
							}
						}
					}

					if ( group.Bodies != null )
					{
						foreach ( var b in group.Bodies )
						{
							inspectedBodyCount++;
							var vel = b.Velocity.Length;
							if ( float.IsNaN( vel ) || float.IsInfinity( vel ) || vel > maxVelocity )
							{
								velocityViolations.Add( new
								{
									Ragdoll = mp.GameObject.Name,
									Velocity = vel,
									Position = b.Position,
									Issue = "Extreme or NaN velocity detected"
								} );
							}

							// Floor clipping check
							var groundTrace = scene.Trace.Ray( b.Position + Vector3.Up * 20f, b.Position - Vector3.Up * 50f )
								.WithoutTags( "trigger" )
								.Run();

							if ( groundTrace.Hit && b.Position.z < (groundTrace.EndPosition.z - 10f) )
							{
								penetrationViolations.Add( new
								{
									Ragdoll = mp.GameObject.Name,
									BonePosition = b.Position,
									GroundHeight = groundTrace.EndPosition.z,
									Issue = "Ragdoll bone clipped below terrain/floor plane"
								} );
							}
						}
					}
				}
			}

			// 2. Audit Standard Rigidbodies
			foreach ( var rb in rigidbodies )
			{
				inspectedBodyCount++;
				var vel = rb.Velocity.Length;
				if ( float.IsNaN( vel ) || float.IsInfinity( vel ) || vel > maxVelocity )
				{
					velocityViolations.Add( new
					{
						GameObject = rb.GameObject.Name,
						Velocity = vel,
						Position = rb.WorldPosition,
						Issue = "Extreme or NaN velocity detected"
					} );
				}
			}

			var passed = stretchViolations.Count == 0 && penetrationViolations.Count == 0 && velocityViolations.Count == 0;

			return ToolOutcome<object>.Ready( new
			{
				Action = "physics_ragdoll_audit",
				Passed = passed,
				InspectedRagdollCount = ragdolls.Length,
				InspectedRigidbodyCount = rigidbodies.Length,
				InspectedJointCount = inspectedJointCount,
				InspectedBodyCount = inspectedBodyCount,
				StretchViolationCount = stretchViolations.Count,
				StretchViolations = stretchViolations,
				PenetrationViolationCount = penetrationViolations.Count,
				PenetrationViolations = penetrationViolations,
				VelocityViolationCount = velocityViolations.Count,
				VelocityViolations = velocityViolations,
				Status = passed ? "All physics bodies and ragdoll joints passed stability criteria" : "Physics stability violations detected"
			} );
		}
	}
}