Debug Tools and Techniques
Console Debug Commands
// Add these context menu items to your orchestrator:
[ContextMenu("Debug: Show All Formulas")]
void DebugShowFormulas()
{
Debug.Log("=== Formula Debug Report ===");
foreach (var formula in formulas)
{
if (formula != null)
{
Debug.Log($" {formula.formulaName}: Enabled={formula.enabled}, Order={formula.executionOrder}");
}
else
{
Debug.LogWarning(" Null formula asset detected");
}
}
}
[ContextMenu("Debug: Test Single Formula")]
void DebugTestFormula()
{
if (formulas.Count > 0 && formulas[0] != null)
{
float result = formulas[0].Calculate(this);
Debug.Log($"Formula {formulas[0].formulaName} result: {result}");
}
}
[ContextMenu("Debug: Show Attribute Values")]
void DebugAttributeValues()
{
var allAttrs = attributeSystem.GetAllAttributes();
foreach (var attr in allAttrs)
{
Debug.Log($"{attr.name}: base={attr.baseValue:F1}, formula={attr.formulaBonus:F1}, " +
$"modifier={attr.modifierBonus:F1}, total={attr.totalValue:F1}");
}
}
Performance Profiling
// Performance measurement script:
public class PerformanceProfiler : MonoBehaviour
{
private System.Diagnostics.Stopwatch stopwatch;
void Start()
{
stopwatch = new System.Diagnostics.Stopwatch();
}
[ContextMenu("Profile Formula Performance")]
void ProfileFormulas()
{
var orchestrator = GetComponent(); // Your orchestrator
stopwatch.Restart();
// Test multiple calculations
for (int i = 0; i < 100; i++)
{
orchestrator.SendMessage("RecalculateAll");
}
stopwatch.Stop();
float avgTime = stopwatch.ElapsedMilliseconds / 100f;
Debug.Log($"Average calculation time: {avgTime:F2}ms");
if (avgTime > 1.0f)
{
Debug.LogWarning("Performance may be too slow for real-time updates");
}
}
}
Validation Tools
// Comprehensive system validation:
public class SystemValidator : MonoBehaviour
{
[ContextMenu("Validate Complete System")]
void ValidateSystem()
{
Debug.Log("=== System Validation Report ===");
// Check components
var attributes = GetComponent();
var orchestrator = GetComponent();
if (attributes == null)
{
Debug.LogError(" No ISimpleAttributeDataSource component");
return;
}
if (orchestrator == null)
{
Debug.LogError(" No orchestrator component");
return;
}
// Test attribute access
try
{
var allAttrs = attributes.GetAllAttributes();
Debug.Log($" {allAttrs.Count()} attributes accessible");
foreach (var attr in allAttrs)
{
if (float.IsNaN(attr.totalValue) || float.IsInfinity(attr.totalValue))
{
Debug.LogError($" {attr.name} has invalid totalValue: {attr.totalValue}");
}
}
}
catch (System.Exception e)
{
Debug.LogError($" Attribute access failed: {e.Message}");
}
Debug.Log("=== End Validation Report ===");
}
}
Advanced Troubleshooting
Memory Issues
Memory Management Best Practices:
• Avoid creating formula assets at runtime
• Cache attribute references instead of repeated lookups
• Use object pooling for temporary calculation objects
• Profile memory usage during long play sessions
Memory Leak Detection:
1. Use Unity Profiler to monitor memory usage
2. Look for growing allocations in GC.Alloc
3. Check for unclosed coroutines in regeneration systems
4. Monitor formula asset creation/destruction
Thread Safety
Thread Safety Guidelines:
• Formula calculations are NOT thread-safe
• Always calculate on main Unity thread
• Use Coroutines for long-running calculations
• Avoid formula access from background threads
Safe Multithreading Pattern:
// Background thread calculates values
float[] values = CalculateInBackground();
// Main thread applies results
UnityMainThreadDispatcher.Instance.Enqueue(() => {
ApplyCalculatedValues(values);
});
Save/Load Corruption
Save/Load Troubleshooting:
Common Issues:
• Saving formulaBonus (should save baseValue only)
• Not recalculating formulas after loading
• Missing currentValue for Vitals
• Incorrect value tier assignments
Robust Save/Load Pattern:
// Saving
SaveData.SetFloat($"{attr.name}_base", attr.baseValue);
if (attr.isVital)
{
SaveData.SetFloat($"{attr.name}_current", attr.currentValue);
}
// Loading
attr.baseValue = SaveData.GetFloat($"{attr.name}_base");
if (attr.isVital)
{
attr.currentValue = SaveData.GetFloat($"{attr.name}_current");
}
// IMPORTANT: Recalculate after loading all attributes
orchestrator.RecalculateAll();
Diagnostic Scripts
Complete System Diagnostic
using UnityEngine;
using SimpleAttributeForge;
using System.Linq;
public class UltimateSystemDiagnostic : MonoBehaviour
{
[ContextMenu("Run Complete Diagnostic")]
void RunDiagnostic()
{
Debug.Log("=== Simple Attribute Forge Ultimate Diagnostic ===");
// Component checks
CheckComponents();
// Attribute system checks
CheckAttributeSystem();
// Formula system checks
CheckFormulaSystem();
// Performance checks
CheckPerformance();
Debug.Log("=== Diagnostic Complete ===");
}
void CheckComponents()
{
Debug.Log("--- Component Check ---");
var attributeComp = GetComponent();
var orchestratorComp = GetComponents()
.FirstOrDefault(mb => mb.GetType().Name.Contains("Influence"));
Debug.Log($"Attribute Component: {(attributeComp != null ? " Found" : " Missing")}");
Debug.Log($"Orchestrator Component: {(orchestratorComp != null ? " Found" : " Missing")}");
if (orchestratorComp != null)
{
Debug.Log($"Orchestrator Type: {orchestratorComp.GetType().Name}");
}
}
void CheckAttributeSystem()
{
Debug.Log("--- Attribute System Check ---");
var attributes = GetComponent();
if (attributes == null) return;
var allAttrs = attributes.GetAllAttributes();
Debug.Log($"Total Attributes: {allAttrs.Count()}");
foreach (var attr in allAttrs)
{
bool hasValidValues = !float.IsNaN(attr.totalValue) && !float.IsInfinity(attr.totalValue);
Debug.Log($"{attr.name}: {(hasValidValues ? "" : "")} Values valid");
if (!hasValidValues)
{
Debug.LogError($" → {attr.name} has invalid values: " +
$"base={attr.baseValue}, formula={attr.formulaBonus}, total={attr.totalValue}");
}
}
}
void CheckFormulaSystem()
{
Debug.Log("--- Formula System Check ---");
var orchestrator = GetComponents()
.FirstOrDefault(mb => mb.GetType().Name.Contains("Influence"));
if (orchestrator == null)
{
Debug.LogError("No orchestrator found");
return;
}
// Use reflection to check formula assets
var formulasField = orchestrator.GetType().GetField("formulas");
if (formulasField != null)
{
var formulas = formulasField.GetValue(orchestrator) as System.Collections.IList;
Debug.Log($"Formula Assets: {formulas?.Count ?? 0}");
if (formulas != null)
{
for (int i = 0; i < formulas.Count; i++)
{
var formula = formulas[i];
Debug.Log($" Formula {i}: {(formula != null ? " Valid" : " Null")}");
}
}
}
}
void CheckPerformance()
{
Debug.Log("--- Performance Check ---");
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
// Test calculation performance
var orchestrator = GetComponents()
.FirstOrDefault(mb => mb.GetType().Name.Contains("Influence"));
if (orchestrator != null)
{
orchestrator.SendMessage("RecalculateAll");
stopwatch.Stop();
float calcTime = stopwatch.ElapsedMilliseconds;
Debug.Log($"Calculation Time: {calcTime:F2}ms");
if (calcTime > 5f)
{
Debug.LogWarning("Calculation time may be too slow for real-time updates");
}
}
}
}
Formula Validation Tool
using UnityEngine;
using UnityEditor;
public class FormulaValidationTool : EditorWindow
{
[MenuItem("Tools/Simple Formula Validator")]
static void ShowWindow()
{
GetWindow("Formula Validator");
}
void OnGUI()
{
GUILayout.Label("Formula System Validation", EditorStyles.boldLabel);
if (GUILayout.Button("Validate All Formula Assets"))
{
ValidateAllFormulas();
}
if (GUILayout.Button("Check Circular Dependencies"))
{
CheckCircularDependencies();
}
if (GUILayout.Button("Performance Test"))
{
PerformanceTest();
}
}
void ValidateAllFormulas()
{
// Find all formula assets in project
var formulaGuids = AssetDatabase.FindAssets("t:FormulaAsset");
Debug.Log($"Found {formulaGuids.Length} formula assets");
foreach (var guid in formulaGuids)
{
var path = AssetDatabase.GUIDToAssetPath(guid);
var formula = AssetDatabase.LoadAssetAtPath(path);
if (formula != null)
{
Debug.Log($" {formula.name}: Valid");
}
else
{
Debug.LogError($" Failed to load formula at {path}");
}
}
}
}
Getting Help
When You Need Additional Help:
Support Information
When Contacting Support, Include:
• Unity version and platform
• Simple Attribute Forge versions (base + Ultimate)
• Console error messages (copy full text)
• Screenshots of wizard configuration
• Minimal reproduction steps
• Project setup details (single vs multi-character, etc.)
Community Resources
- Unity Forums: Search for Simple Attribute Forge discussions
- Asset Store Reviews: Check Q&A section for similar issues
- Documentation Examples: All examples in docs are tested and working
Preventive Measures
Development Best Practices
- Start Simple: Begin with basic formulas, add complexity gradually
- Test Frequently: Use Test Preview panel during formula creation
- Backup Regularly: Export formula configurations before major changes
- Document Dependencies: Note formula relationships in design docs
- Version Control: Track generated files in version control
System Maintenance
Regular Maintenance Tasks:
• Export formula backups before Unity upgrades
• Test formula calculations after package updates
• Validate import/export compatibility with team
• Review performance metrics periodically
• Check for deprecated API usage in generated code
Error Prevention
Avoid Common Problems:
- Always regenerate base system before adding Pro features
- Test formulas in wizard before generating orchestrator
- Use descriptive names for formulas and avoid special characters
- Keep formula complexity reasonable (max 5 breakpoints per formula)
- Document formula logic for team collaboration