From 38f09b9cf2cc4e17a773dfc0f30ae17c7370f24b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 31 Dec 2025 19:44:42 +0000
Subject: [PATCH 1/6] Initial plan
From d6280c93180f5e68c9b41eebacbb35e1edeb0e26 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 31 Dec 2025 19:51:04 +0000
Subject: [PATCH 2/6] Add comprehensive WebGL/WebGPU memory optimization
analysis and implementation guide
Co-authored-by: dyfios <16926525+dyfios@users.noreply.github.com>
---
.../webgl-memory-optimization-analysis.md | 365 ++++++++
...ebgl-memory-optimization-implementation.md | 855 ++++++++++++++++++
.../webgl-memory-optimization-summary.md | 251 +++++
3 files changed, 1471 insertions(+)
create mode 100644 docs/developer/webgl-memory-optimization-analysis.md
create mode 100644 docs/developer/webgl-memory-optimization-implementation.md
create mode 100644 docs/developer/webgl-memory-optimization-summary.md
diff --git a/docs/developer/webgl-memory-optimization-analysis.md b/docs/developer/webgl-memory-optimization-analysis.md
new file mode 100644
index 00000000..2eefd2e1
--- /dev/null
+++ b/docs/developer/webgl-memory-optimization-analysis.md
@@ -0,0 +1,365 @@
+# WebGL/WebGPU Memory Optimization Analysis
+
+## Executive Summary
+
+This document provides a comprehensive analysis of WebGL/WebGPU build memory usage for WebVerse-Runtime and StraightFour repositories, identifying optimization opportunities and providing actionable recommendations for improved memory efficiency and runtime performance.
+
+## Current State Analysis
+
+### WebVerse-Runtime Configuration
+
+#### Memory Settings (ProjectSettings/ProjectSettings.asset)
+- **Initial Memory Size**: 32 MB
+- **Maximum Memory Size**: 3032 MB (2.96 GB)
+- **Memory Growth Mode**: 2 (Geometric)
+- **Linear Growth Step**: 16 MB
+- **Geometric Growth Step**: 0.2 (20%)
+- **Geometric Growth Cap**: 96 MB
+- **Linker Target**: 1 (Wasm)
+- **Exception Support**: 2 (Full)
+- **Data Caching**: Enabled
+- **Compression Format**: 1 (Gzip)
+- **WebGPU Support**: Disabled
+
+#### Quality Settings Analysis
+Current quality levels show opportunities for WebGL-specific optimization:
+- **Streaming Mipmaps**: Disabled across all quality levels
+- **Async Upload Buffer Size**: 16 MB (default)
+- **Async Upload Time Slice**: 2ms
+- **Memory Budget**: Not platform-specific
+
+### StraightFour Configuration
+
+#### Memory Settings (Assets/Runtime/StraightFour/ProjectSettings/ProjectSettings.asset)
+- **Initial Memory Size**: 32 MB
+- **Maximum Memory Size**: 2048 MB (2 GB)
+- **Memory Growth Mode**: 2 (Geometric)
+- **Linear Growth Step**: 16 MB
+- **Geometric Growth Step**: 0.2 (20%)
+- **Geometric Growth Cap**: 96 MB
+- **Exception Support**: 1 (Explicitly Thrown)
+- **Linker Target**: 1 (Wasm)
+
+### Build Configuration
+
+#### Current Build Process (Assets/Build/Builder.cs)
+- Two WebGL build variants: Compressed (Gzip) and Uncompressed
+- No platform-specific memory optimizations in build pipeline
+- No automated asset optimization during build
+
+## Identified Optimization Opportunities
+
+### 1. Memory Configuration Optimization
+
+#### Issue: High Maximum Memory Ceiling
+**Current**: WebVerse-Runtime allows up to 3032 MB
+**Impact**:
+- Larger WASM memory overhead in browsers
+- Potential browser compatibility issues on 32-bit systems
+- Inefficient memory allocation patterns
+
+**Recommendation**:
+- Reduce maximum memory to 2048 MB (align with StraightFour)
+- Consider adaptive memory limits based on browser capabilities
+- Implement memory profiling to determine actual requirements
+
+#### Issue: Suboptimal Initial Memory Size
+**Current**: 32 MB initial allocation
+**Impact**:
+- Too small for complex scenes, causing frequent growth operations
+- Memory fragmentation from frequent allocations
+
+**Recommendation**:
+- Increase initial memory to 64-128 MB based on minimum scene requirements
+- Profile typical scene memory usage and set initial size to 75% of average
+
+### 2. Texture and Asset Optimization
+
+#### Issue: Streaming Mipmaps Disabled
+**Current**: `streamingMipmapsActive: 0` across all quality levels
+**Impact**:
+- All texture mip levels loaded immediately
+- Higher memory usage for distant or off-screen objects
+- Longer initial load times
+
+**Recommendation**:
+```yaml
+streamingMipmapsActive: 1
+streamingMipmapsMemoryBudget: 256 # For WebGL
+streamingMipmapsAddAllCameras: 1
+streamingMipmapsMaxLevelReduction: 3
+```
+
+#### Issue: No WebGL-Specific Quality Settings
+**Current**: Generic quality settings applied to all platforms
+**Impact**:
+- Desktop-optimized settings may be memory-inefficient for WebGL
+- No consideration for browser memory constraints
+
+**Recommendation**:
+Create WebGL-specific quality preset:
+```yaml
+name: WebGL-Optimized
+pixelLightCount: 1
+shadows: 1
+shadowResolution: 0 # Low
+antiAliasing: 0
+streamingMipmapsActive: 1
+streamingMipmapsMemoryBudget: 256
+asyncUploadBufferSize: 8 # Reduced from 16
+asyncUploadTimeSlice: 2
+particleRaycastBudget: 64
+```
+
+### 3. Asset Loading and Management
+
+#### Issue: No Explicit Resource Cleanup Strategy
+**Observation**: Code review shows GameObject.Destroy usage but limited Resources.UnloadUnusedAssets
+**Impact**:
+- Memory leaks from unreleased textures/meshes
+- Accumulation of unused assets in memory
+
+**Recommendation**:
+Implement periodic resource cleanup:
+```csharp
+// Add to WebVerseRuntime.cs or world loading logic
+private IEnumerator PeriodicResourceCleanup()
+{
+ while (true)
+ {
+ yield return new WaitForSeconds(60f); // Every minute
+ #if UNITY_WEBGL
+ Resources.UnloadUnusedAssets();
+ System.GC.Collect();
+ #endif
+ }
+}
+```
+
+### 4. Exception Handling Optimization
+
+#### Issue: Full Exception Support in WebVerse-Runtime
+**Current**: `webGLExceptionSupport: 2` (Full)
+**StraightFour**: `webGLExceptionSupport: 1` (Explicitly Thrown)
+**Impact**:
+- Larger WASM file size
+- Additional runtime overhead
+- Increased memory footprint
+
+**Recommendation**:
+- Reduce to explicitly thrown exceptions (1) for production builds
+- Add build parameter to enable full exceptions for debugging
+- Estimated savings: 10-15% in WASM size
+
+### 5. Code Stripping and Optimization
+
+#### Issue: No IL2CPP Stripping Level Specified
+**Impact**:
+- Unused code included in build
+- Larger download and memory footprint
+
+**Recommendation**:
+Configure aggressive managed code stripping:
+```csharp
+// In Builder.cs
+PlayerSettings.SetManagedStrippingLevel(
+ BuildTargetGroup.WebGL,
+ ManagedStrippingLevel.High
+);
+PlayerSettings.stripEngineCode = true;
+```
+
+### 6. Burst Compiler Optimization
+
+#### Current Configuration (BurstAotSettings_WebGL.json)
+```json
+{
+ "EnableBurstCompilation": true,
+ "EnableOptimisations": true,
+ "EnableSafetyChecks": false,
+ "EnableDebugInAllBuilds": false
+}
+```
+
+**Status**: Well-configured for production
+**Recommendation**: Maintain current settings
+
+### 7. Memory Growth Strategy
+
+#### Issue: Geometric Growth May Be Suboptimal
+**Current**: 20% geometric growth with 96 MB cap
+**Impact**:
+- Multiple growth operations for large scene transitions
+- Potential frame hitches during memory growth
+
+**Recommendation**:
+Consider hybrid approach:
+- Initial: 64 MB (increased from 32 MB)
+- Linear growth: 32 MB steps (increased from 16 MB)
+- Geometric growth: 0.15 (15%, reduced from 20%)
+- Geometric cap: 128 MB (increased from 96 MB)
+
+Rationale: Fewer growth operations for typical scenes while maintaining efficiency.
+
+### 8. WebGPU Enablement
+
+#### Current State
+**WebVerse-Runtime**: `webGLEnableWebGPU: 0`
+**Impact**: Not utilizing modern WebGPU API when available
+
+**Recommendation**:
+Enable WebGPU with fallback:
+```csharp
+// In Builder.cs
+PlayerSettings.WebGL.enableWebGPU = true;
+// Automatic fallback to WebGL 2.0 when WebGPU unavailable
+```
+
+**Benefits**:
+- Better memory management in supporting browsers
+- Improved rendering performance
+- Reduced CPU overhead
+
+### 9. Asset Compression Strategy
+
+#### Current State
+- Gzip compression enabled (compression format: 1)
+- Decompression fallback: false (WebVerse-Runtime)
+
+**Recommendation**:
+- Enable decompression fallback for better compatibility
+- Consider Brotli compression for better compression ratios (if Unity version supports)
+- Implement asset bundling for large resources
+
+### 10. Build-Time Optimizations
+
+#### Issue: No Automated Asset Processing
+**Current**: Manual asset configuration
+**Impact**: Inconsistent asset settings, missed optimization opportunities
+
+**Recommendation**:
+Add pre-build texture compression and optimization:
+```csharp
+public static void OptimizeWebGLAssets()
+{
+ // Find all textures
+ string[] textureGUIDs = AssetDatabase.FindAssets("t:Texture2D");
+
+ foreach (string guid in textureGUIDs)
+ {
+ string path = AssetDatabase.GUIDToAssetPath(guid);
+ TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
+
+ if (importer != null)
+ {
+ // Set WebGL-specific settings
+ TextureImporterPlatformSettings settings = new TextureImporterPlatformSettings
+ {
+ name = "WebGL",
+ overridden = true,
+ maxTextureSize = 2048,
+ format = TextureImporterFormat.DXT5Crunched,
+ compressionQuality = 50,
+ crunchedCompression = true
+ };
+
+ importer.SetPlatformTextureSettings(settings);
+ AssetDatabase.ImportAsset(path);
+ }
+ }
+}
+```
+
+## Implementation Priority
+
+### High Priority (Immediate Impact)
+1. **Reduce Maximum Memory Size**: 3032 MB → 2048 MB
+2. **Increase Initial Memory Size**: 32 MB → 64 MB
+3. **Enable Streaming Mipmaps**: Reduce texture memory by 30-50%
+4. **Reduce Exception Support**: Explicitly thrown only for production
+
+### Medium Priority (Significant Impact)
+5. **WebGL-Specific Quality Settings**: Create optimized preset
+6. **Enable WebGPU**: Future-proof with modern API
+7. **Implement Resource Cleanup**: Prevent memory leaks
+8. **Asset Compression Optimization**: Reduce download size
+
+### Low Priority (Incremental Improvements)
+9. **Memory Growth Strategy Tuning**: Reduce growth operations
+10. **Automated Asset Optimization**: Build pipeline integration
+
+## Expected Results
+
+### Memory Usage Improvements
+- **Initial Memory**: -10% to -20% through streaming mipmaps
+- **Peak Memory**: -15% to -30% through proper resource management
+- **Memory Growth Events**: -40% to -60% through better initial sizing
+
+### Performance Improvements
+- **Load Time**: -20% to -30% through compression and streaming
+- **Frame Time**: More consistent due to reduced memory operations
+- **Browser Compatibility**: Better stability on memory-constrained devices
+
+### Build Size Improvements
+- **WASM Size**: -10% to -15% through exception handling and stripping
+- **Total Build Size**: -15% to -25% through asset optimization
+
+## Monitoring and Metrics
+
+### Recommended Metrics to Track
+1. **Memory Usage**
+ - Initial allocation size
+ - Peak memory usage per session
+ - Number of memory growth operations
+ - Memory fragmentation level
+
+2. **Performance**
+ - Frame time consistency
+ - Load time for various scene types
+ - Asset loading latency
+
+3. **Build Metrics**
+ - Total build size
+ - WASM file size
+ - Asset bundle sizes
+ - Compression ratios
+
+### Profiling Tools
+- Unity Profiler with WebGL builds
+- Browser DevTools Memory Profiler
+- about:memory in Firefox
+- chrome://memory-internals in Chrome
+
+## Implementation Checklist
+
+```markdown
+- [ ] Update ProjectSettings.asset memory configuration
+- [ ] Enable streaming mipmaps in QualitySettings.asset
+- [ ] Create WebGL-optimized quality preset
+- [ ] Update Builder.cs with optimization settings
+- [ ] Implement resource cleanup coroutine
+- [ ] Add automated asset optimization to build pipeline
+- [ ] Enable WebGPU support
+- [ ] Update exception handling for production builds
+- [ ] Configure aggressive code stripping
+- [ ] Test builds with various scene complexities
+- [ ] Benchmark memory usage before/after
+- [ ] Document changes in user-facing documentation
+```
+
+## Conclusion
+
+The WebVerse-Runtime and StraightFour projects have solid foundations but significant opportunities for WebGL/WebGPU memory optimization. The recommendations in this document provide a roadmap for reducing memory usage by 15-30% while improving load times and runtime performance. Implementation should follow the priority order, with high-priority items delivering immediate, measurable improvements.
+
+## References
+
+- [Unity WebGL Memory Documentation](https://docs.unity3d.com/Manual/webgl-memory.html)
+- [Unity Quality Settings](https://docs.unity3d.com/Manual/class-QualitySettings.html)
+- [Texture Streaming](https://docs.unity3d.com/Manual/TextureStreaming.html)
+- [WebGPU in Unity](https://docs.unity3d.com/Manual/webgl-graphics-api.html)
+- [IL2CPP Optimization](https://docs.unity3d.com/Manual/IL2CPP-OptimizingBuildTimes.html)
+
+---
+**Document Version**: 1.0
+**Date**: 2025-12-31
+**Author**: Analysis for WebVerse-Runtime Memory Optimization Initiative
diff --git a/docs/developer/webgl-memory-optimization-implementation.md b/docs/developer/webgl-memory-optimization-implementation.md
new file mode 100644
index 00000000..c59cdb6e
--- /dev/null
+++ b/docs/developer/webgl-memory-optimization-implementation.md
@@ -0,0 +1,855 @@
+# WebGL/WebGPU Memory Optimization Implementation Guide
+
+## Overview
+
+This guide provides step-by-step instructions and code examples for implementing the memory optimizations identified in the WebGL/WebGPU Memory Optimization Analysis.
+
+## Table of Contents
+
+1. [Memory Configuration Updates](#memory-configuration-updates)
+2. [Quality Settings Optimization](#quality-settings-optimization)
+3. [Build Pipeline Enhancements](#build-pipeline-enhancements)
+4. [Runtime Resource Management](#runtime-resource-management)
+5. [Asset Optimization](#asset-optimization)
+6. [Testing and Validation](#testing-and-validation)
+
+## Memory Configuration Updates
+
+### Step 1: Update ProjectSettings Memory Configuration
+
+**File**: `ProjectSettings/ProjectSettings.asset`
+
+**Changes**:
+```yaml
+# Before
+webGLInitialMemorySize: 32
+webGLMaximumMemorySize: 3032
+webGLMemoryLinearGrowthStep: 16
+
+# After (Recommended)
+webGLInitialMemorySize: 64
+webGLMaximumMemorySize: 2048
+webGLMemoryLinearGrowthStep: 32
+webGLMemoryGeometricGrowthStep: 0.15
+webGLMemoryGeometricGrowthCap: 128
+```
+
+**Implementation**:
+1. Open Unity Project Settings (Edit → Project Settings)
+2. Navigate to Player → WebGL Settings → Publishing Settings
+3. Update Memory Size settings:
+ - Initial Memory Size: 64 MB
+ - Maximum Memory Size: 2048 MB
+
+**Rationale**: Reduces unnecessary memory overhead while providing sufficient space for typical scenes.
+
+### Step 2: Optimize Exception Handling
+
+**File**: `ProjectSettings/ProjectSettings.asset`
+
+**Changes**:
+```yaml
+# Before
+webGLExceptionSupport: 2 # Full
+
+# After (Production)
+webGLExceptionSupport: 1 # Explicitly Thrown Exceptions Only
+```
+
+**Build Script Update**:
+```csharp
+// In Assets/Build/Builder.cs
+
+public static void BuildWebGLProduction()
+{
+ Debug.Log("Starting WebGL Production build with optimizations...");
+
+ // Set exception support to explicitly thrown only
+ PlayerSettings.WebGL.exceptionSupport = WebGLExceptionSupport.ExplicitlyThrownExceptionsOnly;
+
+ // Set memory configuration
+ PlayerSettings.WebGL.initialMemorySize = 64;
+ PlayerSettings.WebGL.maximumMemorySize = 2048;
+
+ // Enable WebGPU
+ PlayerSettings.WebGL.enableWebGPU = true;
+
+ // Set compression
+ PlayerSettings.WebGL.compressionFormat = WebGLCompressionFormat.Gzip;
+ PlayerSettings.WebGL.decompressionFallback = true;
+
+ BuildPlayerOptions options = new BuildPlayerOptions()
+ {
+ locationPathName = BuildOutputRoot + "/WebGL-Production",
+ options = BuildOptions.None,
+ scenes = new string[] { WebRuntimeScene },
+ target = BuildTarget.WebGL
+ };
+
+ ExecuteBuild(options, "WebGL Production");
+}
+
+public static void BuildWebGLDebug()
+{
+ Debug.Log("Starting WebGL Debug build...");
+
+ // Set exception support to full for debugging
+ PlayerSettings.WebGL.exceptionSupport = WebGLExceptionSupport.FullWithStacktrace;
+
+ BuildPlayerOptions options = new BuildPlayerOptions()
+ {
+ locationPathName = BuildOutputRoot + "/WebGL-Debug",
+ options = BuildOptions.Development,
+ scenes = new string[] { WebRuntimeScene },
+ target = BuildTarget.WebGL
+ };
+
+ ExecuteBuild(options, "WebGL Debug");
+}
+```
+
+## Quality Settings Optimization
+
+### Step 3: Create WebGL-Specific Quality Preset
+
+**File**: `ProjectSettings/QualitySettings.asset`
+
+**Add New Quality Level**:
+```yaml
+- serializedVersion: 4
+ name: WebGL-Optimized
+ pixelLightCount: 1
+ shadows: 1
+ shadowResolution: 0
+ shadowProjection: 1
+ shadowCascades: 1
+ shadowDistance: 40
+ shadowNearPlaneOffset: 3
+ shadowmaskMode: 0
+ skinWeights: 2
+ globalTextureMipmapLimit: 0
+ textureMipmapLimitSettings: []
+ anisotropicTextures: 1
+ antiAliasing: 0
+ softParticles: 0
+ softVegetation: 0
+ realtimeReflectionProbes: 0
+ billboardsFaceCameraPosition: 1
+ useLegacyDetailDistribution: 1
+ adaptiveVsync: 0
+ vSyncCount: 0
+ realtimeGICPUUsage: 25
+ lodBias: 0.7
+ maximumLODLevel: 0
+ enableLODCrossFade: 1
+ streamingMipmapsActive: 1
+ streamingMipmapsAddAllCameras: 1
+ streamingMipmapsMemoryBudget: 256
+ streamingMipmapsRenderersPerFrame: 512
+ streamingMipmapsMaxLevelReduction: 3
+ streamingMipmapsMaxFileIORequests: 512
+ particleRaycastBudget: 64
+ asyncUploadTimeSlice: 2
+ asyncUploadBufferSize: 8
+ asyncUploadPersistentBuffer: 1
+ resolutionScalingFixedDPIFactor: 1
+ terrainQualityOverrides: 0
+ terrainPixelError: 5
+ terrainDetailDensityScale: 0.5
+ terrainBasemapDistance: 500
+ terrainDetailDistance: 50
+ terrainTreeDistance: 2000
+ terrainBillboardStart: 50
+ terrainFadeLength: 5
+ terrainMaxTrees: 50
+ excludedTargetPlatforms: []
+```
+
+**Update Per-Platform Quality Settings**:
+```yaml
+m_PerPlatformDefaultQuality:
+ WebGL: 6 # Index of WebGL-Optimized quality level
+```
+
+## Build Pipeline Enhancements
+
+### Step 4: Enhanced Build Script with Optimizations
+
+**File**: `Assets/Build/Builder.cs`
+
+**Add New Methods**:
+```csharp
+///
+/// Optimize textures for WebGL before building.
+///
+public static void OptimizeTexturesForWebGL()
+{
+ Debug.Log("Optimizing textures for WebGL...");
+
+ string[] textureGUIDs = AssetDatabase.FindAssets("t:Texture2D");
+ int optimizedCount = 0;
+
+ foreach (string guid in textureGUIDs)
+ {
+ string path = AssetDatabase.GUIDToAssetPath(guid);
+
+ // Skip certain paths (e.g., third-party assets)
+ if (path.Contains("/3rd-party/") || path.Contains("/TextMesh Pro/"))
+ {
+ continue;
+ }
+
+ TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
+
+ if (importer != null)
+ {
+ TextureImporterPlatformSettings webglSettings = importer.GetPlatformTextureSettings("WebGL");
+
+ // Only update if not already configured
+ if (!webglSettings.overridden)
+ {
+ webglSettings.name = "WebGL";
+ webglSettings.overridden = true;
+ webglSettings.maxTextureSize = 2048;
+ webglSettings.format = TextureImporterFormat.DXT5Crunched;
+ webglSettings.compressionQuality = 50;
+ webglSettings.crunchedCompression = true;
+
+ importer.SetPlatformTextureSettings(webglSettings);
+ AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
+ optimizedCount++;
+ }
+ }
+ }
+
+ Debug.Log($"Optimized {optimizedCount} textures for WebGL.");
+}
+
+///
+/// Configure build settings for optimal WebGL memory usage.
+///
+private static void ConfigureOptimalWebGLSettings()
+{
+ // Managed code stripping
+ PlayerSettings.SetManagedStrippingLevel(
+ BuildTargetGroup.WebGL,
+ ManagedStrippingLevel.High
+ );
+ PlayerSettings.stripEngineCode = true;
+
+ // IL2CPP optimization
+ PlayerSettings.SetIl2CppCompilerConfiguration(
+ BuildTargetGroup.WebGL,
+ Il2CppCompilerConfiguration.Master
+ );
+
+ // Memory settings
+ PlayerSettings.WebGL.initialMemorySize = 64;
+ PlayerSettings.WebGL.maximumMemorySize = 2048;
+
+ // WebGPU support
+ PlayerSettings.WebGL.enableWebGPU = true;
+
+ // Data caching
+ PlayerSettings.WebGL.dataCaching = true;
+
+ // Exception support (production)
+ PlayerSettings.WebGL.exceptionSupport = WebGLExceptionSupport.ExplicitlyThrownExceptionsOnly;
+
+ // Compression
+ PlayerSettings.WebGL.compressionFormat = WebGLCompressionFormat.Gzip;
+ PlayerSettings.WebGL.decompressionFallback = true;
+
+ // Linker target
+ PlayerSettings.WebGL.linkerTarget = WebGLLinkerTarget.Wasm;
+
+ Debug.Log("WebGL settings configured for optimal memory usage.");
+}
+
+///
+/// Build WebGL with full optimization pipeline.
+///
+public static void BuildWebGLOptimized()
+{
+ Debug.Log("Starting optimized WebGL build...");
+
+ // Pre-build optimizations
+ OptimizeTexturesForWebGL();
+ ConfigureOptimalWebGLSettings();
+
+ BuildPlayerOptions options = new BuildPlayerOptions()
+ {
+ locationPathName = BuildOutputRoot + "/WebGL-Optimized",
+ options = BuildOptions.None,
+ scenes = new string[] { WebRuntimeScene },
+ target = BuildTarget.WebGL
+ };
+
+ ExecuteBuild(options, "WebGL Optimized");
+
+ // Post-build report
+ ReportBuildMetrics(options.locationPathName);
+}
+
+///
+/// Report build size and metrics.
+///
+private static void ReportBuildMetrics(string buildPath)
+{
+ if (Directory.Exists(buildPath))
+ {
+ DirectoryInfo dir = new DirectoryInfo(buildPath);
+ long totalSize = 0;
+
+ foreach (FileInfo file in dir.GetFiles("*", SearchOption.AllDirectories))
+ {
+ totalSize += file.Length;
+ }
+
+ Debug.Log($"Total build size: {totalSize / (1024.0 * 1024.0):F2} MB");
+
+ // Find and report WASM file size
+ FileInfo[] wasmFiles = dir.GetFiles("*.wasm", SearchOption.AllDirectories);
+ foreach (FileInfo wasm in wasmFiles)
+ {
+ Debug.Log($"WASM file: {wasm.Name} - {wasm.Length / (1024.0 * 1024.0):F2} MB");
+ }
+ }
+}
+```
+
+## Runtime Resource Management
+
+### Step 5: Implement Resource Cleanup System
+
+**File**: `Assets/Runtime/Runtime/Scripts/ResourceManager.cs` (New File)
+
+```csharp
+// Copyright (c) 2019-2025 Five Squared Interactive. All rights reserved.
+
+using UnityEngine;
+using System.Collections;
+
+namespace FiveSQD.WebVerse.Runtime
+{
+ ///
+ /// Manages runtime resource cleanup and memory optimization for WebGL builds.
+ ///
+ public class ResourceManager : MonoBehaviour
+ {
+ [Header("Cleanup Settings")]
+ [Tooltip("Interval between automatic resource cleanup (seconds)")]
+ [SerializeField]
+ private float cleanupInterval = 60f;
+
+ [Tooltip("Enable automatic resource cleanup")]
+ [SerializeField]
+ private bool enableAutomaticCleanup = true;
+
+ [Tooltip("Enable memory profiling logs")]
+ [SerializeField]
+ private bool enableMemoryProfiling = false;
+
+ private Coroutine cleanupCoroutine;
+
+ private void Start()
+ {
+ if (enableAutomaticCleanup)
+ {
+ StartResourceCleanup();
+ }
+ }
+
+ private void OnDestroy()
+ {
+ StopResourceCleanup();
+ }
+
+ ///
+ /// Start automatic resource cleanup.
+ ///
+ public void StartResourceCleanup()
+ {
+ if (cleanupCoroutine == null)
+ {
+ cleanupCoroutine = StartCoroutine(PeriodicResourceCleanup());
+ }
+ }
+
+ ///
+ /// Stop automatic resource cleanup.
+ ///
+ public void StopResourceCleanup()
+ {
+ if (cleanupCoroutine != null)
+ {
+ StopCoroutine(cleanupCoroutine);
+ cleanupCoroutine = null;
+ }
+ }
+
+ ///
+ /// Manually trigger resource cleanup.
+ ///
+ public void CleanupNow()
+ {
+ PerformCleanup();
+ }
+
+ ///
+ /// Periodic resource cleanup coroutine.
+ ///
+ private IEnumerator PeriodicResourceCleanup()
+ {
+ while (true)
+ {
+ yield return new WaitForSeconds(cleanupInterval);
+
+ #if UNITY_WEBGL && !UNITY_EDITOR
+ PerformCleanup();
+ #endif
+ }
+ }
+
+ ///
+ /// Perform resource cleanup operations.
+ ///
+ private void PerformCleanup()
+ {
+ if (enableMemoryProfiling)
+ {
+ LogMemoryUsage("Before cleanup");
+ }
+
+ // Unload unused assets
+ Resources.UnloadUnusedAssets();
+
+ // Trigger garbage collection
+ System.GC.Collect();
+
+ if (enableMemoryProfiling)
+ {
+ LogMemoryUsage("After cleanup");
+ }
+ }
+
+ ///
+ /// Log current memory usage.
+ ///
+ private void LogMemoryUsage(string label)
+ {
+ #if UNITY_WEBGL && !UNITY_EDITOR
+ long totalMemory = System.GC.GetTotalMemory(false);
+ Debug.Log($"[ResourceManager] {label} - Managed Memory: {totalMemory / (1024.0 * 1024.0):F2} MB");
+ #endif
+ }
+
+ ///
+ /// Get memory usage statistics.
+ ///
+ public string GetMemoryStats()
+ {
+ long totalMemory = System.GC.GetTotalMemory(false);
+ return $"Managed Memory: {totalMemory / (1024.0 * 1024.0):F2} MB";
+ }
+ }
+}
+```
+
+### Step 6: Integrate Resource Manager with WebVerseRuntime
+
+**File**: `Assets/Runtime/Runtime/Scripts/WebVerseRuntime.cs`
+
+**Add Integration**:
+```csharp
+// Add to class members
+private ResourceManager resourceManager;
+
+// Add to Initialize method or Awake
+public void InitializeResourceManager()
+{
+ GameObject rmObject = new GameObject("ResourceManager");
+ rmObject.transform.SetParent(transform);
+ resourceManager = rmObject.AddComponent();
+
+ #if UNITY_WEBGL && !UNITY_EDITOR
+ // Enable automatic cleanup for WebGL
+ resourceManager.StartResourceCleanup();
+ #endif
+}
+
+// Add cleanup on world unload
+public void UnloadWorld()
+{
+ // Existing world unload code...
+
+ // Trigger immediate cleanup after unloading
+ #if UNITY_WEBGL && !UNITY_EDITOR
+ if (resourceManager != null)
+ {
+ resourceManager.CleanupNow();
+ }
+ #endif
+}
+```
+
+## Asset Optimization
+
+### Step 7: Create Editor Tool for Asset Analysis
+
+**File**: `Assets/Editor/AssetMemoryAnalyzer.cs` (New File)
+
+```csharp
+// Copyright (c) 2019-2025 Five Squared Interactive. All rights reserved.
+
+#if UNITY_EDITOR
+using UnityEditor;
+using UnityEngine;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace FiveSQD.WebVerse.Editor
+{
+ ///
+ /// Tool for analyzing asset memory usage.
+ ///
+ public class AssetMemoryAnalyzer : EditorWindow
+ {
+ private Vector2 scrollPosition;
+ private List assetInfos = new List();
+ private bool showTexturesOnly = true;
+ private int maxTextureSize = 2048;
+
+ private struct AssetInfo
+ {
+ public string path;
+ public string name;
+ public long size;
+ public string type;
+ public int width;
+ public int height;
+ }
+
+ [MenuItem("WebVerse/Tools/Asset Memory Analyzer")]
+ public static void ShowWindow()
+ {
+ GetWindow("Asset Memory Analyzer");
+ }
+
+ private void OnGUI()
+ {
+ GUILayout.Label("Asset Memory Analysis", EditorStyles.boldLabel);
+
+ EditorGUILayout.Space();
+
+ showTexturesOnly = EditorGUILayout.Toggle("Show Textures Only", showTexturesOnly);
+ maxTextureSize = EditorGUILayout.IntField("Max Texture Size", maxTextureSize);
+
+ EditorGUILayout.Space();
+
+ if (GUILayout.Button("Analyze Assets"))
+ {
+ AnalyzeAssets();
+ }
+
+ if (GUILayout.Button("Optimize Large Textures"))
+ {
+ OptimizeLargeTextures();
+ }
+
+ EditorGUILayout.Space();
+
+ if (assetInfos.Count > 0)
+ {
+ GUILayout.Label($"Found {assetInfos.Count} assets", EditorStyles.boldLabel);
+
+ scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
+
+ foreach (var info in assetInfos.OrderByDescending(a => a.size))
+ {
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField(info.name, GUILayout.Width(200));
+ EditorGUILayout.LabelField($"{info.size / 1024} KB", GUILayout.Width(100));
+
+ if (info.width > 0)
+ {
+ EditorGUILayout.LabelField($"{info.width}x{info.height}", GUILayout.Width(100));
+ }
+
+ if (GUILayout.Button("Select", GUILayout.Width(60)))
+ {
+ Selection.activeObject = AssetDatabase.LoadAssetAtPath