Troubleshooting Guide
Common issues and solutions for Simple Attribute Forge. Updated for the modern three-tier value system.
Installation & Setup Issues
Wizard Menu Missing
Problem: "Window → Simple Attribute Forge" menu doesn't appear
Solutions:
Wait for Unity to finish compiling scripts (check progress bar)
Check Console for compilation errors that prevent script loading
Ensure all Simple Attribute Forge files are in correct folder structure
Right-click on Simple Attribute Forge folder → Reimport
Clear Library folder and restart Unity if necessary
Verify Unity version compatibility (2021.3+ required)
Compilation Errors
Problem: Red errors in Console preventing compilation
Solutions:
Check Unity version (2021.3 LTS or newer required)
Ensure all Simple Attribute Forge files imported correctly
Look for conflicting scripts with same class names
Clear Library folder and let Unity regenerate
Check for .meta file corruption (reimport if needed)
Generated Files Not Appearing
Problem: Wizard completes but no files generated
Solutions:
Check specified output directories exist and are valid
Ensure write permissions on output folders
Look in Project window, files might be in different location
Check Console for file generation errors
Refresh Project window (F5 or right-click → Refresh)
Runtime & Usage Issues
Values Not Updating Correctly
Problem: Attribute values don't behave as expected
Common Causes & Solutions:
Using baseValue instead of totalValue: Always use totalValue for gameplay logic
Old .value property: Update to totalValue or currentValue (for Vitals)
Manual formulaBonus modification: Never modify formulaBonus directly - let Ultimate's Influence System handle it
Missing component reference: Ensure attribute component is assigned
// ❌ WRONG - Common mistakes
float damage = strength.baseValue * weapon; // Missing bonuses!
float health = healthAttr.value; // Property doesn't exist
strength.formulaBonus += 10; // Will be overwritten!
// ✅ CORRECT - Modern patterns
float damage = strength.totalValue * weapon; // Includes all bonuses
float health = healthAttr.currentValue; // For Vitals
float maxHealth = healthAttr.totalValue; // For max values
Regeneration Not Working
Problem: Vital attributes don't regenerate automatically
Checklist:
Behavior Type: Must be set to "Vital"
Can Regenerate: Must be enabled (true)
Regeneration Rate: Must be greater than 0
Damage Method: Use ModifyValue(), not SetValue()
GameObject Active: Component GameObject must be active
Not At Max: Already full attributes won't regenerate
// ✅ Correct way to enable regeneration
health.canRegenerate = true;
health.regenerationRate = 5.0f; // 5 HP per second
health.regenerationDelay = 3.0f; // 3 second delay
// ✅ Correct way to trigger regeneration
health.ModifyValue(-30f); // Triggers regen after delay
// ❌ Wrong way - won't trigger regeneration
health.SetValue(health.currentValue - 30f); // Administrative change
Events Not Firing
Problem: Attribute events not triggering UI updates
Solutions:
Subscribe Correctly: Use proper event syntax with +=
Unsubscribe on Destroy: Prevent null reference exceptions
Check Event Names: Use exact case-sensitive names
Value Change Method: Use ModifyValue() or proper setters
// ✅ Correct event subscription
void Start()
{
var attributes = GetComponent<CharacterAttributes>();
// Individual attribute events
attributes.health.OnValueChanged += UpdateHealthUI;
attributes.health.OnReachedZero += HandleDeath;
// Component-wide events
attributes.OnAnyAttributeChanged += LogAttributeChange;
}
void OnDestroy()
{
// ✅ Always unsubscribe to prevent memory leaks
if (attributes?.health != null)
{
attributes.health.OnValueChanged -= UpdateHealthUI;
attributes.health.OnReachedZero -= HandleDeath;
}
}
Code Generation Issues
Compilation Errors After Generation
Problem: Generated code has compilation errors
Solutions:
Invalid Characters: Check attribute names for special characters
Reserved Keywords: Don't use C# keywords as attribute names
Duplicate Names: Ensure all attribute names are unique
Empty Names: All attributes must have valid names
Namespace Conflicts: Check for conflicting namespaces
Component Not Appearing in Add Component Menu
Problem: Generated MonoBehaviour not available
Solutions:
Wait for Unity to finish compiling (no progress bar in lower-right)
Check Console for compilation errors
Refresh Project window (F5)
Look for component under correct namespace in Add Component menu
Search for component by name in Add Component search box
ScriptableObject Asset Issues
Problem: Generated .asset file not working properly
Solutions:
Missing Assignment: Drag .asset file to "Data Asset" field on component
Asset Corruption: Delete .asset and regenerate through wizard
Meta File Issues: Delete .asset.meta file and let Unity regenerate
Inspector Not Showing Values: Click on .asset file to see contents
Three-Tier Value System Issues
Bonuses Not Showing
Problem: formulaBonus or modifierBonus not reflecting in totalValue
Debug Steps:
Check Individual Values: Log baseValue, formulaBonus, modifierBonus separately
Verify Calculation: totalValue should equal base + formula + modifier
Formula Integration: Ensure Ultimate's Influence System orchestrator is recalculating
Modifier Application: Check if modifierBonus being set correctly
// Debug attribute values
public void DebugAttributeValues()
{
var attr = attributes.GetRuntimeAttribute("Strength");
Debug.Log($"STR Base: {attr.baseValue}");
Debug.Log($"STR Formula: {attr.formulaBonus}");
Debug.Log($"STR Modifier: {attr.modifierBonus}");
Debug.Log($"STR Total: {attr.totalValue}");
Debug.Log($"Expected: {attr.baseValue + attr.formulaBonus + attr.modifierBonus}");
}
Values Accumulating Incorrectly
Problem: Attribute values growing unexpectedly over time
Common Causes:
Reading totalValue for Formulas: Formulas should read baseValue only
Multiple Formula Applications: Check for duplicate formula execution
Modifier Stacking: Ensure temporary effects are properly removed
Save/Load Issues: Don't save formulaBonus or modifierBonus
// ✅ Correct formula input (Ultimate's Influence System)
// Formulas should read baseValue to prevent accumulation
float strengthBonus = strength.baseValue * 0.5f;
// ✅ Correct modifier management
public void ApplyTemporaryBuff(float amount, float duration)
{
attribute.modifierBonus += amount; // Apply
StartCoroutine(RemoveBuffAfterDelay(amount, duration));
}
IEnumerator RemoveBuffAfterDelay(float amount, float duration)
{
yield return new WaitForSeconds(duration);
attribute.modifierBonus -= amount; // Remove
}
Performance Issues
High CPU Usage
Problem: Attribute system causing performance drops
Optimizations:
Cache References: Store attribute references instead of lookup each frame
Throttle UI Updates: Update UI at intervals, not every frame
Event Management: Unsubscribe unused events
Regeneration Limits: Avoid excessive regeneration rates
// ✅ Performance-optimized patterns
public class OptimizedAttributeUI : MonoBehaviour
{
private SimpleRuntimeAttribute health; // Cache reference
private float lastUpdateTime;
private float updateInterval = 0.1f; // Throttle updates
void Start()
{
health = GetComponent<CharacterAttributes>().health;
health.OnValueChanged += MarkDirty; // Event-driven updates
}
void Update()
{
if (isDirty && Time.time - lastUpdateTime > updateInterval)
{
UpdateUI();
lastUpdateTime = Time.time;
isDirty = false;
}
}
}
Memory Leaks
Problem: Memory usage grows over time
Prevention:
Unsubscribe Events: Always unsubscribe in OnDestroy
Stop Coroutines: Stop regeneration coroutines when needed
Null Checks: Check for null before accessing attributes
Object Cleanup: Properly dispose temporary objects
Integration Issues
Ultimate Integration
Problem: Simple Attribute Forge Ultimate subsystems not working with generated attributes
Requirements:
Interface Implementation: Component implements ISimpleAttributeDataSource
Modern Architecture: Uses three-tier value system
OnBaseValueChanged Events: Available for formula triggers
Regenerated Code: Use latest wizard to ensure compatibility
Ultimate Installed: Influence, Modifier, and Character Template systems require Ultimate
Save/Load System
Problem: Attributes not saving/loading correctly
Best Practices:
Save baseValue: This is the persistent value
Save currentValue: For Vital attributes only
Don't Save Bonuses: formulaBonus and modifierBonus are runtime
Recalculate on Load: Let formulas recalculate after loading
// ✅ Correct save/load pattern
[System.Serializable]
public class AttributeSaveData
{
public Dictionary<string, float> baseValues = new();
public Dictionary<string, float> currentValues = new(); // Vitals only
// DON'T save formulaBonus or modifierBonus
}
void SaveAttributes()
{
foreach (var kvp in attributes.GetAllRuntimeAttributes())
{
var attr = kvp.Value;
saveData.baseValues[attr.attributeName] = attr.baseValue;
if (attr.behaviorType == SimpleBehaviorType.Vital)
saveData.currentValues[attr.attributeName] = attr.currentValue;
}
}
Getting Help
Debug Tools
Context Menu: Right-click component → "Log All Attributes"
Inspector Values: Use "Set Attribute Value" for testing
Debug Regeneration: "Debug Active Regeneration" shows coroutines
Common Debug Code
// Log all attribute states
[ContextMenu("Debug All Attributes")]
void DebugAll()
{
foreach(var attr in GetAllRuntimeAttributes().Values)
{
Debug.Log($"{attr.attributeName}: {attr.baseValue} + {attr.formulaBonus} + {attr.modifierBonus} = {attr.totalValue}");
}
}
Support
Check Unity Console for detailed error messages
Try regenerating components with latest wizard
Test with fresh Unity project to isolate issues
Include error messages when seeking help
Most Common Fix:
Many issues are resolved by updating code from the old .value property to the modern three-tier system using .totalValue, .currentValue, and .baseValue appropriately.