I’m at the point in my Sandbox RPG where I need to put in the code that allows the player character to level up (and the opponent character to level down). I have designed the system in such a way as to allow the player to cascade their level, if enough experience is gained to level up twice. Moreover, it’s possible to level up in multiple skills at the same time, as well as levelling down your opponents.
I want to call attention to levelling up process, using a pop-up box that tells you that you levelled up, in what skill, and tells you your new level.
So far, however, only one dialogue box pops up; the last one in the string. I would like for all of them to pop up in the sequence in which they were sent.
Here’s an excerpt of the code, and this is just copied and pasted through all of the different skill categories for each named opponent (with certain exceptions for story reasons):
<<if $PlayerHand lt 10>>\
<<set $PlayerHandXP to $PlayerHandXP + $PHandXP>>\
<<for $PlayerHandXP gte 100 and $PlayerHand lt 10>>\
<<set $PlayerHand to $PlayerHand + 1>>\
<<set $PlayerHandXP to Math.floor(($PlayerHandXP - 100) / 2)>>\
<<set $LevelUpText to "$PlayerName's hand control skill has increased. Your hand skill is now $PlayerHand.">>\
<<run Dialog.create("Level Up").wikiPassage("Level Up").open();>>\
<</for>>\
<<if $PlayerHand is 10>>\
<<set $PlayerHandXP to 100>>\
<</if>>\
<<else>>\
<<set $PlayerHandXP to 100>>\
<</if>>\
\
<<if $PlayerFoot lt 10>>\
<<set $PlayerFootXP to $PlayerFootXP + $PFootXP>>\
<<for $PlayerFootXP gte 100 and $PlayerFoot lt 10>>\
<<set $PlayerFoot to $PlayerFoot + 1>>\
<<set $PlayerFootXP to Math.floor(($PlayerFootXP - 100) / 2)>>\
<<set $LevelUpText to "$PlayerName's foot control skill has increased. Your foot skill is now $PlayerFoot.">>\
<<run Dialog.create("Level Up").wikiPassage("Level Up").open();>>\
<</for>>\
<<if $PlayerFoot is 10>>\
<<set $PlayerFootXP to 100>>\
<</if>>\
<<else>>\
<<set $PlayerFootXP to 100>>\
<</if>>\
The dialog it calls for, “Level Up,” contains the following code:
$LevelUpText
The code may be a little overcomplicated because I’m not exactly the best at this, but I know that the levelling system is working because I tested it. I just want the dialogue boxes to all pop up, instead of just the last one. I’d like the player character to know what skill levels they gained, not just which ones their opponent lost.
That’s because only one dialogue box can be open at a time (it’s built on the same single element: #ui-dialog).
One way to avert this, would be to have the level-up-notifying code on a timer, but doing it from scratch is a pain (especially if you have some random components with the different skills not levelling up at the same time).
I think you might like this custom macro, which gives the player a notification (with whatever you want and how many of them you want on the screen).
I’ve never seen 2 dialog boxes open simultaneously, it may be a limitation of the twine engine. Some alternate ideas are to compile all the stats gained, and show it in one dialog box. Or if two levels are gained, generate a link at the bottom of the first level dialog box leading to the second one.
The limitation doesn’t come from the Twine Engine, but SugarCube as a format. Because all pop-ups/dialog boxes use the same elements #ui-dialog. So when it’s being called multiple times, it will only load the final call.
Some alternate ideas are to compile all the stats gained, and show it in one dialog box.
I did consider this option as I was typing up my question. I was going to use that as a fallback option, where the string of text for levelling up first wipes itself clear by being set to something like “Here are the stats that improved:” and then appending extra lines to the dialogue.
The thought would have stopped me from sending my message, but I really would prefer having each one pop up in turn. Plus, it always helps to learn more about the system I’m using.
I tried the macro you suggested. Not in my main story, of course; I have a test story that I use for making sure the code works before injecting it into my main story.
It does seem to work, for the most part, but I’m having trouble with it reading a variable. I know the variable can be read, because I told it to print the string on the main body of the page in addition to the pop-up, and it reads just fine. It’s just not reading in the pop-up.
<<if $XP lt 100>>\
You did not level up.
<<else>>\
You levelled up:
<<for $XP gte 100>>\
<<set $LV to $LV + 1>>\
<<set $XP to Math.floor(($XP - 100) / 2)>>\
<<set $LVText to "Your level is now $LV">>\
<<flash $LVText>>\
<<Progress false>>\
<<Interactive false>>\
<<Theme dark>>\
<<Transition true>>\
<</flash>>
$LVText
<</for>>\
<</if>>
XP remaining: $XP / 100
[[Start]]
Something is causing the pop-up to not display the level. I had originally just built the string inside the pop-up the same way, but moved it outside for troubleshooting. The string works, but for some reason, the pop-up is not reading it.
If I nest everything inside of a single check and just repeat the check by going back to the page, I can launch the pop-up over and over until all checks are false.
Here’s the code I was trying to figure out, free of any macros:
<<if $XP1 gte 100>>\
<<set $LV1 to $LV1 + 1>>\
<<set $XP1 to Math.floor(($XP1 - 100) / 2)>>\
<<set $LVText to "Your Spear level is now " + $LV1>>\
<<run Dialog.create("Level Up").wikiPassage("Level Up").open();>>\
\
<<elseif $XP2 gte 100>>\
<<set $LV2 to $LV2 + 1>>\
<<set $XP2 to Math.floor(($XP2 - 100) / 2)>>\
<<set $LVText to "Your Sword level is now " + $LV2>>\
<<run Dialog.create("Level Up").wikiPassage("Level Up").open();>>\
\
<<else>>\
\
[[Go Home|Start]]
\
<</if>>\
If it detects that any level has been gained, starting with the first skill and moving forward, it will stop what it’s doing and open a single pop-up that reads as follows:
$LVText
<<button "Okay!">>
<<goto "Apply XP another way">>
<<run Dialog.close();>>
<</button>>
That returns to the XP application screen and checks again to see if there are any levels to be gained.
This has been tested, and it does work. I plan on having two of these running at the end of every battle; one for experience and one for achievements.