Ultimate Dice Roll Toolkit

Advanced Features: Professional-Grade Capabilities

Professional-grade capabilities for complex dice mechanics, deterministic systems, statistical analysis, and enterprise-level game development requirements. These features leverage the full power of the 29-script framework architecture.

Production-Ready Features: Advanced functionality designed for professional game development with network synchronization, deterministic simulation, complex probability management, and sophisticated rule processing based on the actual codebase.

Seeded Random Systems

Deterministic Rolling with SeededRandom

The SeededRandom class provides deterministic random number generation for reproducible results across sessions:

Deterministic Roll Implementation

// Initialize seeded random for deterministic results
DiceAPI.InitializeSeed("GameSession_2024_01_15");

// All subsequent rolls are deterministic and reproducible
int roll1 = DiceAPI.Roll(20, 5);  // Always same result for this seed
int roll2 = DiceAPI.Roll(6, 2);   // Next in deterministic sequence
int roll3 = DiceAPI.Roll(10);     // Continues sequence

// Reset to same seed to replay exact sequence
DiceAPI.InitializeSeed("GameSession_2024_01_15");
int replayRoll1 = DiceAPI.Roll(20, 5);  // Identical to roll1

Debug.Log($"Original: {roll1}, Replay: {replayRoll1}"); // Should be identical

// Return to system random for normal gameplay
DiceAPI.InitializeSystemRandom();

Network Synchronization

Using seeded random for multiplayer dice synchronization:

Multiplayer Synchronization Pattern

public class NetworkedDiceManager : MonoBehaviour
{
    public void ExecuteNetworkRoll(int sides, int modifier, string playerName)
    {
        // Generate network seed from game state + timestamp
        string networkSeed = $"{Time.time}_{playerName}_{Random.Range(1000, 9999)}";
        
        // Server executes seeded roll
        DiceAPI.InitializeSeed(networkSeed);
        int result = DiceAPI.Roll(sides, modifier);
        
        // Send seed and result to all clients for verification
        SendNetworkRoll(sides, modifier, networkSeed, result, playerName);
    }
    
    private void SendNetworkRoll(int sides, int modifier, string seed, int expected, string player)
    {
        // Network RPC or similar to synchronize all clients
        foreach (var client in NetworkManager.ConnectedClients)
        {
            client.VerifyNetworkRoll(sides, modifier, seed, expected, player);
        }
    }
    
    public void VerifyNetworkRoll(int sides, int modifier, string seed, int expected, string player)
    {
        // Client verifies result using same seed
        DiceAPI.InitializeSeed(seed);
        int clientResult = DiceAPI.Roll(sides, modifier);
        
        if (clientResult == expected)
        {
            Debug.Log($"{player} rolled {clientResult} - Verified");
            ProcessVerifiedRoll(clientResult, player);
        }
        else
        {
            Debug.LogError($"Network desync! Expected {expected}, got {clientResult}");
        }
    }
}

Procedural Content Generation

Using seeded generation for consistent procedural content:

Seeded Procedural Generation

public class SeededDungeonGenerator : MonoBehaviour
{
    public GeneratedDungeon CreateDungeon(string seedString, int roomCount)
    {
        // Initialize with seed for reproducible generation
        DiceAPI.InitializeSeed(seedString);
        
        var dungeon = new GeneratedDungeon();
        dungeon.rooms = new List<DungeonRoom>();
        
        for (int i = 0; i < roomCount; i++)
        {
            var room = new DungeonRoom();
            
            // Room size using drop dice for consistent distribution
            var sizeResult = DiceAPI.RollDrop(6, 4, 1, DropType.Lowest, 2); // 4d6 drop lowest + 2
            room.size = sizeResult.totalResult;
            
            // Room type using weighted distribution
            var typeConfig = ScriptableObject.CreateInstance<DiceConfiguration>();
            typeConfig.sides = 100;
            typeConfig.weightConfig.enabled = true;
            typeConfig.weightConfig.algorithm = WeightAlgorithm.BiasLow; // Common rooms more likely
            
            int typeRoll = DiceAPI.Roll(typeConfig);
            room.roomType = DetermineRoomType(typeRoll);
            
            // Monster population using pool system
            if (room.roomType == RoomType.MonsterDen)
            {
                var monsterPool = DiceAPI.RollPool(6, 8, 4); // 8d6, count 4+ as monsters
                room.monsterCount = monsterPool.totalResult;
            }
            
            // Treasure using exploding dice for rare high-value finds
            if (room.roomType == RoomType.TreasureRoom)
            {
                var treasureRoll = DiceAPI.RollExploding(10, 3); // d10 exploding max 3 times
                room.treasureValue = treasureRoll.totalResult * 100; // Scale up value
            }
            
            dungeon.rooms.Add(room);
        }
        
        // Reset to system random after generation
        DiceAPI.InitializeSystemRandom();
        
        return dungeon;
    }
    
    // Validation method for testing consistency
    public bool ValidateDungeonGeneration(string seed, GeneratedDungeon expected)
    {
        var testDungeon = CreateDungeon(seed, expected.rooms.Count);
        return CompareDungeons(testDungeon, expected);
    }
}

Advanced Conditional Rules

77 Rule Combinations

The framework provides 11 trigger types and 7 action types for 77 total rule combinations:

Complete Rule Matrix

Trigger Types (11)
  • OnMax: Natural maximum die result
  • OnMin: Natural minimum die result
  • OnValue: Specific die result
  • OnRange: Result within range
  • OnSuccess: Meeting target number
  • OnFailure: Missing target number
  • OnMargin: Exceeding target by amount
  • OnSequence: Consecutive results pattern
  • OnPattern: Specific result patterns
  • OnFlag: Conditional flag presence
  • OnModifier: Session modifier conditions
Action Types (7)
  • RollBonus: Add bonus dice rolls
  • AddValue: Add fixed value to result
  • MultiplyResult: Multiply result by factor
  • SetFlag: Set conditional flags
  • AddModifier: Add session modifier
  • Reroll: Force reroll with conditions
  • Cascade: Trigger additional rules

Rule Chaining and Priority

Complex rule systems with proper priority and chaining:

Advanced Rule Chain Implementation

public ConditionalRule[] CreateSpellcastingRules()
{
    var rules = new List<ConditionalRule>();
    
    // Rule 1: Critical Success (Priority 1 - Execute first)
    var criticalRule = ScriptableObject.CreateInstance<ConditionalRule>();
    criticalRule.ruleName = "Critical Success";
    criticalRule.priority = 1;
    criticalRule.enabled = true;
    criticalRule.chainable = true;
    
    criticalRule.trigger.type = TriggerType.OnMax;
    criticalRule.action.type = ActionType.SetFlag;
    criticalRule.action.flagName = "Critical";
    rules.Add(criticalRule);
    
    // Rule 2: Spell Damage on Success (Priority 5)
    var damageRule = ScriptableObject.CreateInstance<ConditionalRule>();
    damageRule.ruleName = "Spell Damage";
    damageRule.priority = 5;
    damageRule.enabled = true;
    damageRule.chainable = true;
    
    damageRule.trigger.type = TriggerType.OnSuccess;
    damageRule.trigger.targetNumber = 15; // Spell DC
    damageRule.action.type = ActionType.RollBonus;
    damageRule.action.diceConfig = new BonusDiceConfiguration
    {
        count = 2,
        sides = 6,
        modifier = 0,
        rollType = RollType.Normal
    };
    rules.Add(damageRule);
    
    // Rule 3: Critical Damage Enhancement (Priority 10 - After damage)
    var critDamageRule = ScriptableObject.CreateInstance<ConditionalRule>();
    critDamageRule.ruleName = "Critical Damage";
    critDamageRule.priority = 10;
    critDamageRule.enabled = true;
    critDamageRule.chainable = false;
    
    critDamageRule.trigger.type = TriggerType.OnFlag;
    critDamageRule.trigger.flagName = "Critical";
    critDamageRule.action.type = ActionType.MultiplyResult;
    critDamageRule.action.multiplier = 2.0f;
    rules.Add(critDamageRule);
    
    return rules.ToArray();
}

// Usage with rule processing
public RollResult CastSpell(DiceConfiguration spellConfig)
{
    var rules = CreateSpellcastingRules();
    var (result, nextModifier) = DiceAPI.RollWithRules(spellConfig, rules);
    
    // Apply accumulated modifier to modifier session
    if (nextModifier > 0)
    {
        ModifierSession.AddModifier(nextModifier, "Spell Momentum");
    }
    
    return result;
}

Dynamic Rule Processing

Context-aware rule activation and state-dependent processing:

Dynamic Rule System

public class DynamicRuleProcessor : MonoBehaviour
{
    private Dictionary<string, object> gameState = new Dictionary<string, object>();
    private List<ConditionalRule> availableRules = new List<ConditionalRule>();
    
    public RollResult ProcessDynamicRoll(DiceConfiguration baseConfig, string context = "")
    {
        // Filter rules based on current context and game state
        var applicableRules = GetApplicableRules(context);
        
        // Execute roll with context-filtered rules
        var (result, accumulatedModifier) = DiceAPI.RollWithRules(baseConfig, applicableRules);
        
        // Update game state based on result
        UpdateGameState(result, context);
        
        // Handle accumulated modifiers
        if (accumulatedModifier != 0)
        {
            ModifierSession.AddModifier(accumulatedModifier, $"Dynamic Rule - {context}");
        }
        
        return result;
    }
    
    private ConditionalRule[] GetApplicableRules(string context)
    {
        var applicable = new List<ConditionalRule>();
        
        foreach (var rule in availableRules)
        {
            if (IsRuleApplicable(rule, context))
            {
                applicable.Add(rule);
            }
        }
        
        // Sort by priority for proper execution order
        return applicable.OrderBy(r => r.priority).ToArray();
    }
    
    private bool IsRuleApplicable(ConditionalRule rule, string context)
    {
        // Context-based filtering
        if (context.Contains("combat") && !rule.ruleName.ToLower().Contains("combat"))
        {
            return false;
        }
        
        // Game state filtering
        if (rule.ruleName.Contains("Night") && !gameState.ContainsKey("IsNight"))
        {
            return false;
        }
        
        if (rule.ruleName.Contains("Magic") && !(bool)gameState.GetValueOrDefault("MagicEnabled", false))
        {
            return false;
        }
        
        // Resource-based filtering
        if (rule.trigger.type == TriggerType.OnModifier && 
            ModifierSession.GetTotalModifier() <= 0)
        {
            return false;
        }
        
        return rule.enabled;
    }
    
    private void UpdateGameState(RollResult result, string context)
    {
        // Update state based on roll outcome
        if (result.totalResult >= 18)
        {
            gameState["LastRollExceptional"] = true;
        }
        
        // Context-specific state updates
        if (context.Contains("spell") && result.naturalResult == 20)
        {
            gameState["SpellSurge"] = true;
        }
        
        // Track roll history for sequence-based rules
        if (!gameState.ContainsKey("RecentRolls"))
        {
            gameState["RecentRolls"] = new Queue<int>();
        }
        
        var recentRolls = (Queue<int>)gameState["RecentRolls"];
        recentRolls.Enqueue(result.naturalResult);
        if (recentRolls.Count > 5) // Keep last 5 rolls
        {
            recentRolls.Dequeue();
        }
    }
}

Statistical Analysis

Monte Carlo Simulation

The ProbabilityEngine provides sophisticated statistical analysis through Monte Carlo methods:

Comprehensive Statistical Analysis

public class StatisticalAnalyzer : MonoBehaviour
{
    public void AnalyzeWeaponBalance(DiceConfiguration weaponConfig)
    {
        // Perform Monte Carlo analysis with 50,000 iterations
        var probability = DiceAPI.CalculateProbability(
            weaponConfig, 
            15, // Target AC
            ComparisonType.GreaterEqual, 
            50000
        );
        
        Debug.Log("=== Weapon Balance Analysis ===");
        Debug.Log($"Configuration: {weaponConfig.displayName}");
        Debug.Log($"Hit Rate vs AC 15: {probability.percentage:F2}%");
        Debug.Log($"Average Roll: {probability.average:F2}");
        Debug.Log($"Standard Deviation: {probability.standardDeviation:F2}");
        Debug.Log($"Range: {probability.minimum} - {probability.maximum}");
        Debug.Log($"Median: {probability.median:F2}");
        
        // Analyze damage output with same weapon
        if (weaponConfig.rollType != RollType.Pool) // Don't analyze pool dice as damage
        {
            var damageAnalysis = AnalyzeDamageDistribution(weaponConfig, 10000);
            DisplayDamageAnalysis(damageAnalysis);
        }
    }
    
    private DamageDistribution AnalyzeDamageDistribution(DiceConfiguration config, int iterations)
    {
        var results = new List<int>();
        
        for (int i = 0; i < iterations; i++)
        {
            var result = DiceAPI.RollDetailed(config);
            results.Add(result.totalResult);
        }
        
        results.Sort();
        
        return new DamageDistribution
        {
            average = results.Average(),
            minimum = results.Min(),
            maximum = results.Max(),
            percentile25 = results[results.Count / 4],
            percentile75 = results[(3 * results.Count) / 4],
            median = results[results.Count / 2],
            standardDeviation = CalculateStandardDeviation(results),
            distribution = BuildDistributionMap(results)
        };
    }
    
    private Dictionary<int, float> BuildDistributionMap(List<int> results)
    {
        var distribution = new Dictionary<int, float>();
        var total = results.Count;
        
        foreach (var result in results)
        {
            if (!distribution.ContainsKey(result))
            {
                distribution[result] = 0;
            }
            distribution[result]++;
        }
        
        // Convert to percentages
        var percentageDistribution = new Dictionary<int, float>();
        foreach (var kvp in distribution)
        {
            percentageDistribution[kvp.Key] = (kvp.Value / total) * 100f;
        }
        
        return percentageDistribution;
    }
}

Probability Engine Usage

Advanced probability calculations for game balance:

Balance Validation System

public class GameBalanceValidator : MonoBehaviour
{
    public BalanceReport ValidateGameBalance(DiceConfiguration[] configs, int[] targetNumbers)
    {
        var report = new BalanceReport();
        report.configurations = new List<ConfigurationAnalysis>();
        
        foreach (var config in configs)
        {
            var configAnalysis = new ConfigurationAnalysis();
            configAnalysis.configName = config.displayName;
            configAnalysis.targetAnalysis = new List<TargetAnalysis>();
            
            foreach (var target in targetNumbers)
            {
                // Analyze success probability for each target
                var probability = DiceAPI.CalculateProbability(
                    config, target, ComparisonType.GreaterEqual, 25000);
                
                var targetAnalysis = new TargetAnalysis
                {
                    targetNumber = target,
                    successRate = probability.percentage,
                    averageRoll = probability.average,
                    recommendation = GenerateRecommendation(probability.percentage, target)
                };
                
                configAnalysis.targetAnalysis.Add(targetAnalysis);
            }
            
            // Overall balance score
            configAnalysis.balanceScore = CalculateOverallBalance(configAnalysis.targetAnalysis);
            report.configurations.Add(configAnalysis);
        }
        
        // Cross-configuration comparison
        report.relativeBalance = AnalyzeRelativeBalance(report.configurations);
        report.recommendations = GenerateGlobalRecommendations(report);
        
        return report;
    }
    
    private string GenerateRecommendation(float successRate, int target)
    {
        var idealRange = GetIdealSuccessRange(target);
        
        if (successRate < idealRange.min)
        {
            return $"Too difficult - consider reducing target or adding bonuses";
        }
        else if (successRate > idealRange.max)
        {
            return $"Too easy - consider increasing target or reducing bonuses";
        }
        else
        {
            return $"Well balanced - {successRate:F1}% success rate is appropriate";
        }
    }
    
    private (float min, float max) GetIdealSuccessRange(int targetNumber)
    {
        // Different target numbers have different ideal success rates
        return targetNumber switch
        {
            <= 10 => (70f, 90f),  // Easy targets
            <= 15 => (55f, 75f),  // Moderate targets
            <= 20 => (35f, 55f),  // Hard targets
            _ => (15f, 35f)       // Very hard targets
        };
    }
}

Game Balance Validation

Automated balance testing and validation workflows:

Automated Balance Testing

[System.Serializable]
public class BalanceTestSuite
{
    public string testName;
    public DiceConfiguration[] testConfigurations;
    public int[] testTargets;
    public BalanceTestCriteria criteria;
}

public class AutomatedBalanceTester : MonoBehaviour
{
    [SerializeField] private BalanceTestSuite[] testSuites;
    
    [ContextMenu("Run All Balance Tests")]
    public void RunAllBalanceTests()
    {
        var allResults = new List<BalanceTestResult>();
        
        foreach (var testSuite in testSuites)
        {
            Debug.Log($"=== Running Balance Test: {testSuite.testName} ===");
            var result = RunBalanceTestSuite(testSuite);
            allResults.Add(result);
            LogTestResults(result);
        }
        
        // Generate comprehensive report
        GenerateBalanceReport(allResults);
    }
    
    private BalanceTestResult RunBalanceTestSuite(BalanceTestSuite testSuite)
    {
        var result = new BalanceTestResult();
        result.testSuiteName = testSuite.testName;
        result.configResults = new List<ConfigBalanceResult>();
        
        foreach (var config in testSuite.testConfigurations)
        {
            var configResult = new ConfigBalanceResult();
            configResult.configName = config.displayName;
            configResult.targetResults = new List<TargetBalanceResult>();
            
            foreach (var target in testSuite.testTargets)
            {
                // Run probability analysis
                var probability = DiceAPI.CalculateProbability(
                    config, target, ComparisonType.GreaterEqual, 
                    testSuite.criteria.iterations);
                
                var targetResult = new TargetBalanceResult
                {
                    targetNumber = target,
                    successRate = probability.percentage,
                    meetsExpectations = IsWithinExpectedRange(
                        probability.percentage, 
                        testSuite.criteria.GetExpectedRange(target)),
                    deviation = CalculateDeviation(
                        probability.percentage, 
                        testSuite.criteria.GetExpectedRange(target))
                };
                
                configResult.targetResults.Add(targetResult);
            }
            
            configResult.overallBalance = CalculateOverallBalanceScore(configResult.targetResults);
            result.configResults.Add(configResult);
        }
        
        result.passed = result.configResults.All(cr => cr.overallBalance >= testSuite.criteria.minimumScore);
        return result;
    }
    
    private void GenerateBalanceReport(List<BalanceTestResult> results)
    {
        var report = new StringBuilder();
        report.AppendLine("=== AUTOMATED BALANCE TEST REPORT ===");
        report.AppendLine($"Generated: {System.DateTime.Now}");
        report.AppendLine();
        
        int passedTests = results.Count(r => r.passed);
        int totalTests = results.Count;
        
        report.AppendLine($"Overall Results: {passedTests}/{totalTests} test suites passed");
        report.AppendLine();
        
        foreach (var result in results)
        {
            report.AppendLine($"Test Suite: {result.testSuiteName} - {(result.passed ? "PASSED" : "FAILED")}");
            
            foreach (var configResult in result.configResults)
            {
                report.AppendLine($"  {configResult.configName}: {configResult.overallBalance:F2} balance score");
                
                foreach (var targetResult in configResult.targetResults)
                {
                    string status = targetResult.meetsExpectations ? "OK" : "FAIL";
                    report.AppendLine($"    Target {targetResult.targetNumber}: {targetResult.successRate:F1}% ({status})");
                }
            }
            report.AppendLine();
        }
        
        // Write report to file
        string reportPath = Path.Combine(Application.dataPath, "BalanceReports", 
            $"balance_report_{System.DateTime.Now:yyyyMMdd_HHmmss}.txt");
        Directory.CreateDirectory(Path.GetDirectoryName(reportPath));
        File.WriteAllText(reportPath, report.ToString());
        
        Debug.Log($"Balance report saved to: {reportPath}");
    }
}

Advanced Session Management

Complex Multi-Dice Sessions

Sophisticated session management with dependency handling:

Complex Combat Session

public class AdvancedCombatManager : MonoBehaviour
{
    public CombatResult ExecuteFullCombatRound(Character attacker, Character defender)
    {
        var combatResult = new CombatResult();
        
        // Phase 1: Initiative and Setup
        var initiativeSession = CreateInitiativeSession(attacker, defender);
        var initiativeResult = DiceAPI.RollSession(initiativeSession);
        
        var attackerInit = initiativeResult.GetResult("Attacker Initiative");
        var defenderInit = initiativeResult.GetResult("Defender Initiative");
        
        // Determine turn order
        bool attackerFirst = attackerInit.totalResult >= defenderInit.totalResult;
        
        // Phase 2: Attack Resolution
        if (attackerFirst)
        {
            combatResult.attackerTurn = ExecuteAttackTurn(attacker, defender);
            if (!combatResult.attackerTurn.targetDefeated)
            {
                combatResult.defenderTurn = ExecuteAttackTurn(defender, attacker);
            }
        }
        else
        {
            combatResult.defenderTurn = ExecuteAttackTurn(defender, attacker);
            if (!combatResult.defenderTurn.targetDefeated)
            {
                combatResult.attackerTurn = ExecuteAttackTurn(attacker, defender);
            }
        }
        
        return combatResult;
    }
    
    private AttackTurnResult ExecuteAttackTurn(Character attacker, Character defender)
    {
        var turnResult = new AttackTurnResult();
        
        // Create comprehensive attack session
        var attackSession = DiceAPI.CreateSession($"{attacker.name} Attack Turn");
        attackSession.UseSessionModifiers = true;
        
        // Add all relevant dice to session
        attackSession.AddDice(attacker.weaponConfig, "Attack Roll");
        attackSession.AddDice(attacker.damageConfig, "Base Damage");
        
        // Add conditional dice based on character abilities
        if (attacker.HasAbility("Sneak Attack"))
        {
            attackSession.AddDice(attacker.sneakAttackConfig, "Sneak Attack");
        }
        
        if (attacker.HasAbility("Divine Strike"))
        {
            attackSession.AddDice(attacker.divineStrikeConfig, "Divine Strike");
        }
        
        // Execute session with conditional rules
        var sessionRules = GetApplicableCombatRules(attacker, defender);
        var sessionResult = DiceAPI.RollSessionWithRules(attackSession, sessionRules);
        
        // Process results
        var attackRoll = sessionResult.GetResult("Attack Roll");
        turnResult.hit = attackRoll.totalResult >= defender.armorClass;
        
        if (turnResult.hit)
        {
            turnResult.totalDamage = CalculateTotalDamage(sessionResult);
            turnResult.critical = attackRoll.naturalResult == 20;
            
            // Apply damage with resistance
            turnResult.finalDamage = ApplyDamageResistance(
                turnResult.totalDamage, defender.resistances);
            
            // Check for defeat
            defender.currentHitPoints -= turnResult.finalDamage;
            turnResult.targetDefeated = defender.currentHitPoints <= 0;
        }
        
        return turnResult;
    }
    
    private DiceSession CreateInitiativeSession(Character char1, Character char2)
    {
        var session = DiceAPI.CreateSession("Initiative Roll");
        
        var initiativeConfig = ScriptableObject.CreateInstance<DiceConfiguration>();
        initiativeConfig.sides = 20;
        initiativeConfig.rollType = RollType.Normal;
        
        var char1Config = Object.Instantiate(initiativeConfig);
        char1Config.modifier = char1.initiativeBonus;
        
        var char2Config = Object.Instantiate(initiativeConfig);
        char2Config.modifier = char2.initiativeBonus;
        
        session.AddDice(char1Config, "Attacker Initiative");
        session.AddDice(char2Config, "Defender Initiative");
        
        return session;
    }
}

Modifier Session Management

Advanced modifier accumulation and tracking:

Modifier Session Usage

public class ModifierManager : MonoBehaviour
{
    public void DemonstrateModifierSession()
    {
        // Clear any existing modifiers
        ModifierSession.ClearModifiers();
        
        // Add various modifiers from different sources
        ModifierSession.AddModifier(2, "Bless Spell");
        ModifierSession.AddModifier(1, "Magic Weapon");
        ModifierSession.AddModifier(-1, "Cursed");
        
        Debug.Log($"Total accumulated modifiers: {ModifierSession.GetTotalModifier()}");
        Debug.Log($"Modifier sources: {string.Join(", ", ModifierSession.GetModifierHistory())}");
        
        // Roll with accumulated modifiers (automatically applied)
        int rollWithModifiers = DiceAPI.Roll(20); // Includes +2 from accumulated modifiers
        Debug.Log($"Roll result with modifiers: {rollWithModifiers}");
        
        // Conditional rules can add more modifiers
        var ruleWithModifier = ScriptableObject.CreateInstance<ConditionalRule>();
        ruleWithModifier.trigger.type = TriggerType.OnMax;
        ruleWithModifier.action.type = ActionType.AddModifier;
        ruleWithModifier.action.modifierValue = 3;
        ruleWithModifier.action.modifierSource = "Critical Momentum";
        
        var config = ScriptableObject.CreateInstance<DiceConfiguration>();
        config.sides = 20;
        
        var (result, nextModifier) = DiceAPI.RollWithRules(config, new[] { ruleWithModifier });
        
        if (nextModifier > 0)
        {
            Debug.Log($"Rule added {nextModifier} to modifier session");
        }
        
        // Advanced modifier management
        ManageModifierExpiration();
    }
    
    private void ManageModifierExpiration()
    {
        // Custom modifier expiration logic
        var expiredSources = new[] { "Temporary Buff", "Combat Bonus" };
        
        foreach (var source in expiredSources)
        {
            if (ModifierSession.HasModifierFromSource(source))
            {
                ModifierSession.RemoveModifierFromSource(source);
                Debug.Log($"Expired modifier from {source}");
            }
        }
    }
    
    // Method to save/restore modifier state
    public ModifierSessionState SaveModifierState()
    {
        return new ModifierSessionState
        {
            totalModifier = ModifierSession.GetTotalModifier(),
            sources = ModifierSession.GetModifierHistory().ToArray(),
            timestamp = System.DateTime.Now
        };
    }
    
    public void RestoreModifierState(ModifierSessionState state)
    {
        ModifierSession.ClearModifiers();
        
        // Re-apply saved modifiers (you'd need to store individual values)
        foreach (var source in state.sources)
        {
            // This would require extending ModifierSession to store individual values
            // ModifierSession.AddModifier(value, source);
        }
    }
}

Template-Based Sessions

Using the template generation system for quick session creation:

Template-Based Session Creation

public class SessionTemplateManager : MonoBehaviour
{
    [SerializeField] private DiceTemplateData diceTemplates;
    
    public DiceSession CreateSessionFromTemplate(string templateName)
    {
        switch (templateName.ToLower())
        {
            case "dnd_combat":
                return CreateDnDCombatSession();
            case "skill_challenge":
                return CreateSkillChallengeSession();
            case "saving_throws":
                return CreateSavingThrowSession();
            case "damage_breakdown":
                return CreateDamageBreakdownSession();
            default:
                Debug.LogWarning($"Unknown template: {templateName}");
                return CreateBasicSession();
        }
    }
    
    private DiceSession CreateDnDCombatSession()
    {
        var session = DiceAPI.CreateSession("D&D Combat Round");
        session.Description = "Complete D&D 5e combat resolution";
        
        // Attack roll
        var attackConfig = ScriptableObject.CreateInstance<DiceConfiguration>();
        attackConfig.displayName = "Attack Roll";
        attackConfig.sides = 20;
        attackConfig.rollType = RollType.Normal; // Can be changed to Advantage/Disadvantage
        attackConfig.modifier = 0; // Set based on character
        attackConfig.targetConfig.enabled = true;
        attackConfig.targetConfig.value = 15; // Target AC
        attackConfig.targetConfig.comparison = ComparisonType.GreaterEqual;
        
        session.AddDice(attackConfig, "Attack");
        
        // Base weapon damage
        var weaponDamage = ScriptableObject.CreateInstance<DiceConfiguration>();
        weaponDamage.displayName = "Weapon Damage";
        weaponDamage.sides = 8; // Longsword
        weaponDamage.modifier = 0; // Strength/Dex modifier
        
        session.AddDice(weaponDamage, "Base Damage");
        
        return session;
    }
    
    private DiceSession CreateSkillChallengeSession()
    {
        var session = DiceAPI.CreateSession("Skill Challenge");
        session.Description = "Multi-skill challenge resolution";
        
        string[] skillNames = { "Investigation", "Perception", "Athletics", "Persuasion" };
        int[] skillBonuses = { 5, 3, 2, 4 }; // Example bonuses
        
        for (int i = 0; i < skillNames.Length; i++)
        {
            var skillConfig = ScriptableObject.CreateInstance<DiceConfiguration>();
            skillConfig.displayName = $"{skillNames[i]} Check";
            skillConfig.sides = 20;
            skillConfig.modifier = skillBonuses[i];
            skillConfig.targetConfig.enabled = true;
            skillConfig.targetConfig.value = 15; // Standard DC
            skillConfig.targetConfig.comparison = ComparisonType.GreaterEqual;
            
            session.AddDice(skillConfig, skillNames[i]);
        }
        
        return session;
    }
    
    private DiceSession CreateSavingThrowSession()
    {
        var session = DiceAPI.CreateSession("Saving Throws");
        session.Description = "All saving throw types";
        
        string[] saveTypes = { "Fortitude", "Reflex", "Will" };
        int[] saveBonuses = { 4, 2, 6 }; // Example bonuses
        
        for (int i = 0; i < saveTypes.Length; i++)
        {
            var saveConfig = ScriptableObject.CreateInstance<DiceConfiguration>();
            saveConfig.displayName = $"{saveTypes[i]} Save";
            saveConfig.sides = 20;
            saveConfig.modifier = saveBonuses[i];
            saveConfig.targetConfig.enabled = true;
            saveConfig.targetConfig.value = 16; // Save DC
            saveConfig.targetConfig.comparison = ComparisonType.GreaterEqual;
            
            session.AddDice(saveConfig, $"{saveTypes[i]} Save");
            
            // Set as disabled initially - enable as needed
            session.SetDiceEnabled(saveTypes[i] + " Save", false);
        }
        
        return session;
    }
}

Configuration Management

JSON Import/Export System

The ImportExportSystem provides comprehensive configuration serialization:

Configuration Import/Export

public class ConfigurationManager : MonoBehaviour
{
    public void ExportConfiguration(DiceConfiguration config, string filePath)
    {
        try
        {
            string json = ImportExportSystem.ExportConfiguration(config);
            File.WriteAllText(filePath, json);
            Debug.Log($"Configuration exported to: {filePath}");
        }
        catch (System.Exception e)
        {
            Debug.LogError($"Export failed: {e.Message}");
        }
    }
    
    public DiceConfiguration ImportConfiguration(string filePath)
    {
        try
        {
            string json = File.ReadAllText(filePath);
            var config = ImportExportSystem.ImportConfiguration(json);
            Debug.Log($"Configuration imported from: {filePath}");
            return config;
        }
        catch (System.Exception e)
        {
            Debug.LogError($"Import failed: {e.Message}");
            return null;
        }
    }
    
    // Batch operations
    public void ExportMultipleConfigurations(DiceConfiguration[] configs, string directoryPath)
    {
        Directory.CreateDirectory(directoryPath);
        
        foreach (var config in configs)
        {
            string fileName = $"{config.displayName.Replace(" ", "_")}.json";
            string fullPath = Path.Combine(directoryPath, fileName);
            ExportConfiguration(config, fullPath);
        }
        
        Debug.Log($"Exported {configs.Length} configurations to {directoryPath}");
    }
    
    public DiceConfiguration[] ImportMultipleConfigurations(string directoryPath)
    {
        var configs = new List<DiceConfiguration>();
        var jsonFiles = Directory.GetFiles(directoryPath, "*.json");
        
        foreach (var filePath in jsonFiles)
        {
            var config = ImportConfiguration(filePath);
            if (config != null)
            {
                configs.Add(config);
            }
        }
        
        Debug.Log($"Imported {configs.Count} configurations from {directoryPath}");
        return configs.ToArray();
    }
    
    // Cross-project configuration sharing
    public void ShareConfigurationSet(string setName, DiceConfiguration[] configs)
    {
        var sharedPath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
            "DiceRollToolkit", "SharedConfigs", setName);
            
        ExportMultipleConfigurations(configs, sharedPath);
        
        // Create metadata file
        var metadata = new ConfigurationSetMetadata
        {
            setName = setName,
            createdDate = System.DateTime.Now,
            configCount = configs.Length,
            configNames = configs.Select(c => c.displayName).ToArray(),
            createdBy = System.Environment.UserName
        };
        
        string metadataPath = Path.Combine(sharedPath, "_metadata.json");
        string metadataJson = JsonUtility.ToJson(metadata, true);
        File.WriteAllText(metadataPath, metadataJson);
        
        Debug.Log($"Configuration set '{setName}' shared successfully");
    }
}

Template Generation System

Advanced template generation for AI integration and documentation:

Template Generation Usage

public class TemplateManager : MonoBehaviour
{
    [ContextMenu("Generate Master Template")]
    public void GenerateMasterTemplate()
    {
        var masterTemplate = TemplateGenerationSystem.GenerateMasterTemplate();
        
        string templatePath = Path.Combine(Application.dataPath, "Templates", "MasterTemplate.json");
        Directory.CreateDirectory(Path.GetDirectoryName(templatePath));
        
        string json = JsonUtility.ToJson(masterTemplate, true);
        File.WriteAllText(templatePath, json);
        
        Debug.Log($"Master template generated: {templatePath}");
        Debug.Log($"Template contains {masterTemplate.diceTemplates.Length} dice configurations");
        Debug.Log($"Template contains {masterTemplate.ruleTemplates.Length} rule combinations");
    }
    
    [ContextMenu("Generate Dice Template Set")]
    public void GenerateDiceTemplateSet()
    {
        var diceTemplate = TemplateGenerationSystem.GenerateDiceTemplate();
        
        string templatePath = Path.Combine(Application.dataPath, "Templates", "DiceTemplate.json");
        Directory.CreateDirectory(Path.GetDirectoryName(templatePath));
        
        string json = JsonUtility.ToJson(diceTemplate, true);
        File.WriteAllText(templatePath, json);
        
        Debug.Log($"Dice template generated: {templatePath}");
        Debug.Log($"Contains templates for all {System.Enum.GetNames(typeof(RollType)).Length} roll types");
    }
    
    [ContextMenu("Generate Rule Template Set")]
    public void GenerateRuleTemplateSet()
    {
        var ruleTemplate = TemplateGenerationSystem.GenerateRuleTemplate();
        
        string templatePath = Path.Combine(Application.dataPath, "Templates", "RuleTemplate.json");
        Directory.CreateDirectory(Path.GetDirectoryName(templatePath));
        
        string json = JsonUtility.ToJson(ruleTemplate, true);
        File.WriteAllText(templatePath, json);
        
        Debug.Log($"Rule template generated: {templatePath}");
        Debug.Log($"Contains all 77 rule combinations");
    }
    
    // Custom template creation
    public void CreateCustomGameTemplate(string gameName, GameTemplateSpec spec)
    {
        var customTemplate = new CustomGameTemplate
        {
            gameName = gameName,
            gameType = spec.gameType,
            diceConfigs = CreateConfigsForGame(spec),
            commonRules = CreateRulesForGame(spec),
            sessionTemplates = CreateSessionsForGame(spec)
        };
        
        string templatePath = Path.Combine(Application.dataPath, "Templates", "CustomGames", $"{gameName}.json");
        Directory.CreateDirectory(Path.GetDirectoryName(templatePath));
        
        string json = JsonUtility.ToJson(customTemplate, true);
        File.WriteAllText(templatePath, json);
        
        Debug.Log($"Custom template for {gameName} created: {templatePath}");
    }
    
    private DiceConfiguration[] CreateConfigsForGame(GameTemplateSpec spec)
    {
        var configs = new List<DiceConfiguration>();
        
        // Generate configurations based on game specifications
        foreach (var dieSpec in spec.requiredDice)
        {
            var config = ScriptableObject.CreateInstance<DiceConfiguration>();
            config.displayName = dieSpec.name;
            config.sides = dieSpec.sides;
            config.rollType = dieSpec.rollType;
            config.modifier = dieSpec.baseModifier;
            
            configs.Add(config);
        }
        
        return configs.ToArray();
    }
}

Cross-Project Configuration Sharing

Sharing configurations between projects and teams:

Configuration Sharing System

public class ConfigurationSharingManager : MonoBehaviour
{
    private const string SHARED_CONFIGS_FOLDER = "DiceRollToolkit_SharedConfigs";
    
    public void PublishConfigurationPack(string packName, ConfigurationPack pack)
    {
        string sharedPath = GetSharedConfigsPath();
        string packPath = Path.Combine(sharedPath, packName);
        
        Directory.CreateDirectory(packPath);
        
        // Export all configurations
        foreach (var config in pack.diceConfigurations)
        {
            string configPath = Path.Combine(packPath, $"{config.displayName}.json");
            string json = ImportExportSystem.ExportConfiguration(config);
            File.WriteAllText(configPath, json);
        }
        
        // Export rules
        foreach (var rule in pack.conditionalRules)
        {
            string rulePath = Path.Combine(packPath, "Rules", $"{rule.ruleName}.json");
            Directory.CreateDirectory(Path.GetDirectoryName(rulePath));
            string json = ImportExportSystem.ExportRule(rule);
            File.WriteAllText(rulePath, json);
        }
        
        // Export sessions
        foreach (var session in pack.diceSessions)
        {
            string sessionPath = Path.Combine(packPath, "Sessions", $"{session.sessionName}.json");
            Directory.CreateDirectory(Path.GetDirectoryName(sessionPath));
            string json = ImportExportSystem.ExportSession(session);
            File.WriteAllText(sessionPath, json);
        }
        
        // Create pack manifest
        var manifest = new ConfigurationPackManifest
        {
            packName = packName,
            version = pack.version,
            author = pack.author,
            description = pack.description,
            createdDate = System.DateTime.Now,
            diceConfigCount = pack.diceConfigurations.Length,
            ruleCount = pack.conditionalRules.Length,
            sessionCount = pack.diceSessions.Length,
            tags = pack.tags
        };
        
        string manifestPath = Path.Combine(packPath, "manifest.json");
        string manifestJson = JsonUtility.ToJson(manifest, true);
        File.WriteAllText(manifestPath, manifestJson);
        
        Debug.Log($"Configuration pack '{packName}' published successfully");
    }
    
    public string[] GetAvailableConfigurationPacks()
    {
        string sharedPath = GetSharedConfigsPath();
        
        if (!Directory.Exists(sharedPath))
        {
            return new string[0];
        }
        
        var packDirs = Directory.GetDirectories(sharedPath);
        var packNames = new List<string>();
        
        foreach (var dir in packDirs)
        {
            string manifestPath = Path.Combine(dir, "manifest.json");
            if (File.Exists(manifestPath))
            {
                packNames.Add(Path.GetFileName(dir));
            }
        }
        
        return packNames.ToArray();
    }
    
    public ConfigurationPack ImportConfigurationPack(string packName)
    {
        string packPath = Path.Combine(GetSharedConfigsPath(), packName);
        
        if (!Directory.Exists(packPath))
        {
            Debug.LogError($"Configuration pack '{packName}' not found");
            return null;
        }
        
        // Load manifest
        string manifestPath = Path.Combine(packPath, "manifest.json");
        if (!File.Exists(manifestPath))
        {
            Debug.LogError($"Invalid configuration pack: missing manifest");
            return null;
        }
        
        string manifestJson = File.ReadAllText(manifestPath);
        var manifest = JsonUtility.FromJson<ConfigurationPackManifest>(manifestJson);
        
        var pack = new ConfigurationPack
        {
            packName = manifest.packName,
            version = manifest.version,
            author = manifest.author,
            description = manifest.description
        };
        
        // Import dice configurations
        var diceConfigs = new List<DiceConfiguration>();
        var diceFiles = Directory.GetFiles(packPath, "*.json")
            .Where(f => !Path.GetFileName(f).Equals("manifest.json"));
        
        foreach (var diceFile in diceFiles)
        {
            string json = File.ReadAllText(diceFile);
            var config = ImportExportSystem.ImportConfiguration(json);
            if (config != null)
            {
                diceConfigs.Add(config);
            }
        }
        pack.diceConfigurations = diceConfigs.ToArray();
        
        // Import rules
        string rulesPath = Path.Combine(packPath, "Rules");
        if (Directory.Exists(rulesPath))
        {
            var rules = new List<ConditionalRule>();
            var ruleFiles = Directory.GetFiles(rulesPath, "*.json");
            
            foreach (var ruleFile in ruleFiles)
            {
                string json = File.ReadAllText(ruleFile);
                var rule = ImportExportSystem.ImportRule(json);
                if (rule != null)
                {
                    rules.Add(rule);
                }
            }
            pack.conditionalRules = rules.ToArray();
        }
        
        // Import sessions
        string sessionsPath = Path.Combine(packPath, "Sessions");
        if (Directory.Exists(sessionsPath))
        {
            var sessions = new List<DiceSession>();
            var sessionFiles = Directory.GetFiles(sessionsPath, "*.json");
            
            foreach (var sessionFile in sessionFiles)
            {
                string json = File.ReadAllText(sessionFile);
                var session = ImportExportSystem.ImportSession(json);
                if (session != null)
                {
                    sessions.Add(session);
                }
            }
            pack.diceSessions = sessions.ToArray();
        }
        
        Debug.Log($"Imported configuration pack '{packName}' successfully");
        return pack;
    }
    
    private string GetSharedConfigsPath()
    {
        return Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
            SHARED_CONFIGS_FOLDER);
    }
}
Professional Framework: These advanced features provide enterprise-level capabilities for sophisticated dice mechanics, deterministic systems, comprehensive statistical analysis, and professional configuration management. All features are based on the actual 29-script framework implementation.

Quick Nav