[RM2K3] BEST WAY TO MAKE A VARIABLE-COMPARING CALCULATION?
Posts
Pages:
1
Hello, like the title said, is there an easy way to make the system "sort" the variable; as well as comparing it to find (for example) the highest value?
Specifically, it is something like a SPEED stat based calculation in battle. That is, the person with the highest SPEED would act first, followed by the next highest etc etc.
Ex.
A : 10 SPD
B : 8 SPD
C : 9 SPD
So A will act first, followed by B, and then C.
However, I have NO idea how to implement this in simple coding (is there a Function for this?). I tried making a counter that goes down (highest goes first), but it does get a bit messy and ended up with a pretty long loop, especially with huge number.
So uh, please help?
SIDE NOTE
I remember seeing an old RM2k3 game with battle system like GRANDIA series. There is a bar with moving icon and all that; Something like that would work too. So if you know how to make that (the basics, like how many variables I need, which FUNCTION to use, how to set it up and all that) please let me know!
Specifically, it is something like a SPEED stat based calculation in battle. That is, the person with the highest SPEED would act first, followed by the next highest etc etc.
Ex.
A : 10 SPD
B : 8 SPD
C : 9 SPD
So A will act first, followed by B, and then C.
However, I have NO idea how to implement this in simple coding (is there a Function for this?). I tried making a counter that goes down (highest goes first), but it does get a bit messy and ended up with a pretty long loop, especially with huge number.
So uh, please help?
SIDE NOTE
I remember seeing an old RM2k3 game with battle system like GRANDIA series. There is a bar with moving icon and all that; Something like that would work too. So if you know how to make that (the basics, like how many variables I need, which FUNCTION to use, how to set it up and all that) please let me know!
Although I never directly used it myself, I know a mathematical way to do this with variables: It will result in a "priority" system. However, it will become much more complicated if the number of characters in battle is higher, as a large number of characters and enemies will result in a lot of calculations that need to be done. It is also not extremely simple, but I'd try to decribe it as precisely as possible.
So, how many participants can be in a battle at maximum?
So, how many participants can be in a battle at maximum?
At most it would be... roughly 10 participants in battle, although 8 is fine too.
I guess it kinda falls into the "too large" category?
I guess it kinda falls into the "too large" category?
Well, it depends on how much time and work you are willing to put into it. With a maximum number of 10 partcipants in battle, you will have to set up at least 200 Conditional Branches - although you can just copy/paste and then slightly modificate most of them.
It would still work, but if it sounds like too much for you, that's understandable.
Just for clarification: This is intended to be used in a custom battle system, right? Because using it in the regular battle engine probably wouldn't work well.
It would still work, but if it sounds like too much for you, that's understandable.
Just for clarification: This is intended to be used in a custom battle system, right? Because using it in the regular battle engine probably wouldn't work well.
author=NeverSilentBollocks. I say 3.
With a maximum number of 10 partcipants in battle, you will have to set up at least 200 Conditional Branches
If there is no sorting FUNCTION, you make one (as a CallEvent):
<> Comment: VarCheck FUNCTION
<> Change Variable: [0021:VC_ID_First/Now] = 1
<> Change Variable: [0022:VC_ID_Last] = 10
<> Change Variable: [0023:VC_ID_Memory] = V[0021]
<> Label: 1
<> Change Variable: [0024:VC_Value] = Var[V[0021]] value
<> Fork Condition: If Variable [0024:VC_Value] is 0 or more
<> Comment: Variables with negative values are ignored.
<> Change Variable: [0025:VC_Temp] = Var[V[0023]] value
<> Fork Condition: If Variable [0024:VC_Value] is V[0025] greater
<> Comment: Memorize new Var_ID if the value is higher than the highest
: memorized value.
<> Change Variable: [0023:VC_ID_Memory] = V[0021]
<>
: End
<>
: End
<> Fork Condition: If Variable [0021:VC_ID_First/Now] not V[0022]
<> Change Variable: [0021:VC_ID_First/Now] + 1
<> Jump To Label: 1
<> Comment: FUNCTION loops from Var_ID_First/Now to Var_ID_Last.
<>
: End
<> Change Variable: [0025:VC_Temp] = Var[V[0023]] value
<> Show Message: The highest value of \v[0025] is in Variable No. \v[0023].
<> Change Variable: [0021:VC_ID_First/Now] = 1
<> Change Variable: [0022:VC_ID_Last] = 10
This picks the highest number (if equal, it's prioritizing participants with a lower ID) out of a range of values stored in variables referenced by Var[0021:VC_ID_First/Now] (participant A) and Var[0022:VC_ID_Last] (participant XYZ).
You can use this to make a list of turn orders by taking the participant_ID from Var[0023], put it into your list, go one position down your list, multiplying Var[V[0023]] by -1 (that 'marks' the participant as 'ignore me' in the sorting function and can be easily reverted by multiplying every participants SPEED value by -1 when all the sorting was done.) and calling the sorting function again, getting the next highest number (while ignoring the marked values).
Or just go turn-by-turn (sort once -> do turn -> sort next turn) without a list of turn orders (if turn order is not shown).
edit:
To reduce lag: AntiLagSwitch
bugmenot, that solution sounds a thousand times better than what I had in mind. I did not know this:
was possible in RM2K3. If such a function to call a variable ID specified by the value of another variable exists, that's a huge advantage. (I use RMXP which has no such function by default, so I was oblivious and wanted to do it all manually.)
s_w, just forget everything I suggested and use above solution.
author=bugmenot<> Change Variable: [0024:VC_Value] = Var[V[0021]] value
was possible in RM2K3. If such a function to call a variable ID specified by the value of another variable exists, that's a huge advantage. (I use RMXP which has no such function by default, so I was oblivious and wanted to do it all manually.)
s_w, just forget everything I suggested and use above solution.
Just got the chance to pop back in. The code looks promising, but honestly I am still trying to understand how it works.
@BugMeNot
I hope you don't mind me asking some uh, stupid question about the code.
So basically what it does is cycle through the values of 21-22, comparing them one by one (i.e. until it got thelast Final value that is the highest)?
Also, My brain is a bit wrecked from the initial coding, so by this
Did you mean after getting the highest value, I then do a similar call event in reverse to get the "slower than current" character in the list?
Also, um, regarding the multiplying by -1, you are referring to the original code (that ignore speed <0) to exclude them from the list, so basically instead of (my suggestion before about "reverse" event, I just re-plugged your code playing with negatives?)
For example
Var1-6
when I got the highest value, which say, var3
I just multiplies it by -1 so it becomes -9, and gets ignored?
Also, Genius!
@NeverSilent
Honestly I was thinking of manually coding them too (kinda resigned to doing hundreds of and FUNCTION). Luckily it seem there is a better way. Anyway, thanks for the initial response as well as for kicking the discussion forward. Also, RMXP can't do this VarA=VarB? I have no experience in XP but shouldn't that be possible (XP is released later after all).
@BugMeNot
I hope you don't mind me asking some uh, stupid question about the code.
So basically what it does is cycle through the values of 21-22, comparing them one by one (i.e. until it got the
Also, My brain is a bit wrecked from the initial coding, so by this
You can use this to make a list of turn orders by taking the participant_ID from Var, put it into your list, go one position down your list, multiplying Var[V] by -1 (that 'marks' the participant as 'ignore me' in the sorting function and can be easily reverted by multiplying every participants SPEED value by -1 when all the sorting was done.) and calling the sorting function again, getting the next highest number (while ignoring the marked values).
Did you mean after getting the highest value, I then do a similar call event in reverse to get the "slower than current" character in the list?
Also, um, regarding the multiplying by -1, you are referring to the original code (that ignore speed <0) to exclude them from the list, so basically instead of (my suggestion before about "reverse" event, I just re-plugged your code playing with negatives?)
For example
Var1-6
when I got the highest value, which say, var3
I just multiplies it by -1 so it becomes -9, and gets ignored?
Also, Genius!
@NeverSilent
Honestly I was thinking of manually coding them too (kinda resigned to doing hundreds of and FUNCTION). Luckily it seem there is a better way. Anyway, thanks for the initial response as well as for kicking the discussion forward. Also, RMXP can't do this VarA=VarB? I have no experience in XP but shouldn't that be possible (XP is released later after all).
author=s_wYou'd have to know some Ruby or someone that knows Ruby to get that working. (Probably... dunno)
Also, RMXP can't do this VarA=VarB?
Also, it's about getting a variable_ID into VarB so VarA is set to the contents of the variable that is referenced in VarB.
author=s_wSorry. I need to up my software documentation skills.
I am still trying to understand how it works.
Let's go by the Var_IDs I stated in my first post here (you can, of course, change them). Let's say you have your participants' SPEED values in Var[0385] to Var[0394] and only 3 participants in battle:
A = Var[0385] = 10
B = Var[0386] = 8
C = Var[0387] = 9
D = Var[0388] = 0
...
K = Var[0394] = 0
Var[0021:VC_ID_First/Now] should be set to the first variable that has to be considered (= 385 in this example) and Var[0022:VC_ID_Last] should be set to the last variable (= 387 in this example).
That's why it might be a better idea to assign 'ID_First/Now' and 'ID_Last' before calling the CallEvent / function.
Yes, the event code cycles through the variables from 'ID_First/Now' up to 'ID_Last' and only memorizes a variable_ID if its value is higher than the previously memorized one.
1. You set 'ID_First/Now' and 'ID_Last' (to refer to where any values that you want to get the highest value from are stored in variables).
2. You call the Event with the VarCheck FUNCTION (either CommonEvent or MapEvent if on a CBS map).
3. The result gets written into Var[0023:VC_ID_Memory], which states the variable that contains the highest value amidst 'ID_First/Now' and 'ID_Last' (= 385 in this example).
4. You have your turn order in, for example, Var[0501] and the consecutive variables. You make a
<> Change Variable: [0501:TOrder_1st] = V[0023]
<> Change Variable: [0501:TOrder_1st] - 384
5. To get the next highest number you have to knock the already tested values out of the system by multiplying the variable that is referenced in Var[0023:VC_ID_Memory] by -1.
6. 'ID_First/Now' and 'ID_Last' stay the same as in step 1. and you call the Event with the VarCheck FUNCTION again, which outputs 387 in Var[0023:VC_ID_Memory] this time.
7.
<> Change Variable: [0502:TOrder_2nd] = V[0023]
<> Change Variable: [0502:TOrder_2nd] - 384
8. Multiply the variable referenced in Var[0023] by -1, and rinse and repeat until you get to the last participant.
X. Multiply every variable in the range between 'ID_First/Now' and 'ID_Last' by -1 to get back to the initial SPEED values, so you can work with them normally again.
Bear in mind that this event code FUNCTION thingy considers only positive values.
(you would have to change the first conditional branch after the <Label> to ask for another digital cue... for example if a value is still within -1.000.000 and +1.000.000 when working with 6 digit numbers... marking negative numbers by reducing them by 1.000.000 and marking positive numbers by adding 1.000.000 to them. Like, thinking up an easy way to make variables into pseudo-booleans without making it too complicated (like comparing it with what's already in the TOrder list))
author=s_wIndeed. Reusable and revertable (instead of wasting other variables to make backups of values to work with 'em)
when I got the highest value, which say, var3 = [9]
I just multiply it by -1 so it becomes -9, and gets ignored?
Likewise you can use this to ignore variables beforehand that interrupt the range of values you want to test (for example you have the participants stats not ordered as "SPD(A) SPD(B) SPD(C) ..." but in a sequence of "ATK(A) DEF(A) SPD(A) ATK(B) ...")
author=bugmenotNo, no, it is mostly my fault, since my coding skill/comprehension is pretty lacking.author=s_wSorry. I need to up my software documentation skills.
I am still trying to understand how it works.
I got pretty much the gist of the code, but this line
<> Change Variable: [0501:TOrder_1st] - 384
Why is this necessary (-384)? And this value stay the same with this part :
<> Change Variable: [0502:TOrder_2nd] = V[0023]
<> Change Variable: [0502:TOrder_2nd] - 384
Would it be easier to multiply the variable by -1 (which is also possible).
In retrospect, I think the -384 function is when I need to actually show a sequence of turn in a list?
Basically until the point that your code told me how to:
1. Find a highest/lowest value (technically to find lowest value I just need to change the "greater" comparison to "lower" right? Haven't really tried in reverse yet)among a set of numbers
2. How to exclude the "turn" via negative multiplier
I can already figure a bit of a method to allow me to
1)call the event
2)allow ACT in battle
3)exclude that character and call the event again
basically not showing the actual Turn sequence to the player; which may prove beneficial since 1) extra work to show 2) speed boosting ability may make it messy.
Am I getting it right so far? Also I'll say it again. Your code is amazing. I tried to make similar function/loop but can't figured out which function in Rm2k3 I need to mix and match to create it. Certainly save me tons of work since comparison is important in making say, enemy AI.
=====
Lastly, Not to sound like ungrateful prick, but since we are at this topic, perhaps you know how to create similar battle system like Grandia or old Rm2k3 demo (I think it is "winter"?) which shows a sort of ATB but everyone follows the same line (represented by face icon), until a certain point at which they are allowed to act.
Basically I am just curious how to implement how fast the icon move to the "act" point. I can implement multi-event/parallel event that adds variable to the " ACT gauge" based on character's speed, but since the value varies (say 1-10 for example between the character), the icon would probably jump instead of moving at a faster rate?
(this is just extra question btw, don't sweat it).
======
author=s_wIf you have listed all the SPEED values after Var[0385], this will get the participant_ID / Battler_ID that belongs to the referenced SPD value. Yes, to show the player what moves next. In hindsight... this would lead to something like a "global turn" in which the fastest battler would get another turn after everyone else already did. Then the next global turn starts.
but this lineWhy is this necessary (-384)?<> Change Variable: [0501:TOrder_1st] - 384
author=s_wYes. Or lower/equal to not have A be considered slower than E if their SPD is the same (prioritize the player).
I just need to change the "greater" comparison to "lower" right?
author=s_wNah. It's just simple. And it does not seem to help making a smooth turn order.
Your code is amazing.
author=s_wHaven't played Grandia, yet.
how to create similar battle system like Grandia
author=s_wA solution might be to get the average SPD of everyone participating (everyone still alive, that is) in battle and basing the increase in a battler's "ACT gauge" on the quotient of battlerSPD x100 divided by AvgSPD x10 getting a decimal value times 10 (or else there would only be 0|1|2 ...)
" ACT gauge" based on character's speed, but since the value varies the icon would probably jump
SPD(A) = 10
SPD(B) = 8
SPD(C) = 9
SPD(D) = 8
SPD(all) = 35
AvgSPD(x10) = SPD(all) x10 /4
AvgSPD(x10) = 350 /4
AvgSPD(x10) = 88 (the decimal would be AvgSPD = 8.75)
So in an ACT+ cycle (every 0.5 second or so):
ACT+(A) = SPD(A) x100 / AvgSPD(x10)
ACT+(A) = 1000 / 88 = 11 (= 1.1 times faster than the average)
... and so on. Adding ACT+ to someone's ACT value.
Let's say someone gets a turn when their ACT value reaches 100. It would take up to 10 seconds + turn execution time until someone that's half as fast as the average has its turn. It might be a good idea to have the ACT+ increased by an additional x2.0 when nobody has an ACT value above 40(%) so it's faster. Increase ACT+ by x1.5 when noone's above 60%. Factor x1.0 when someone's above 80%.
That's where the sorting FUNCTION can help (getting the highest ACT value). And it can be used to get the participant that is the furthest down the shared "ACT gauge" to highlight its icon or whatever.
That's just an idea. And it sure needs work.
edit:
As it is, low SPD against high SPD will not get sufficient turns... maybe have the amount at which the ACT value is filled be somewhat logarithmic:
SPD = 1 = 10 ACT+
SPD = 2 = 15 ACT+
SPD = 3 = 19 ACT+
SPD = 4 = 22 ACT+
SPD = 5 = 24 ACT+
...
SPD = 8 = 28 ACT+
SPD = 9 = 29 ACT+
SPD = 10 = 30 ACT+
(Or the other way around, meaning that the higher the SPD the more ACT will be filled. You did say that there are abilities that lower SPD, so it would have a bigger effect on fast enemies/allies when shot in the foot (or what can be considered a foot) whereas the slow 'n' steady units will more ore less shrug it off.)
Or add +3 to SPD before calculating the AvgSPD to avoid B getting a turn after A finally had 9 turns in case of:
A : 10 SPD +3
B : 1 SPD +3
So that it's 2 or 3 turns.
author=bugmenotAll right, I think I got the gist of it. It might need a lot of testing and all that, but at least i can understand the idea better. Now I just need to improvise.
<about the icon-battle system thing>
author=bugmenotAll the better, since yeah, I am a bit more partial to the player.author=s_wYes. Or lower/equal to not have A be considered slower than E if their SPD is the same (prioritize the player).
I just need to change the "greater" comparison to "lower" right?
Again, thanks a lot for showing me how it is done; it really take a load off my mind!
Pages:
1















