Leveling & experience system: How to separate exp gains

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By hontohowsu

I have a autoload node with GDQuest’s leveling code:

@export var level = 1
var experience = 0
var experience_total = 0
var experience_required = get_required_experience(level + 1)

func get_required_experience(level):
	return round(pow(level, 1.8) + level * 4)

func gain_experience(amount):
	experience_total += amount
	experience += amount
	while experience >= experience_required:
		experience -= experience_required
		level_up()

func level_up():
	level += 1
	experience_required = get_required_experience(level + 1) 

and now I am wondering how to grant exp only to certain skills based on the activity. So if I catch a fish I only want to give exp to the fishing skill. How do I do this?
I saw a similar post that said to use dictionaries but implementing it did not make much sense to me.

:bust_in_silhouette: Reply From: godot_dev_

I think a dictionary-based approach would be sufficient for a simple experience-level game. I suggest you first separate logic into two pieces: a) ExperienceProducers: things that give experience and may require a certain level, and b) ExperienceTracker: the system that tracks what level the player is at.

  • ExperienceProducers: the very first logic is to check whether you have the level requirement, and if the appropriate level for the appropriate skill is met, then the producer (say a function, like go_fish will award experience (either by having direct access to the ExperienceTracker or by signaling exp was gained and the ExperienceTracker will handle it) when the action is performed
  • ExperienceTracker: tracks the experience advancement, and tracks level ups. You could simply implement this via two dictionaries, an exp dictionary and a level dictionary. To determine if a level up occurred, you can have a dictionary (key: level (int), value: experience required (int)) that lists the experience requirement to achieve a level up for every level (let’s assume each skill have the same amount of exp required to level up. Otherwise, if you want variable amounts of exp to level up for each skill, you could have a dictionary to store the dictionaries that explains the exp level requirement (key: skillname (string), (key: level (int), value: experience required (int))))

For example, here is sample code providing my suggested idea:

# ExperienceTracker.gd
    const LIST_OF_SKILL_NAMES=["fishing","mining","woodcutting"...]
    var expMap = {} #key skill name, value amount of exp player has in that skill
    var levelMap = {} # key skill name, value: current level in that skill
   var levelUpRequirement = {} #key: level, value: amount of exp required to reach that level
    func _ready():
        #populate every skill with minimum level (e.g., 1) and minimum experience (e.g., 0)
        for skillName in LIST_OF_SKILL_NAMES:
            expMap[skillName]=0
            levelMap[skillName]=1
    func gainExperience(skillName,exp):
        #skillName: the skill to increase experience in in
        #exp: the amount of experience to increase by
        var currExp = expMap[skillName]
        expMap[skillName] = currExp + exp
        
        #level up?
        var currLevel =levelMap[skillName]
        if expMap[skillName] >= levelUpRequirement [currLevel]:
            level_up(skillName)

    func level_up(skillName,currLevel):
        var currLevel =levelMap[skillName]
        levelMap[skillName]=currLevel  +1

    func hasLevelRequirement(skillName,levelReq):
        return levelMap[skillName]>=levelReq

# ExperienceProducer.gd
     var expTracker = null #assume we have reference to ExperienceTracker
     func go_fish_tuna():
         if expTracker.hasLevelRequirement("fishign",30) #lvl 30 required
             expTracker.gainExperience("fishing",165) #gain 165 exp

     func go_fish_lobster():
         if expTracker.hasLevelRequirement("fishign",45) #lvl 45 required
             expTracker.gainExperience("fishing",235) #gain 235 exp

thank you a lot

hontohowsu | 2023-05-09 01:18