Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ai delay timer #3302

Merged
merged 2 commits into from
Sep 13, 2023
Merged

Add ai delay timer #3302

merged 2 commits into from
Sep 13, 2023

Conversation

DizzyEggg
Copy link
Collaborator

Adds a timer which counts how long it takes for the AI to decide which action and move to choose.
The number of frames will be displayed in the battle box replacing the "What will PKMN do" text.
Uses new config define DEBUG_AI_DELAY_TIMER

I also changed GetAiLogicData function's name to SetAiLogicDataForTurn, because it made more sense to me, but I can revert it or change to something else if needed.

Current benchmarks on upcoming are:

  • 11 frames when choosing a move
  • 48 frames when AI switches(note it may actually be closer to 30 or 50 depending on how many pokemon the AI party has). It takes too long, and the lag is way too noticeable, it'll be fixed in Smarter SwitchAI Mon Choices | HasBadOdds Switch Check #3253
  • 45 frames in a double battle
    When building with modern these all take less frames(which is all the more reason to ditch agbcc)
    upcoming_single
    pokeemerald_modern_02
    upcoming_double
    modern_upcoming_double
    upcoming_single_switch
    modern_upcoming_single_switch

Copy link
Collaborator

@ghoulslash ghoulslash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as ideas for making AI faster - replacing the table of AI flag functions with a table of score changes per move effect speeds things up considerably (we did this in voyager and I got 19 frames for a double battle with partner)

@@ -1889,6 +1889,19 @@ static void HandleChooseActionAfterDma3(u32 battler)
{
gBattle_BG0_X = 0;
gBattle_BG0_Y = DISPLAY_HEIGHT;
if (gBattleStruct->aiDelayTimer != 0)
{
gBattleStruct->aiDelayFrames = gMain.vblankCounter1 - gBattleStruct->aiDelayTimer;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on adding the frames counter to the battle debug menu?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AI one or in more general sense?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was thinking just adding the value to the AI Info page but that can just be a separate PR if desired. Otherwise I think this looks good now

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do it in a separate PR then

src/battle_controller_player.c Show resolved Hide resolved
@DizzyEggg
Copy link
Collaborator Author

As far as ideas for making AI faster - replacing the table of AI flag functions with a table of score changes per move effect speeds things up considerably (we did this in voyager and I got 19 frames for a double battle with partner)

Wow, this is a huge change! Could you share with us how it looks like?

@ghoulslash
Copy link
Collaborator

As far as ideas for making AI faster - replacing the table of AI flag functions with a table of score changes per move effect speeds things up considerably (we did this in voyager and I got 19 frames for a double battle with partner)

Wow, this is a huge change! Could you share with us how it looks like?

On mobile and can share more later, but basically it combines all AI calcs into a single function call like so:

s16 BattleAiCalcScore(battlerAtk, battlerDef, move, moveIndex, aiflags, score)
{
  // initialize local data struct with relevant AI info
  struct AICalcData aiData;
  aiData.battlerAtk = battlerAtk:
  //Etc

  // do some generic AI calcs/flags like doubles logic, field effects, move usability, strongest move, try to faint logic, specific ability interactions

  // finally, move effect specific check
  return sAiMoveEffectFuncs[moveEffect](&aiData, score);
}

And our table is just a table of function pointers:

static s16 (*const) sAiMoveEffectFuncs[](struct AiCalcData *idata, s16 score) = {
[MOVE_EFFECT_HIT] = sAiEffectScore_Hit,
//etc
}

And each function looks like this, having individual calcs for each ai Flag

s16 sAiEffectScore_Hit(aiData, score)
{
  if (aiData.flags & AI_CHECK_BAD_MOVE) {
    // bad move logic for this effect only
  }
  // other effect specific flag checks/calcs
}

So it's a bit cumbersome but having all the AI calcs in a single function and the jump tables speeds things along nicely. Theoretically we don't need a table of functions and could keep the switch statement to just combine CheckBadMove and CheckViability though

@ghoulslash ghoulslash merged commit 623015b into rh-hideout:upcoming Sep 13, 2023
@DizzyEggg DizzyEggg mentioned this pull request Sep 14, 2023
@AsparagusEduardo AsparagusEduardo mentioned this pull request Sep 27, 2023
@DizzyEggg DizzyEggg deleted the ai_lag_meter branch June 23, 2024 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants