All Docs Documentation Version: Base (Free) Influence System Ultimate
Simple Attribute Forge Ultimate

API Reference

Complete Ultimate system API documentation

Core Interfaces

IAttributeProvider

Interface implemented by the generated orchestrator for attribute access during formula calculations.

public interface IAttributeProvider { // Primary attribute access - used by formulas SimpleRuntimeAttribute GetAttribute(string attributeName); IEnumerable<SimpleRuntimeAttribute> GetAllAttributes(); // Value access - returns baseValue for formula calculations float GetAttributeValue(string attributeName); // Attribute existence check bool HasAttribute(string attributeName); }
Critical: GetAttributeValue() returns baseValue, not totalValue, to prevent feedback loops in formula calculations.

FormulaAsset Class

ScriptableObject that defines a single formula with its complete configuration.

Core Properties

public class FormulaAsset : ScriptableObject { [Header("Basic Configuration")] public string formulaName; // Unique identifier public string targetAttribute; // Attribute to modify public int executionOrder; // Calculation priority [Header("Pipeline Configuration")] public StartMode startMode; // Zero or TargetBase public ApplyMode applyMode; // How to apply result public FormulaTarget targetProperty; // Which property to write to public bool alsoUpdateCurrent; // Update currentValue for Vitals [Header("Formula Steps")] public List<FormulaRow> flatRows; // Step 2: Flat bonuses public List<FormulaRow> addPctRows; // Step 3: Additive percentages public List<FormulaRow> subPctRows; // Step 4: Subtractive percentages public List<MultiplierRow> mulRows; // Step 5: Multipliers public List<PostFlatRow> postFlatRows; // Step 6: Post-flat bonuses public List<Breakpoint> breakpoints; // Conditional effects // Calculation method public float Calculate(IAttributeProvider attributes); }

Enums

public enum StartMode { Zero, // Start calculation from 0 TargetBase // Start from target's baseValue } public enum ApplyMode { OverrideBase, // Replace baseValue with result AddToBase, // Add result to baseValue SubtractFromBase // Subtract result from baseValue }

Formula Row Types

FormulaRow (Flat and Percentage Bonuses)

public class FormulaRow { public string id; // Unique identifier public string source; // Source attribute name public MathOperation operation; // Math operation to apply public float value; // Multiplier/percentage value } public enum MathOperation { Add, // Positive contribution Divide, // Division Multiply, // Multiplication Percentage, // Percentage-based Subtract // Negative contribution }

MultiplierRow (Step 5)

public class MultiplierRow { public string label; // Description/identifier public float factor; // Multiplication value }

PostFlatRow (Step 6)

public class PostFlatRow { public string label; // Description/identifier public float amount; // Flat value to add/subtract public bool isAdditive; // true = add, false = subtract }

Breakpoint System

Breakpoint Class

public class Breakpoint { [Header("Primary Condition")] public string attribute; // Attribute to check public ComparisonOp comparison; // Comparison operator public float value; // Threshold value [Header("Multiple Conditions")] public bool hasAdditionalConditions; public LogicalOperator globalLogicalOp; // AND/OR public List<BreakpointCondition> additionalConditions; [Header("Effect")] public BreakpointType type; // Threshold or Step public BreakpointEffect effectType; // Which pipeline step to affect public float effectValue; // Magnitude of effect public MathOperation operation; // Add or subtract effect }

Breakpoint Enums

public enum BreakpointType { Threshold, // Activates once when condition met Step // Activates multiple times at intervals } public enum BreakpointEffect { Flat, // Affects Step 2 (flat bonuses) AddPercent, // Affects Step 3 (additive percentages) SubPercent, // Affects Step 4 (subtractive percentages) Multiplier, // Affects Step 5 (multipliers) PostFlat // Affects Step 6 (post-flat bonuses) } public enum ComparisonOp { Equal, NotEqual, Greater, GreaterOrEqual, Less, LessOrEqual } public enum LogicalOperator { And, // All conditions must be true Or // Any condition can be true }

Generated Orchestrator

The wizard generates a complete MonoBehaviour orchestrator that manages all formula execution.

Core Properties

public class [SystemName] : MonoBehaviour, IAttributeProvider { [Header("System Configuration")] [SerializeField] private MonoBehaviour attributeSystem; // ISimpleAttributeDataSource [SerializeField] private List<FormulaAsset> formulas; // Formula assets [Header("Update Configuration")] [SerializeField] private UpdateMode updateMode; [SerializeField] private float intervalUpdateRate; [SerializeField] private bool enableCaching; [SerializeField] private bool debugMode; }

Public Methods

// Primary recalculation methods public void RecalculateAll(); // Recalculate all formulas public void RecalculateAttribute(string name); // Recalculate specific attribute public void RecalculateFormula(string name); // Recalculate specific formula // Formula management public void AddFormula(FormulaAsset formula); // Add formula at runtime public void RemoveFormula(string formulaName); // Remove formula at runtime public void ClearFormulas(); // Clear all formulas // State queries public bool HasFormula(string name); // Check formula existence public FormulaAsset GetFormula(string name); // Get formula asset public string[] GetFormulaNames(); // Get all formula names // IAttributeProvider implementation public SimpleRuntimeAttribute GetAttribute(string attributeName); public float GetAttributeValue(string attributeName); public bool HasAttribute(string attributeName);

Configuration Enums

public enum UpdateMode { Manual, // Only on explicit RecalculateAll() calls Update, // Recalculate every Update frame FixedUpdate, // Recalculate every FixedUpdate frame Smart, // Event-driven updates (recommended) Interval // Fixed time interval updates }

FormulaCalculator

Static utility class that performs the actual mathematical calculations.

public static class FormulaCalculator { // Main calculation pipeline (single entry point) public static float CalculatePipeline( float startValue, List<FormulaRow> flatRows, List<FormulaRow> addPctRows, List<FormulaRow> subPctRows, List<MultiplierRow> mulRows, List<PostFlatRow> postFlatRows, List<Breakpoint> breakpoints, IAttributeProvider attributes, float? levelOverride = null ); }

Extension Methods

Utility extensions for easier integration with existing code.

SimpleAttributeSystemExtensions

public static class SimpleAttributeSystemExtensions { // Find attribute system on GameObject (compatibility layer) public static MonoBehaviour FindAttributeSystem(this GameObject gameObject); // Get runtime attribute (works with any ISimpleAttributeDataSource) public static SimpleRuntimeAttribute GetRuntimeAttribute( this MonoBehaviour component, string attributeName); // Get all runtime attributes public static Dictionary<string, SimpleRuntimeAttribute> GetAllRuntimeAttributes( this MonoBehaviour component); // Check if component implements ISimpleAttributeDataSource public static bool IsAttributeSystem(this MonoBehaviour component); // Convenience value access with default fallback public static float GetAttributeValue( this MonoBehaviour component, string attributeName, float defaultValue = 0f); // Set attribute value (baseValue modification) public static bool SetAttributeValue( this MonoBehaviour component, string attributeName, float value); }

Usage Examples

// Extension method usage var health = gameObject.GetRuntimeAttribute("Health"); float healthValue = gameObject.GetAttributeValue("Health", 100f); // Direct component access var attributes = GetComponent<CharacterAttributes>(); float damage = attributes.strength.totalValue;

Formula Data Classes

SimpleInfluenceData

[Serializable] data container for complete influence system configuration, used by the wizard.

[Serializable] public class SimpleInfluenceData { // System Configuration public string SystemName { get; set; } public string Namespace { get; set; } public string OutputPath { get; set; } public string AssetSubfolder { get; set; } public string AttributeSourceClass { get; set; } // Update Settings public UpdateMode UpdateMode { get; set; } public float UpdateInterval { get; set; } public bool EnableCaching { get; set; } public int MaxCalculationsPerFrame { get; set; } public string UpdateTrigger { get; set; } // Level Scaling public bool EnableLevelScaling { get; set; } public string LevelSourceAttribute { get; set; } // Attribute Info public List<string> AvailableAttributes { get; set; } public List<string> VitalAttributes { get; set; } public bool IsVitalAttribute(string attributeName); // Formula Data public List<SimpleFormulaData> Formulas { get; set; } // Validation and utility methods public bool Validate(out List<string> errors, out List<string> warnings); public List<SimpleFormulaData> GetEnabledFormulas(); public List<SimpleFormulaData> GetFormulasTargeting(string attributeName); }

SimpleFormulaData

[Serializable] individual formula configuration data used by the wizard and code generation.

[Serializable] public class SimpleFormulaData { // Identity public string Name { get; set; } public string TargetAttribute { get; set; } public int ExecutionOrder { get; set; } public bool Enabled { get; set; } // Calculation Settings public StartMode StartMode { get; set; } public ApplyMode ApplyMode { get; set; } public FormulaTarget TargetProperty { get; set; } public bool AlsoUpdateCurrent { get; set; } // Pipeline Steps public List<FormulaRow> FlatRows; public List<FormulaRow> AddPctRows; public List<FormulaRow> SubPctRows; public List<MultiplierRow> MulRows; public List<PostFlatRow> PostFlatRows; public List<Breakpoint> Breakpoints; // Code Generation Flags public bool GenerateMonoBehaviour { get; set; } public bool GenerateScriptableObject { get; set; } public bool GenerateStaticHelper { get; set; } public bool HasAnyGenerationType(); // Utility methods public float Calculate(Dictionary<string, float> attributeValues); public bool Validate(string[] availableAttributes, out List<string> errors, out List<string> warnings); public HashSet<string> GetAllDependencies(); public bool HasCircularDependency( Dictionary<string, HashSet<string>> allFormulaDependencies); }

Generated Orchestrator Methods

The code generator creates specific methods for each formula in your system.

Per-Formula Methods

// Generated for each formula (example: "StrengthDamage") private float Calculate_StrengthDamage() { // Implements complete 7-step pipeline // Returns calculated result } private void Apply_StrengthDamage(float value) { // Applies result to target attribute's formulaBonus // Handles ApplyMode logic // Manages currentValue updates for Vitals }

Lifecycle Methods

void Awake() { // Initialize caching system // Validate configuration // Set up dependency tracking } void Start() { // Validate attribute system reference // Build dependency map // Perform initial calculation } void OnValidate() { // Editor-time validation // Update formula references } void OnDestroy() { // Cleanup event subscriptions // Stop interval coroutines }

Update Mode Implementation

// Smart mode - event-driven updates void SubscribeToAttributeEvents() { foreach (var attr in GetAllAttributes()) { attr.OnBaseValueChanged += OnAttributeChanged; } } // Interval mode - coroutine-based updates IEnumerator IntervalUpdateCoroutine() { while (enabled) { yield return new WaitForSeconds(intervalUpdateRate); if (ShouldRecalculate()) RecalculateAll(); } } // Manual mode - explicit calls only // No automatic updates

Validation System

Runtime Validation

// Circular dependency detection private HashSet<string> currentlyCalculating = new HashSet<string>(); bool DetectCircularDependency(string formulaName) { if (currentlyCalculating.Contains(formulaName)) { LogError($"Circular dependency detected: {formulaName}"); return true; } return false; } // Attribute existence validation bool ValidateAttributeReferences(FormulaAsset formula) { foreach (var row in formula.flatRows) { if (!HasAttribute(row.source)) { LogError($"Missing attribute: {row.source}"); return false; } } return true; }

Value Boundary Enforcement

float ClampResult(float result, SimpleRuntimeAttribute target) { // Respect attribute min/max values if (target.minValue != target.maxValue) { result = Mathf.Clamp(result, target.minValue, target.maxValue); } // Force integer for Resource types if (target.behaviorType == SimpleBehaviorType.Resource && target.forceInteger) { result = Mathf.Round(result); } return result; }

Performance Features

Dependency Tracking

// Automatic dependency mapping private Dictionary<string, HashSet<string>> dependencyMap; void BuildDependencyMap() { dependencyMap.Clear(); foreach (var formula in formulas) { var dependencies = formula.GetSourceAttributes(); foreach (var dep in dependencies) { if (!dependencyMap.ContainsKey(dep)) dependencyMap[dep] = new HashSet<string>(); dependencyMap[dep].Add(formula.targetAttribute); } } } // Smart recalculation - only affected formulas void OnAttributeChanged(SimpleRuntimeAttribute attr, float oldValue, float newValue) { if (dependencyMap.ContainsKey(attr.attributeName)) { foreach (string targetAttr in dependencyMap[attr.attributeName]) { RecalculateAttribute(targetAttr); } } }

Caching System

// Optional caching for high-frequency calculations private Dictionary<string, float> lastValues; private Dictionary<string, SimpleRuntimeAttribute> attributeCache; void RefreshAttributeCache() { if (!enableCaching) return; attributeCache.Clear(); var allAttrs = attributeSystem.GetAllRuntimeAttributes(); foreach (var kvp in allAttrs) { attributeCache[kvp.Key] = kvp.Value; } } SimpleRuntimeAttribute GetCachedAttribute(string name) { if (enableCaching && attributeCache.ContainsKey(name)) return attributeCache[name]; return attributeSystem.GetRuntimeAttribute(name); }

Integration Patterns

Accessing Orchestrator in Code

public class GameManager : MonoBehaviour { // Direct reference [SerializeField] private CharacterInfluence orchestrator; // Or find dynamically void Start() { orchestrator = GetComponent<CharacterInfluence>(); // Or from any GameObject: // orchestrator = FindObjectOfType<CharacterInfluence>(); } void ModifyAttribute(string attrName, float delta) { var attr = orchestrator.GetAttribute(attrName); if (attr != null) { attr.baseValue += delta; // Manual recalculation if using Manual update mode orchestrator.RecalculateAttribute(attrName); } } }

Runtime Formula Modification

public class DynamicFormulas : MonoBehaviour { public void CreateTemporaryFormula() { // Create formula asset at runtime var formula = ScriptableObject.CreateInstance<FormulaAsset>(); formula.formulaName = "TempBonus"; formula.targetAttribute = "Damage"; formula.startMode = StartMode.Zero; formula.applyMode = ApplyMode.AddToBase; // Add flat bonus formula.flatRows.Add(new FormulaRow { source = "Level", operation = MathOperation.Add, value = 5f }); // Add to orchestrator var orchestrator = GetComponent<CharacterInfluence>(); orchestrator.AddFormula(formula); } }

Common Usage Patterns

Reading Values in Gameplay

// CORRECT - Use totalValue for gameplay float attackDamage = strength.totalValue * weaponModifier; float maxHealth = health.totalValue; float currentHealth = health.currentValue; // Vitals only // INCORRECT - Don't use for gameplay float damage = strength.baseValue; // Ignores formula bonuses float damage = strength.formulaBonus; // Only formula portion

Modifying Values

// CORRECT - Permanent changes strength.baseValue += 5; // Equipment, upgrades, permanent bonuses // CORRECT - Temporary effects strength.modifierBonus += 10; // Buffs, temporary bonuses // INCORRECT - Never modify directly strength.formulaBonus = 20; // Managed by orchestrator only strength.totalValue = 50; // Read-only calculated value

Event Handling

void Start() { var attributes = GetComponent<CharacterAttributes>(); // Listen for attribute changes attributes.health.OnValueChanged += UpdateHealthUI; attributes.health.OnReachedZero += HandleDeath; // Listen for base value changes (triggers formula recalc) attributes.strength.OnBaseValueChanged += OnStrengthChanged; } void OnStrengthChanged(SimpleRuntimeAttribute attr, float oldValue, float newValue) { // Formulas depending on strength will auto-recalculate Debug.Log($"Strength changed: {oldValue} → {newValue}"); }

Debug and Testing API

Debug Mode Features

// Enable debug logging orchestrator.debugMode = true; // Debug specific formula orchestrator.DebugFormula("StrengthDamage"); // Debug output example: // [FormulaDebug] StrengthDamage calculation: // - Start: 0 // - Flat: Strength(10) × 1.5 = 15 // - Result: 15 // - Applied to Damage.formulaBonus

Testing Utilities

// Test formula with specific values public float TestFormula(string formulaName, Dictionary<string, float> testValues) { var formula = GetFormula(formulaName); if (formula == null) return 0f; // Create temporary test provider var testProvider = new TestAttributeProvider(testValues); return formula.Calculate(testProvider); } // Manual calculation breakdown public FormulaBreakdown GetFormulaBreakdown(string formulaName) { // Returns step-by-step calculation details // Useful for debugging and UI display }