AddExperience¶
AddExperience is a terminal coroutine that is invoked whenever most battles are won with EXP gain. This coroutine will be the step between the battle finishing and ExitBattle which is a wrapper around ReturnToOverworld.
The coroutine yield breaks immediately if alreadyending is true (meaning AddExperience or GameOver was already invoked) or gameover is in progress.
NOTE: The vast majority of the logic in this coroutine concerns very verbose animations and UI rendering. For the sake of brevity, they will be paraphrased and details will be kept at a high level. All other logic will still be mentioned in granular details.
Setup¶
alreadyendingis set to true which prevents double invocationsactionandcancelupdateare set to true changing to a terminal flowenemyis set to false, but this doesn't do anything because we just changed to a terminal flow- If the 
HealingBuzzmedal is equipped:- All player party members with an 
hpabove 0 has Heal called on them for an ammount of 2 with nosound - The 
Healsound is played (the reason the Heal calls didn't had sound is to avoid playing healing sounds multiple times) 
 - All player party members with an 
 - 0.5 seconds are yielded if any player party members were healed as a result of the 
HealingBuzzlogic above - If the 
VictoryBuzzmedal is equipped:- HealTP is called which plays a 
Heal2sound followed by a heal of instance.tpby 4 followed by a ShowDamageCounter with type 2, the amount being 4, the start position beingplayerdata[GetRandomAvaliablePlayer()].battleentityposition + (2.0, 2.0, 2.0) and the end position being (5.0, 5.0, 5.0) - 0.5 seconds are yielded
 
 - HealTP is called which plays a 
 - If 
exprewardis above 5:checkingdeadis set to a new UseCharm coroutine starting withExpUpas the type- All frames are yielded while 
checkingdeadis in progress 
 - The 
switchiconandfronticonare destroyed - If flags 613 is true (RUIGEE is active), 
exprewardis set to 0 - Otherwise, if 
exprewardwas already 0 whileenemyfledis false and instance.partylevelis less than 27 (the normal max rank),exprewardis set to 1 - RefreshEXP is called
 - AddExperience determines if a 
BattleWonsound should be played. it will be ifmusicvolumeis above 0.0 andmusic[0].name isBattle0orBattle6(meaning that the music we were just playing was one of the 2 regular battle themes). If that is the case:- FadeMusic is called with a fadespeed of 0.05
 - The 
BattleWonsound is played and the AudioSource is kept track locally - If the 
BattleWonAudioSource indeed exists, its volume is set tomusicvolume(this is needed because it's a sound so it wouldn't get the music volume by default) 
 - flagvar 0 is set to 
expreward(this will be used for rendering later) - instance.
hudcooldownis set to -1.0 - All frames are yielded while there are still any enemy party members
 - 0.45 seconds are yielded
 - All player party members has their matching instance.
hud's child has its local position set to Vector3.zero - For every player party members whose 
hpis above 0: - instance.
camtargetposis set to (-4.5, 0.0, 2.5) 
EXP gain visuals setup¶
The process to render the expereince gain screen is very verbose and complex so the procedure is paraphrased a lot here:
- A 
textholderGameObject gets created with aDelAftBtltag (destroyed on ReturnToOverworld) childed to the GUICamera with a z local position of 5.0 - SetText is called in non dialogue mode using the following string: 
|sort,10000||color,4||center||dropshadow,0.05,-0.05||backbox,6|followed bymenutext[117](a message informing the player they gained EXP where the number is|var,0|). The call has the following properties:- fonttype of 2 (UNUSED, but gets overriden to 
D3Streetism) - No linebreak
 - No tridimensional
 - position of (0.0, 3.0, 5.0)
 - No cameraoffset
 - size of Vector3.one
 - parent being the 
textholder - No caller
 
 - fonttype of 2 (UNUSED, but gets overriden to 
 - A new UI object called 
ExpBarwith aDelAftBtltag (destroyed on ReturnToOverworld), a DialogueAnim and a pure yellow color usingguisprites[4](the HUD background sprite) is created as the background of the EXP text lviconis set to a new UI object namedIconusingguisprites[27](the EXP icon sprite) childed to theExpBar- A DynamicFont is setup childed to the 
ExpBarwith a layer of 5 (UI) with a pure white color with the starting text being the following appended together:- instance.
partyexppadded to the left with 30 /- instance.
neededexp 
 - instance.
 - All player party members with an 
hpabove 0 has their battleentity.spinzeroed out leveledis set to false- 0.15 seconds are yielded
 
EXP orbs counting and wait¶
This sub section concerns the counting of the EXP gained and the management of its fast version if requested by the player.
- instance.skiptext is set to false (this isn't used for its SetText use since it will be managed manually)
 - A new GetSkip coroutine is started and stored localled which will yield all frames until input 4 (Confirm) is pressed which wil cause instance.
skiptextto be set to true - The EXP orbs are counted starting with 
bigexporbsthen moving tosmallexporbsthat exists (there is a frame yield between the 2 types's counting). A big one will have 1 EXP counted 10 times while a small one will only have it counted once. This is how the counting happens each time:- The orb gets destroyed
 - AddExp(1) is called to add the exp (more details below)
 - If the AddExp call resulted in a rank up, Leveled is called which sets 
leveledto true, but if it wasn't true before, a SpinAround component added tolviconwith itsitselfset to (0.0, 20.0, 0.0) followed by aLazersound being played at 1.2 pitch - The DynamicFont of the EXP's text is refreshed using the new instance.
partyexp - If instance.
skiptextis still false, a yield is done. The time of the yield is 0.075 seconds unlessexprewardwas at least 10 where it will be 0.045 seconds instead 
 - At this point, the GetSkip coroutine call earlier is stopped since it no longer has any use
 - If instance.
skiptextwas set to true by the end of the counting, the DynamicFont of the EXP's text is refreshed using the new instance.partyexpfollowed by 0.2 seconds being yielded - A frame is yielded
 - instance.
skiptextis set back to false - For a maximum of 50.0 frames (tracked with a local counter starting at 0.0 and incremented by 1/50 of the game's frametime until it reaches 1.0), all frames are yielded until any input is pressed which interupts this wait early
 - If the 
BattleWonsound was played earlier, all frames are yielded while it's still playing and hasn't reached 2.35 seconds - A second is yielded if no 
BattleWonsound was played 
AddExp¶
The method mentioned above called AddExp belongs to MainManager and it adds the exploration points and determines if a rank up happened as a result:
public static bool AddExp(int ammount)
Increases partyexp by ammount. If this resulted in a rank up, true is returned, false otherwise. A rank up is detected if after the increase, partyexp becomes at least neededexp. When that happens, partyexp is decreased by neededexp.
Before returning, a PlaySound call happens to play the the Exp2 sound with a volume of 1.0 and a pitch of 1.5 + a random number between -0.1 and 0.1. The sounds element to use is the first among sounds[4], sounds[5], sounds[6] and sounds[7] in that order that isn't playing (always falsback to sounds[7] even if it is playing).
Text UI teardown¶
- A DialogueAnim is added on the 
ExpBarobject to move it to the left offscreen - 0.5 seconds are yielded
 - The 
textholderobject is destroyed - A frame is yielded
 
Rank up logic¶
This logic only happens if leveled is true and instance.partylevel is less than 27 (the normal max rank).
The logic in here is very complex and mostly contains verbose animations so it will be paraphrased a lot.
Setup¶
- instance.
partylevelis incremented - 0.25 seconds are yielded
 - instance.
neededexpis increased to a certain amount to indicate the new amount required to rank up. The first increase that applies in the following ones is the one that will occur (they are mutually exclusive):- +5 If flags 656 is true (MOREFARM is active)
 - +3 if instance.
partylevelis at least 24 - +2 if instance.
partylevelis at least 15 - +1 if none of the above applied
 
 - ChangeMusic is called with the 
LevelUpmusic Prefabs/Particles/Flowerettiparticles are instantiated childed to thebattlemapand played- All 
Sprites/GUI/BattleMessage/rankXare loaded whereXis the languageid (it falls back to English if no Sprites exists for it) - All objects with tag 
Enemyare destroyed - SetDefaultCamera is called
 - MainManager.Heal is called
 - instance.
hudcooldownis set to -1 - instance.
optionis set to 0 and instance.maxoptionsto 3 
Rank up animation¶
- All player party members has their battleentity.
animstateset to 4 (ItemGet) and theirspinto (0.0, 20.0, 0.0) - All player party members are move to be centered on the screen using MiddlePos via lerping their battleentity.position for a maximum of 34 frames (tracked via a local framecounter advancing by 0.03 of the game's frametime from 0.0 to 1.0)
 - All player party members gets their battleentity.
spinzeroed out and their battleentity has a SpecialAnimation started with thelevelupanimation - The letters of the Rank up messages appears in the following fashion:
- A 
LetterHolderobject is created and childed to GUICamera - New UI objects called 
letterXwhere X is the index of the letter sprite loaded earlier are created all childed to theLetterHolderwith a FontEffects using just the rainbow effect - The letters appear from offscreen at 99.0 in Y and 5.0 in Z using a lerp off their local position. This is done over a maximum of 200.0 frames and it is porportional to the amount of letters to show
 - 0.65 seconds are yielded
 - All letters have their local scale lerped from Vector3.one to (0.0, 1.25, 1.0) and their angle increased by Vector3.up * 5x the game's frametime continuoudly over the course of maximum 34 frames (tracked via a local framecounter advancing by 0.03 of the game's frametime from 0.0 to 1.0)
 - The 
LetterHolderis destroyed 
 - A 
 
Rank up bonus UI setup¶
- 3 
Prefabs/Objects/Vineare created using layer 15 (3DUI) childed to thebattlemapwith each their own UI icon. The vines are positioned centered to the screen using MiddlePos and they have a DialogueAnim with a tsize being Vector3.one * 2.0. Each has aguisprites[42](a hexagon) on the background of a newOvericonobject with a SpriteRenderer childed to their vine. The sprites used for the icons are:- 0: HP icon
 - 1: TP icon
 - 2: MP icon
 
 - An MP count HUD element is created:
- New UI object called 
medalhudchilded to thetextholderwith a pure yellow color using the HUD background sprite - New UI object called 
medaliconchiled to themedalhudusing the MP icon sprite - A DynamicFont is setup on the 
medalhudas parent withdropshadowand with the text being the following appended together:- instance.
bppadded to the left by 20 /- instance.
maxbppadded to the left by 20 
 - instance.
 - A DialogueAnim is added on the 
medalhudso it appears from the top of the screen 
 - New UI object called 
 - 0.8 seconds are yielded
 - A 9Box is created with a DialogueAnim to make it grow
 - A SetText call happens in non dialogue mode with the text being 
|single|followed bymenutext[122](a prompt message to pick a stat boost) and the following properties:- fonttype of 0 (
BubblegumSans) - No linebreak
 - No tridimensional
 - position of (-7.5, 0.15, 0.0)
 - No cameraoffset
 - size of Vector3.one
 - parent being the 9Box
 - No caller
 
 - fonttype of 0 (
 - A new UI object is created named 
tchilded to the GUICamera using thecursorsprite[0]with a SpriteBounce - 5 frames are yielded (counted by MainManager.
framestep) 
Rank up bonus UI naviguation and confirmation¶
- All frames are yielded while Input 4 (Confirm) isn't pressed
 - A 
Confirmsound is played - A frame is yielded
 - The cursor gets childed to the 
battlemapthen moved offscreen and DestroyText is called with it - instance.
hudcooldownis set to -1 - A SetText call happens in non dialogue mode with the text being 
|single|followed bymenutext[119](the HP rank up bonus description) and the following properties:- fonttype of 0 (
BubblegumSans) - No linebreak
 - No tridimensional
 - position of (-7.5, 0.15, 0.0)
 - No cameraoffset
 - size of Vector3.one
 - parent being the 9Box
 - No caller
 
 - fonttype of 0 (
 - 5 frames are yielded (counted by MainManager.
framestep) - From here, an infinite loop is entered with a frame yield each iteration that won't exit until one of the 3 rank up bonuses have been chosen. Each iterations features the selected instance.
option's vine's sprites being rotated and scaled via a lerp continuously propotional to the games frametime. It also feature another SetText call just like the above when instance.optionchanges, but the text ismenutext[119 + X]whereXis instance.option:- If 
caninputcooldownisn't expired, it is decreased by the MainManager.framestepand no input can be taken until it expires - Otherwise, the logic depends on the input:
- 2 / 3 (Left / Right): changes instance.
optionaccordingly with wrap around to 2 followed by a scroll sound followed bycaninputcooldownbeing set to 3.0 - 4 (confirm): The UI loop is exited (the option chosen is indicated by instance.
option) 
 - 2 / 3 (Left / Right): changes instance.
 
 - If 
 - The 
LevelUpsound is played - For a maximum of 40 frames (tracked with a local counter starting at 0.0 and incremented by 1/40 of the game's frametime until it reaches 1.0):
- All other vines than the instance.
optionone have their local Y position lerped to 20.0 and their Z to 0.0 which moves them offscreen - The instance.
optionvine gets their angles reset 
 - All other vines than the instance.
 - The 
CrowdClapsound is played onsounds[9]with 0.5 volume 
Rank Up bonus application¶
The logic to apply the bonus depends on instance.option:
- 0 (HP): All player party members gets their 
basehpandmaxhpgets incremented and a 1HPbonus to the party is added to instance.statbonusvia AddStatBonus - 1 (TP): A 1 
TPbonus to the party is added to instance.statbonusvia AddStatBonus - 2 (MP): instance.
maxbpand instance.bpgets increased by 3 and a 3MPbonus to the party is added to instance.statbonusvia AddStatBonus. It also causes themedalhud's DynamicFont text to be refreshed with the new instance.bpand instance.maxbp 
After, the following happens:
- ApplyStatBonus is called
 - Each player party member has a unique animation played there that sets their battleentity.animstate to a value that depends on the 
trueid:Bee: 111, also comes with a SlowSpinStop of (0.0, -20.0, 0.0) for 30.0 frametime on the battleentityBeetle: 114, also comes with a battleentity.fliptoggleMoth: 115
 - A frame is yielded
 - ApplyBadges is called
 
LevelUpMessage and teardown¶
- instance.
hudcooldownis set to -1 medalhud's DialogueAnim'stargetposis set to (3.7, 10.0, 5.0) which moves it along with the rest of the HUDmedalhudis destroyed in 0.5 seconds- 0.5 seconds is yielded
 - The 9Box is destroyed
 - flagvar 0 is set to 0 (this will be used to track whenever a coroutine gets done)
 - A LevelUpMessage coroutine is started (this will set flagvar 0 to 1 when it's complete)
 - All frames are yielded while flagvar 0 is 0 (meaning the LevelUpMessage isn't done yet)
 - ApplyBadges is called
 - A frame is yielded
 - MainManager.Heal is called with noparticle and with nosound
 - instance.
hudcooldownis set to -1 
Special heal¶
If the rank up logic didn't happen, but instance.partylevel is at least 99 (which normally can never happen), Heal is called.
Last steps¶
- A frame is yielded
 sounds[9]is stopped with a 0.002 delay- ExitBattle is called