XP not being given to player? (1.4)

Discussion in 'Programming' started by IncuTyph, Oct 18, 2019.

Tags:
  1. IncuTyph

    IncuTyph Member

    Joined:
    Oct 18, 2019
    Posts:
    10
    Hi, I'm fairly new to GML. I've been slowly working on my first game, and so far things have been pretty good. I came across an issue that is probably super simple to fix, but I'm not entirely sure what is wrong with what I have.

    So, I'm trying to implement an XP system. When a monster is killed, its base xp (bxp) value (the amount of xp scales with monster level; think Pokemon) is supposed to be added to the player's (or other party members' once I actually add them) xp totals. This part seems to work, as the debug message I put in the monster's code shows when it's killed. However, what doesn't work is when the xp the player gets doesn't advance them to the next level.

    This is the monster's code. Currently just touching the monster inflicts damage on it. This is in the monster's collision event with the player object:

    Code:
    if hp <= 0
        {
            with(obj_player)
                {
                xp += obj_goobey_grey_ow.bxp; //(player?)xp += monster's bxp
                show_debug_message("xp gained");
                }
        instance_destroy();
        }
    As I said, this displays the debug message, so I'm assuming it works. This is my player's code though (Create event):

    Code:
    lvl = 1;
    xp = 0;
    nlvl = lvl*10; //nlvl stands for next level
    
    if xp >= nlvl
        {
        lvl += 1;
        show_debug_message("Leveled up!")
        }
    In the monster's code, I did try using self.xp and obj_player.xp but it doesn't seem to work either. I'm just not sure what's wrong with what I have. Also, I do have the monster set to give 10,000 xp, so surely I meet the requirements to level up a few times with that. Any help would be appreciated though.
     
  2. BattleRifle BR55

    BattleRifle BR55 Member

    Joined:
    Jun 24, 2016
    Posts:
    1,039
    You can use the dot operator to link an instance to a variable, then you can just use what you commented out
    Code:
    if hp <= 0
       {
       obj_player.xp += bxp;
       show_debug_message("xp gained");
    
       instance_destroy();
       }
     
  3. TailBit

    TailBit Member

    Joined:
    Oct 16, 2019
    Posts:
    137
    The create event is only run once when the object is created, so it will never check if you have enough xp after a kill.

    Instead consider doing the level up check in the xp code:
    Code:
    with(obj_player)
               {
               xp += other.bxp; //(player?)xp += monster's bxp
               show_debug_message("xp gained");
               }
    in with statements, you can use other to refer back to the spesific monter that told player to increase xp
     
  4. IncuTyph

    IncuTyph Member

    Joined:
    Oct 18, 2019
    Posts:
    10
    That might be my problem. My player's stats are all in the create event. I'm not sure what else to stick that in though. A step event? A script?
     
  5. TsukaYuriko

    TsukaYuriko Q&A Spawn Camper Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    1,849
    The code you quoted should be executed whenever the player earns experience. Ideally, you'd have this in a script so you can call it whenever the player should get experience, and could execute the level-up check there as well.

    If you're unsure what sort of code goes where, I suggest refreshing your knowledge about the basic types of events.
     
  6. IncuTyph

    IncuTyph Member

    Joined:
    Oct 18, 2019
    Posts:
    10
    Sorry, I've just been a tad burnt out from doing other things. Been a long day and ended up having a brain fart. Stuck it in a step event and it works now. Kinda mad at myself for not just trying that first, but at least it's working!
     
    TsukaYuriko likes this.
  7. TsukaYuriko

    TsukaYuriko Q&A Spawn Camper Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    1,849
    No need to apologize for anything - remembering that trying stuff yourself is always an option is a step forward, if you ask me. :)
     
  8. IncuTyph

    IncuTyph Member

    Joined:
    Oct 18, 2019
    Posts:
    10
    I usually try things out, but when I get stuck, I like to have a soundboard because I'll forget basic stuff after trying to fiddle with something for so long.

    I must say though that as I was typing the last post, I actually did discover a problem! Yes it levels, but I don't think my nlvl variable is updating. I set my enemy to give out 50 xp upon dying, and had the nlvl value set to lvl*100 (so at lvl 1, this would be 100 xp). Ideally, killing two enemies would give a total of 100 xp, and then nlvl would be 200 to get to lvl 3. However, if I kill another enemy, I'll level up immediately again, and it levels infinitely. I did try moving the lvl, xp, and nlvl variables into the step event, but then levelling doesn't actually happen. Just having the nlvl in Step DOES level, but if I get another enemy, I'll get another level, while with a 3rd I'll level up twice, and a 4th enemy levels me 3 times (and so on). Tried several combinations of the variables being moved between Step and Create, and either I level infinitely, consecutively, or not at all. I'm wondering if my experience formula is just bad or something, but I can't work it out. Tried setting it to lvl*150 and it just says the same (though it takes a bit longer obviously).
     
  9. BattleRifle BR55

    BattleRifle BR55 Member

    Joined:
    Jun 24, 2016
    Posts:
    1,039
    Post the formula and such you're using. It'll also be better to move that stuff to another event, one that only fires off when it needs to (such as the Destroy event of an enemy)
     
  10. IncuTyph

    IncuTyph Member

    Joined:
    Oct 18, 2019
    Posts:
    10
    So this, again, is the enemy's collide event with the player:
    Code:
    if hp <= 0
       {
       obj_player.xp += bxp;
       obj_player.xptotal += obj_player.xp; //I have this because somehow I thought if I had an xptotal separate from xp, I could somehow use it to correct this levelling issue. I don't think it's needed after all, honestly.
       show_debug_message("xp gained");
    
       instance_destroy();
       }
    I have it in the collide event because at the moment I have no battle system in place, so simply the player touching the enemy kills it.
    This is in the player's step event:
    Code:
    nlvl = lvl*150; //this is the formula for determining the xp needed for next level (nlvl)
    hp = ((2*bhp*lvl)/100)+50; //these variables are for stat calculations. Not using them yet so i'm not worried about their placements
    mp = ((2*bmp*lvl)/100)+50;
    str = ((2*bstr)*lvl)/100 +50;
    mag = ((2*bmag)*lvl)/100 +50;
    p_def = ((2*bp_def)*lvl)/100 +50;
    m_def = ((2*bm_def)*lvl)/100 +50;
    bspd = ((2*bbspd)*lvl)/100 +50;
    
    if xptotal >= nlvl
        {
        lvl += 1;
        show_debug_message("Leveled up!") //this part seems to work as the debug message shows
        }
    This is in my Create event:
    Code:
    ///Stats
    bhp = 80; //the b stands for base stat, for influencing growth
    bmp = 200;
    bstr = 70;
    bmag= 230;
    bp_def = 115;
    bm_def = 115;
    bbspd = 70;
    corruption = 50;
    lvl = 1; //I've tried moving these around in the step event with mixed to no results. 
    xp = 0;
    xptotal = 0;
    Sorry if it's weirdly messy or spaghetti-like.
     
  11. TailBit

    TailBit Member

    Joined:
    Oct 16, 2019
    Posts:
    137
    Your problem there is that you increase xptotal exponensly with your xp
    50 in xp, 50 in total -> 100, 150 -> 150, 300 -> 200, 500
    So it is messing up your system
    Code:
    if hp <= 0
        {
            with(obj_player)
                {
                xp += other.bxp; //(player?)xp += monster's bxp
                if(xp >= nlvl){
                    lvl++;
                    nlvl = lvl * 100;
                }
    // You could also adjust all the variables here after increasing lvl
                show_debug_message("xp gained");
                }
        instance_destroy();
        }
    You do want a lot of enemies to drop xp, so I would consider making it a script like scr_give_xp, moving the whole with into the script and replacing bxp with argument0.

    Then the enemy code in the brackets would just be
    Code:
    scr_give_xp(bxp);
    instance_destroy();
     
    Last edited: Oct 18, 2019
  12. IncuTyph

    IncuTyph Member

    Joined:
    Oct 18, 2019
    Posts:
    10
    After a long day of retail work, I finally have a chance to try this out. I did drop the xptotal variable, but my problem doesn't seem to be fixed. The problem is that the player isn't actually levelling. I put my variables for level into my step event (the lvl, xp, and nlvl were in a create event) and still no. Here's my player's step event:
    Code:
    //effective stats
    lvl = 1;
    nlvl = lvl*100;
    xp = 0;
    hp = ((2*bhp*lvl)/100)+50; //stat calculating formulas. the b in front means 'base'
    mp = ((2*bmp*lvl)/100)+50;
    str = ((2*bstr)*lvl)/100 +50;
    mag = ((2*bmag)*lvl)/100 +50;
    p_def = ((2*bp_def)*lvl)/100 +50;
    m_def = ((2*bm_def)*lvl)/100 +50;
    bspd = ((2*bbspd)*lvl)/100 +50;
    
    if xp >= nlvl
        {
        lvl += 1;
        show_debug_message("Leveled up!") //the debug message is not displaying
        }
    I just don't understand what could be wrong.

    Sorry if I'm frustrating lol
     
  13. Simon Gust

    Simon Gust Member

    Joined:
    Nov 15, 2016
    Posts:
    3,244
    To be in the clear, the code you've shown is the step event? You mentioned lvl, xp and nlvl are in the create event, so what are lvl and xp doing here in the step event? If you continously set xp to 0 and lv to 1, they will be set to that every frame. Say you gain 40 xp, next frame xp is just set back to 0.
     
  14. Yal

    Yal GMC Memer GMC Elder

    Joined:
    Jun 20, 2016
    Posts:
    4,172
    Yeah, you should ideally only set level/EXP to 0 once, perhaps at the game start (not every room, and definitely not every step) and then store them globally (e.g. in a global array if you've got more than one player - each player would then have a "player_id" that tells the game which of the levels / EXPs / other stats to use).
    Code:
    if hp <= 0
       {
       global.xp[other.player_id] += bxp;
       global.xptotal[other.player_id] += global.xp[other.player_id]; 
       show_debug_message("xp gained");
    
       instance_destroy();
       }
    
     
  15. IncuTyph

    IncuTyph Member

    Joined:
    Oct 18, 2019
    Posts:
    10
    I had them in the Create event first, and when that didn't work I moved them to the Step event to see if that would change anything. It didn't lol




    I think I see what you mean. So I'd set the player (there's only one player, but there's party members [RPG], so I assume it would still be like your example) lvl, xp, maybe the nlvl into a game start event, but set them as global variables? I want to make sure I understand this before I screw it up worse.
     
  16. Yal

    Yal GMC Memer GMC Elder

    Joined:
    Jun 20, 2016
    Posts:
    4,172
    Set them at the start of the game (doesn't need to be a Game Start event, I prefer having stuff in the Create event of a special "setup" object in the first room, so that IF I decide to add a new room before that - e.g. for most of the game the first room is a title screen, but when it's almost complete, I add a new "Yal logo" room before that - things aren't broken), then don't ever reset them again - only add to them when the player gets EXP or levels up. Making them global means they carry over between rooms, so you don't need to set them at the create/room start to avoid "variable doesn't exist" errors. Global things exist forever once you set them once (until you quit/restart the game).
     
  17. IncuTyph

    IncuTyph Member

    Joined:
    Oct 18, 2019
    Posts:
    10
    You know, I never thought of making a title screen a room (don't have any yet; this is something I haven't been working on for long). I'll try making a stat-handling setup object for my first room and see if that works. I was going to implement saving (it is an RPG after all) but I'm nowhere near doing that so I think I'll be ok with values resetting when I boot up to test for now.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice