This issue is to list the large scale battle system refactors that need to be done.
Remove the hacks from the battle PRs and have a more streamlined and simple battle console.
I did some sampling and noticed some small differences in battle action results. Maybe rounding of variant is wrong? Maybe our RNG behaves differently?
First verify results with no variance, then add variance.
Consolidate skill effects and other battle related algorithms into one place. In particular, one code path should be used for skills and items in battle and in the menu.
Game_Battler class inheritance heirarchyGame_Actor should stand alone and not inherit from Game_Battler. The problem is that Game_Battler contains battle state, and this should not exist outside of battle. Instead Game_Battler objects should be created on battle start and maintain a pointer to an actor or enemy. When the battle ends, all Game_Battler's will be destroyed.
The benefits are:
SourceAnimationState conceptAnimation state is 2k3 specific. It should live in some 2k3 specific entity. Enemy Death and Self-Destruct in 2k will need to be moved to their own special place.
@CherryDT
I did some testing and noticed that for RPG_RT, the variance applied to damage calculations may not use a uniform distribution. I found the that the edges (X-20%,X+20%) seem to occur more rarely than other values.
Is RPG_RT using any special distribution here?
(From Discord)
Cherry, what distribution is used for variance and m battles? It seems not uniform as the min max are rare
Hm but I think it's uniform, at least in 2k... should be like this:
function applyVariance(value, variance) {
let range = Math.floor(value * variance / 10)
if (range < 1) range = 1
return value + Math.floor(Math.random() * (range + 1)) - Math.floor(range / 2)
}
_Maybe_ it's different in 2k3...
@CherryDT
Another one I just remembered.
Do you know the frame timings in between battle messages in the rm2k battle system? We now have 2k battles nearly feature complete but I think we are still off for the delay timings on some of those messages.
It will be very time consuming to research and list them here, there are so many different times used for various things in the battle.
You are better off testing it yourself.
There is a function, let's just call it Wait(min, max). It will wait for max frames. Enter or Shift (regardless of testplay) will skip the wait if pressed after min frames. If escape is pressed, it will extend the wait until escape is released. Clarification: The triggering doesn't matter, only the current state, so holding down Enter or Shift will skip everything as soon as possible all the time.
_Note: especially in older versions the escape key feature wouldn't work indefinitely as soon as the game ran on more than one processor, due to the same race condition that caused key input processing to randomly return 0 for one frame even thought the key was continuously held down._
On RM2kE 1.62, this function is at virtual address 0x4794870x479484 (_EDIT: doesn't matter here though, this guide will work either way_), and min and max are passed in registers edx and ecx.
So, to log the calls, you can do this: (Windows)
479487, click "OK"

0 and "Log Text" to Wait({d:edx}, {d:ecx})
Wait function are logged in the debugger!
(Correction: Shift also skips only after min frames.)
By the way, if you _don't_ set the "Break Condition" to 0, but leave it empty or set to 1, you will actually break every time the wait function is called. May also be useful to understand more exactly when it is called. You can resume with F9.
By the way, if you need this for RM2k3 too, on RM2k3 v1.09a+ (that is, both inofficial v1.09a+ and official v1.10+, since they are all just huge hacks on top of the v1.09a binary) the address is 4966B8.
(Also, I realized the address is actually 479484 and not 479487 in RM2k, it just happens to not make a difference to log at 479787 :D)
@CherryDT
Here's a debugger case that would be very useful. I'd like to get a printout of all damage numbers that occur from attacks, skills, healing, etc.. actions in battle.
Basically what i want to do is some distribution testing of damage to ensure the numbers from RPG_RT match Player. For this I need a lot of samples.
For example, put the hero on autobattle, record damage numbers for 200 attacks, and compare the distributions from RPG_RT and Player.
I noticed some differences before so this is important for difficulty scaling to match.
Self Destruct Damage Algo:
v8 = (*RPG::Inventory)->party.size;
v9 = 0;
do
{
v10 = LookupActorByPartyIndex(*RPG::Inventory, v9);
if ( BattlerExists(v10) )
{
v2->actionMessageLineAmount = 1;
sub_47AFC8(v2);
DisplayBattleMessage(v2, 4, 4);
v11 = LookupActorByPartyIndex(*RPG::Inventory, v9);
v17 = GetActorDef(v11) / 2;
v12 = GetBattlerAtk(&v25->battler);
v24 = max(0, v12 - v17);
if ( v24 > 0 )
{
v23 = max(1, 4 * v24 / 10);
v13 = RPG_RandExclusive(v23 + 1);
v24 += v13 - v23 / 2;
}
v17 = 100;
v14 = LookupActorByPartyIndex(*RPG::Inventory, v9);
ProcessDamage(v2, v14, v24, v9, v8, v2, 10, v17);
}
++v9;
--v8;
}
while ( v8 );
Superseded by #2399
anything of interest in here for the release blog?
If yes: Milestone it
If not: Label it with "Duplicate", thx
Labeled it, we can use #2399 for release blog