Alatreon AI Observations

Based on the em050_00 and em050_55 files provided alongside juzzi's recent video.

I've been putting some effort into making these files more human-readable by renaming nodes according to their likely purpose. So far, I've focused on the logic that determines when element changes and flying phases occur. I have added snippets of Leviathon code to provide context for claims I make, but the surrounding explanation should be self-contained, so feel free to skip them if you like.

General

Surprisingly, there don't seem to be any time-based mechanics in the fight; instead, progression is measured in terms of attack combos. I might explore the structure of these combos more later, for now just think of them as random sequences of maybe one to three attacks. Ahead of every attack combo, the AI first performs a check to see whether Alatreon should change to dragon or start an EJ, followed by a check to see whether Alatreon should land or take off.

def node_003
  >> Global.N195__element_change_check
  >> Global.node_359 // search, repositioning and special cases?
  >> Global.N202__flying_check
  if self.flying()
    >> Global.N008__aerial_combo
  else
    >> Global.N005__ground_combo
  endif
  >> N004__keep_current_target_check
  if [KeepCurrentTarget > 0]
    repeat
  endif
  return
endf

Each check has a counter that keeps track of how many times the check has been performed. Once the checks reach certain thresholds, Alatreon will take off, land or change its active element. These counters reset after an element change, whether from fire/ice to dragon or from dragon back to fire/ice through EJ.

def N197__change_active_element
  if function#101(3) // if active element is dragon
    >> N001__force_landing
    if function#52(0,2) // ?
      self.targetArea(target_area.nearest_entrance)
      >> N198__dash_no_interrupt__if_distance_3d_above_750__loop_5_times
    else
    endif
    [NumEscatonJudgments ++]
    if function#104() // if initial element of current cycle is fire
      if function#102() // if horn break occured
        >> N199__elemental_explosion_to_fire
      else
        >> N200__elemental_explosion_to_ice
      endif
    else
      if function#102() // if horn break occured
        >> N200__elemental_explosion_to_ice
      else
        >> N199__elemental_explosion_to_fire
      endif
    endif
  else
    >> N201__change_to_dragon
  endif
  [NumElementChangeChecks |-]
  [NumAerialCombos |-]
  [NumGroundCombos |-]
  return
endf

Element Changes

Ignoring health-based triggers for now, Alatreon will change elements after 14 element change checks during the first EJ cycle, after 12 checks on the second cycle, or after 10 checks on the third and later cycles. As the time between element changes decreases after the first and second EJ, in that sense getting topples/horn breaks becomes harder as the fight goes on.

def N195__element_change_check
  if self.flying()
  else
    [NumElementChangeChecks ++]
    >> N196__element_change_health_check
    if [NumEscatonJudgments == 0]
      if [NumElementChangeChecks >= 15]
        >> N197__change_active_element
        reset
      endif
    elif [NumEscatonJudgments == 1]
      if [NumElementChangeChecks >= 13]
        >> N197__change_active_element
        reset
      endif
    else
      if [NumElementChangeChecks >= 11]
        >> N197__change_active_element
        reset
      endif
    endif
  endif
  return
endf

Because the element change check is skipped while Alatreon is flying, aerial combos don't increment the check counter. In other words, the element check counter just counts the number of ground combos started. Time Alatreon spends flying is "extra", it doesn't eat into the time it spends on the ground between element changes. For the purpose of counting element checks, the take-off moves each count as a ground combo, because Alatreon's AI first increments the check counter and then picks a take-off move instead of a ground combo.

There are also health-based triggers for element changes, but only on the first EJ cycle. In this case, the threshold for starting EJ is reduced to 8 checks if Alatreon's hp is at or below 20%, and the threshold for switching from fire/ice to dragon is reduced to 3 checks if Alatreon's hp is at or below 55%.

def N196__element_change_health_check
  if function#101(3) // if active element is dragon
    if [NumEscatonJudgments == 0]
      if self.hp_percent().leq(20)
        if [NumElementChangeChecks >= 9]
          >> N197__change_active_element
          reset
        endif
      endif
    endif
  else
    if [NumEscatonJudgments == 0]
      if self.hp_percent().leq(55)
        if [NumElementChangeChecks >= 4]
          >> N197__change_active_element
          reset
        endif
      endif
    endif
  endif
  return
endf

This explains why Dawn's Triumph's Alatreon can change to dragon very quickly after just 3 ground combos in fire mode, while staying in dragon for at least 7 ground combos (remembering that one ground combo is "lost" to the dragonflight take-off move), plus the dragonflight phase which does not contribute to the counter. Again, these health-based triggers only apply on the first EJ cycle, so for inexperienced players attempting full health Alatreon or experienced players attempting no-armor runs, they are irrelevant.

Flying Phases

Alatreon will start flying after 11 ground combos in fire/ice mode, and after just 3 ground combos in dragon mode.

def N202__flying_check
  if self.flying()
    // ...
  else
    [NumGroundCombos ++]
    if [NumAerialCombos > 0]
    else
      if function#101(3) // if active element is dragon
        if [NumGroundCombos >= 4]
          >> N204__transition_ground_to_aerial
          reset
        endif
      else
        if [NumGroundCombos >= 12]
          >> N204__transition_ground_to_aerial
          reset
        endif
      endif
    endif
  endif
  return
endf

def N204__transition_ground_to_aerial
  if function#101(1) // if active element is fire
    >> N122__back_step_fire_breath_to_fly
  elif function#101(2) // if active element is ice
    >> N132__ice_meteor
  else
    if function#104() // if initial element of current cycle is fire
      >> N132__ice_meteor
    else
      >> N122__back_step_fire_breath_to_fly
    endif
  endif
  return
endf

This explains why fire-/iceflight is skippable, but dragonflight is not: In fire/ice mode, if the 55% health threshold is reached within the first 11 ground combos, Alatreon will change to dragon before it starts flying. In dragon mode, the 9 check threshold for EJ will never take precedence over the 4 check threshold to start flying. Another interesting consequence is that fire-/iceflight never occurs after the second EJ, no matter how much remaining health Alatreon has.

As for how long Alatreon stays flying, it's a bit weird: usually, it will land after 5 aerial combos, yet during the second EJ cycle only (after first EJ but before second EJ), it will land after just 3 aerial combos.

def N202__flying_check
  if self.flying()
    [NumAerialCombos ++]
    >> N203__health_landing_check
    if [NumEscatonJudgments == 1]
      if [NumAerialCombos == 4]
        >> N205__transition_aerial_to_ground
        reset
      elif [NumAerialCombos > 4]
        >> N206__quick_transition_aerial_to_ground
        reset
      endif
    else
      if [NumAerialCombos == 6]
        >> N205__transition_aerial_to_ground
        reset
      elif [NumAerialCombos > 6]
        >> N206__quick_transition_aerial_to_ground
        reset
      endif
    endif
  else
    // ...
  endif
  return
endf

def N205__transition_aerial_to_ground
  if function#101(1) // if active element is fire
    >> N175__hot_blast
  elif function#101(2) // if active element is ice
    >> N165__rush_fly_to_ground
  else
    if function#104() // if initial element of current cycle is fire
      >> N165__rush_fly_to_ground
    else
      >> N175__hot_blast
    endif
  endif
  return
endf

However, there are again health-based landing triggers that only apply to the first EJ cycle: It will land after just 1 aerial combo at the same thresholds as above; 55% for fire/ice and 20% for dragon.

def N203__health_landing_check
  if self.flying()
    if [NumEscatonJudgments == 0]
      if [NumAerialCombos == 2]
        if function#101(3) // if active element is dragon
          if self.hp_percent().leq(20)
            >> N205__transition_aerial_to_ground
            reset
          endif
        else
          if self.hp_percent().leq(55)
            >> N205__transition_aerial_to_ground
            reset
          endif
        endif
      elif [NumAerialCombos > 2]
        if function#101(3) // if active element is dragon
          if self.hp_percent().leq(20)
            >> N206__quick_transition_aerial_to_ground
            reset
          endif
        else
          if self.hp_percent().leq(55)
            >> N206__quick_transition_aerial_to_ground
            reset
          endif
        endif
      endif
    endif
  endif
  return
endf

def N206__quick_transition_aerial_to_ground
  >> N165__rush_fly_to_ground
  return
endf

While the landing move usually depends on the active element (the downward "hot blast" fire breath for fire, the "rush fly to ground" dive for ice), if Alatreon has performed at least 2 aerial combos when the health threshold landing triggers, it will unconditionally choose the faster rush to ground.

As an interesting bonus fact, there seems to be logic for a mid-air fire/ice to dragon shift, but it never comes into play because the element change check is only performed while Alatreon is on the ground.

1
2
3
4
5
6
7
8
9
def N201__change_to_dragon
  if self.flying()
    -> alatreon.mode_change_to_dragon_fly()
  else
    -> alatreon.mode_change_to_dragon_ground()
  endif
  >> node_103
  return
endf

Summary

If the health-based triggers don't come into play, an Alatreon fight should progress like this (in terms of attack combos):

1
2
3
4
1. 11x ground -> 5x aerial -> 2x ground -> dragon switch -> 3x ground -> 5x aerial -> 10x ground -> EJ
2. 11x ground -> 3x aerial --------------> dragon switch -> 3x ground -> 3x aerial ->  8x ground -> EJ
3. 10x ground ---------------------------> dragon switch -> 3x ground -> 5x aerial ->  6x ground -> EJ
repeat cycle 3

The 55% health threshold can cut the first fire/ice phase short, either after at least 3 ground combos, or forcing an early landing after at least 1 aerial combo into an instant dragon switch. The 20% health threshold can cut the first dragon phase short, however Alatreon will always fly and perform at least 1 aerial combo, and the landing will always be followed by at least 4 more ground combos before EJ. Phases after the first EJ are unaffected by health thresholds.

by noderoo

Edit

Pub: 26 Mar 2024 11:41 UTC

Edit: 26 Mar 2024 15:50 UTC

Views: 478