Editor/Tools/WorkflowTools.PerformanceAndPhysics.cs

Editor tool entry points for performance and physics diagnostics. Exposes two MCP tools: PerformanceProfile invokes PerformanceAndPhysicsDriver.ProfilePerformance and returns JSON; PhysicsAudit calls PerformanceAndPhysicsDriver.AuditPhysicsAndRagdoll with parameters and returns JSON, both wrapped in try/catch to emit failure ToolOutcome on exception.

File Access
#nullable enable
using System;
using System.ComponentModel;

namespace Editor.Mcp
{
	public static partial class SboxMcpAssistant
	{
		/// <summary>
		/// Profiles real-time engine performance metrics: GPU frametimes, CPU sub-system timings
		/// (Render, Physics, Animation, UI layout, C# Update, Network replication, Audio),
		/// GC heap allocations in hot loops, and network bandwidth telemetry.
		/// </summary>
		[McpTool( "pocketknife_performance_profile" )]
		public static string PerformanceProfile()
		{
			try
			{
				var result = PerformanceAndPhysicsDriver.ProfilePerformance();
				return McpJson.Write( result );
			}
			catch ( Exception ex )
			{
				return McpJson.Write( ToolOutcome<object>.Failure( null, ToolStatus.Failed, "performance.profile_failed", "Performance profiling failed.", ex ) );
			}
		}

		/// <summary>
		/// Audits physics ragdolls and rigidbodies: detects bone joint stretching, geometry clipping below terrain,
		/// NaN or runaway velocities, with optional impulse stress-testing to verify Havok/PhysX stability.
		/// </summary>
		[McpTool( "pocketknife_physics_audit" )]
		public static string PhysicsAudit(
			[Description( "Target GameObject name with ModelPhysics/Rigidbody (optional, audits all if omitted)" )] string? target = null,
			[Description( "Maximum allowable bone stretch percentage (default 15.0)" )] float maxBoneStretchPercent = 15.0f,
			[Description( "Maximum allowed linear velocity before flagging runaway physics (default 5000)" )] float maxVelocity = 5000.0f,
			[Description( "Whether to apply random multi-angle impulse bursts to stress-test stability" )] bool applyStressImpulse = false,
			[Description( "Stress impulse magnitude (default 500)" )] float impulseForce = 500.0f )
		{
			try
			{
				var result = PerformanceAndPhysicsDriver.AuditPhysicsAndRagdoll(
					target,
					maxBoneStretchPercent,
					maxVelocity,
					applyStressImpulse,
					impulseForce
				);
				return McpJson.Write( result );
			}
			catch ( Exception ex )
			{
				return McpJson.Write( ToolOutcome<object>.Failure( null, ToolStatus.Failed, "physics.audit_failed", "Physics stability audit failed.", ex ) );
			}
		}
	}
}