My traits are acting weird upon levelup

so when i start the game it gives me the starting number of traits i have assigned on the progression asset but if i use them and level up it dosnt give me the ammount i have on the second element of the array for example i start with 4 trait point and the next element i was them to have 8 i have to start with four then set the second element to 8 for it to give me 8 point if i set them all to a single number like 1 then itll go negative and just act weird

heres my trait store

namespace RPG.Stats
{
    public class TraitStore : MonoBehaviour, IModifierProvider, ISaveable, IPredicateEvaluator
    {
        [SerializeField] Traitbonus[] bonusConfig;
        [System.Serializable]
        class Traitbonus
        {
            public Trait trait;
            public Stat stat;
            public float additiveBonusPerPoint = 0;
            public float percentageBonusPerPoint = 0;
        }

        Dictionary<Trait, int> assingedPoints = new Dictionary<Trait, int>();
        Dictionary<Trait, int> stagedPoints = new Dictionary<Trait, int>();

        Dictionary<Stat, Dictionary<Trait, float>> additiveBonusCache;
        Dictionary<Stat, Dictionary<Trait, float>> percentageBonusCache;

        private void Awake()
        {
            additiveBonusCache = new Dictionary<Stat, Dictionary<Trait, float>>();
            percentageBonusCache = new Dictionary<Stat, Dictionary<Trait, float>>();
            foreach (var bonus in bonusConfig)
            {
                if (!additiveBonusCache.ContainsKey(bonus.stat))
                {
                    additiveBonusCache[bonus.stat] = new Dictionary<Trait, float>();
                }
                if (!percentageBonusCache.ContainsKey(bonus.stat))
                {
                    percentageBonusCache[bonus.stat] = new Dictionary<Trait, float>();
                }
                additiveBonusCache[bonus.stat][bonus.trait] = bonus.additiveBonusPerPoint;
                percentageBonusCache[bonus.stat][bonus.trait] = bonus.percentageBonusPerPoint;
            }
        }

        // int unAssignedPoints = 10;

        public int GetProposedPoints(Trait trait)
        {
            return GetPoints(trait) + GetStagedPoints(trait);
        }

        public int GetPoints(Trait trait)
        {
            return assingedPoints.ContainsKey(trait) ? assingedPoints[trait] : 0;
        }

        public int GetStagedPoints(Trait trait)
        {
            return stagedPoints.ContainsKey(trait) ? stagedPoints[trait] : 0;
        }

        public void AssignPoints(Trait trait, int points)
        {
            if (!CanAssignPoints(trait, points)) return;

            stagedPoints[trait] = GetStagedPoints(trait) + points;
            //unAssignedPoints -= points;
        }

        public bool CanAssignPoints(Trait trait, int points)
        {
            if (GetStagedPoints(trait) + points < 0) return false;
            if (GetUnAssignedPoints() < points) return false;
            return true;
        }

        public int GetUnAssignedPoints()
        {
            return GetAssignablePoints() - GetTotalProposedPoints();
        }

        public int GetTotalProposedPoints()
        {
            int total = 0;
            foreach (int points in assingedPoints.Values)
            {
                total += points;
            }
            foreach (int points in stagedPoints.Values)
            {
                total += points;
            }
            return total;
        }

        public void Commit()
        {
            foreach (Trait trait in stagedPoints.Keys)
            {
                assingedPoints[trait] = GetProposedPoints(trait);
            }
            stagedPoints.Clear();
        }

        public int GetAssignablePoints()
        {
            return (int)GetComponent<BaseStats>().GetStat(Stat.TotalTraitPoints);
        }

        public IEnumerable<float> GetAddititveModifers(Stat stat)
        {
            if (!additiveBonusCache.ContainsKey(stat)) yield break;

            foreach (Trait trait in additiveBonusCache[stat].Keys)
            {
                float bonus = additiveBonusCache[stat][trait];
                yield return bonus * GetPoints(trait);
            }
        }

        public IEnumerable<float> GetPercentageModifiers(Stat stat)
        {
            if (!percentageBonusCache.ContainsKey(stat)) yield break;

            foreach (Trait trait in percentageBonusCache[stat].Keys)
            {
                float bonus = percentageBonusCache[stat][trait];
                yield return bonus * GetPoints(trait);
            }
        }

        public object CaptureState()
        {
            return assingedPoints;
        }

        public void RestoreState(object state)
        {
            assingedPoints = new Dictionary<Trait, int>((IDictionary<Trait, int>)state);
        }

        public bool? Evaluate(string predicate, string[] parameters)
        {
            if (predicate == "MinimumTrait")
            {
                if (Enum.TryParse<Trait>(parameters[0], out Trait trait))
                {
                    return GetPoints(trait) >= Int32.Parse(parameters[1]);
                }
                //int.Parse()
            }
            return null;
        }
    }
}

heres my progression

namespace RPG.Stats
{
    [CreateAssetMenu(fileName = "Progression", menuName = "Stats/New Progression", order = 0)]
    public class Progression : ScriptableObject
    {
        [SerializeField] ProgressionCharacterClass[] characterClasses = null;

        Dictionary<CharacterClass, Dictionary<Stat, float[]>> lookupTable = null;

        public float GetStat(Stat stat, CharacterClass characterClass, int level, float Fallback = 0)
        {
            BuildLookup();

            if (!lookupTable[characterClass].ContainsKey(stat))
            {
                //return 0;
                return Fallback;
            }

            float[] levels = lookupTable[characterClass][stat];
            if (levels.Length == 0)
            {
                //return 0; 
                return Fallback;
            }

            if (levels.Length < level)
            {
                return levels[levels.Length -1];
            }

            return levels[level - 1];

        }

        public int GetLevels(Stat stat, CharacterClass characterClass)
        {
            BuildLookup();

            float[] levels = lookupTable[characterClass][stat];
            return levels.Length;
        }

        private void BuildLookup()
        {
            if (lookupTable != null) return;

            lookupTable = new Dictionary<CharacterClass, Dictionary<Stat, float[]>>();

            foreach (ProgressionCharacterClass progressionClass in characterClasses)
            {
                var statLookupTable = new Dictionary<Stat, float[]>();

                foreach (ProgressionStat progressionStat in progressionClass.stats)
                {
                    statLookupTable[progressionStat.stat] = progressionStat.levels;
                }

                lookupTable[progressionClass.characterClass] = statLookupTable;
            }
        }

        [System.Serializable]
        class ProgressionCharacterClass
        {
            public CharacterClass characterClass;
            public ProgressionStat[] stats;
        }

        [System.Serializable]
        class ProgressionStat
        {
            public Stat stat;
            public float[] levels;
        }
    }
}

i cant seem to find an issue with it but it could be obvious and i just dont see it

I think what you’re describing is actually the correct behavior of Progression and GetStat…
Each level contains the total number of attributes at that level (the amount you had at the level before + whatever is added…).
So if you wanted to have 4 traits per level, then your progression would be
4,
8,
12,
16,
20,
24,
etc

so if i wanted to have them different for exmaple have 4 for 4 levels then increase to 8 on the 5th then drop to 4 again i cant because it messes up after you dont stay in order making stuff negative or reverting back to 0 points regardless of what you spent or didnt spend already

Do you mean adding 4 each level, or staying at 4 total trait points until level 5, then going to 8, then clawing it back to only 4 total trait points later? [hint: If you do that, you will lose your players]

like starting with a decent ammount untill later levels i want it dropped so it dosnt get too broken instead of a steady number or climbing a steady ammount alternating the points given after level up like getting 4 every level then after that boosting it on the 5th or 10th as a “milestone” then dropping back down for a little while untill the next instead of it being a constant increase or stagnant

i feel like the higher you get in level the less trait points you should have so maybe some levels you dont get any once you reach way up in level

Something like
4,
8, (4+4)
12, (8+4)
16, (12+4)
24, (16+8, Bonus!)
28, (24+4)
30, (28+2, tapering off)
32,
34
40 (bonus!)
42
44
46
48
50
60 (bonus!)
61
62
63
64
65
66
67
68
69
70
75 (Bonus)
75 (nothing gained at all for a while)
75
75
75
75
75
75
75
80 (Bonus!)
80
80
80
80
80

so i cant do down in points but i can give nothing for a few levels to make up for what i couldnt remove i guess i misunderstood how the traits were working i was doing something like

4,
4,
4,
8,
4,
4,
4

i may try to find a way to make leveling cost something like a potion costs money similar to dark souls trait allocating like when you kill stuff you get a certain amount of something and spend that to increase your traits

yes, this would start with 4 traits, stay at four traits till you have 8, then on the next level, claw back those traits and take them away from the player, and I’m pretty sure that’s not what you intended. :slight_smile:

I enjoy that mechanic

Privacy & Terms