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.
// 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
}
// 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
}