diff --git a/src/ui/abstact-option-select-ui-handler.ts b/src/ui/abstact-option-select-ui-handler.ts
new file mode 100644
index 00000000000..1486351d543
--- /dev/null
+++ b/src/ui/abstact-option-select-ui-handler.ts
@@ -0,0 +1,128 @@
+import BattleScene, { Button } from "../battle-scene";
+import { TextStyle, addTextObject } from "./text";
+import { Mode } from "./ui";
+import UiHandler from "./uiHandler";
+
+export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
+  protected handlers: Function[];
+
+  protected optionSelectContainer: Phaser.GameObjects.Container;
+  protected optionSelectBg: Phaser.GameObjects.NineSlice;
+  protected optionSelectText: Phaser.GameObjects.Text;
+
+  private cursorObj: Phaser.GameObjects.Image;
+
+  constructor(scene: BattleScene, mode?: Mode) {
+    super(scene, mode);
+  }
+
+  abstract getWindowWidth(): integer;
+
+  abstract getWindowHeight(): integer;
+
+  abstract getOptions(): string[];
+
+  setup() {
+    const ui = this.getUi();
+    
+    this.optionSelectContainer = this.scene.add.container((this.scene.game.canvas.width / 6) - 1, -48);
+    this.optionSelectContainer.setVisible(false);
+    ui.add(this.optionSelectContainer);
+
+    this.optionSelectBg = this.scene.add.nineslice(0, 0, 'window', null, this.getWindowWidth(), this.getWindowHeight(), 6, 6, 6, 6);
+    this.optionSelectBg.setOrigin(1, 1);
+    this.optionSelectContainer.add(this.optionSelectBg);
+
+    this.setupOptions();
+    this.setCursor(0);
+  }
+
+  protected setupOptions() {
+    const options = this.getOptions();
+
+    if (this.optionSelectText)
+      this.optionSelectText.destroy();
+
+    this.optionSelectText = addTextObject(this.scene, 0, 0, options.join('\n'), TextStyle.WINDOW, { maxLines: options.length });
+    this.optionSelectText.setLineSpacing(12);
+    this.optionSelectContainer.add(this.optionSelectText);
+
+    this.optionSelectBg.width = Math.max(this.optionSelectText.displayWidth + 24, this.getWindowWidth());
+    this.optionSelectBg.height = this.getWindowHeight();
+
+    this.optionSelectText.setPositionRelative(this.optionSelectBg, 16, 9);
+  }
+
+  show(args: any[]) {
+    const options = this.getOptions();
+
+    if (args.length >= options.length && args.slice(0, options.length).filter(a => a instanceof Function).length === options.length) {
+      super.show(args);
+      
+      this.handlers = args.slice(0, options.length) as Function[];
+
+      this.optionSelectContainer.setVisible(true);
+      this.setCursor(0);
+    }
+  }
+
+  processInput(button: Button): boolean {
+    const ui = this.getUi();
+
+    let success = false;
+
+    const options = this.getOptions();
+
+    if (button === Button.ACTION || button === Button.CANCEL) {
+      success = true;
+      if (button === Button.CANCEL)
+        this.setCursor(options.length - 1);
+      const handler = this.handlers[this.cursor];
+      handler();
+      this.clear();
+    } else {
+      switch (button) {
+        case Button.UP:
+          if (this.cursor)
+            success = this.setCursor(this.cursor - 1);
+          break;
+        case Button.DOWN:
+          if (this.cursor < options.length - 1)
+            success = this.setCursor(this.cursor + 1);
+          break;
+      }
+    }
+
+    if (success)
+      ui.playSelect();
+
+    return success;
+  }
+
+  setCursor(cursor: integer): boolean {
+    const ret = super.setCursor(cursor);
+
+    if (!this.cursorObj) {
+      this.cursorObj = this.scene.add.image(0, 0, 'cursor');
+      this.optionSelectContainer.add(this.cursorObj);
+    }
+
+    this.cursorObj.setPositionRelative(this.optionSelectBg, 12, 17 + this.cursor * 16);
+
+    return ret;
+  }
+
+  clear() {
+    super.clear();
+    for (let h = 0; h < this.handlers.length; h++)
+      this.handlers[h] = null;
+    this.optionSelectContainer.setVisible(false);
+    this.eraseCursor();
+  }
+
+  eraseCursor() {
+    if (this.cursorObj)
+      this.cursorObj.destroy();
+    this.cursorObj = null;
+  }
+}
\ No newline at end of file
diff --git a/src/ui/confirm-ui-handler.ts b/src/ui/confirm-ui-handler.ts
index d7d9d7add30..e32b38878c4 100644
--- a/src/ui/confirm-ui-handler.ts
+++ b/src/ui/confirm-ui-handler.ts
@@ -1,8 +1,8 @@
 import BattleScene from "../battle-scene";
-import OptionSelectUiHandler from "./option-select-ui-handler";
+import AbstractOptionSelectUiHandler from "./abstact-option-select-ui-handler";
 import { Mode } from "./ui";
 
-export default class ConfirmUiHandler extends OptionSelectUiHandler {
+export default class ConfirmUiHandler extends AbstractOptionSelectUiHandler {
   private switchCheck: boolean;
   private switchCheckCursor: integer;
 
diff --git a/src/ui/game-mode-select-ui-handler.ts b/src/ui/game-mode-select-ui-handler.ts
index de7eb901a22..f5a89d23254 100644
--- a/src/ui/game-mode-select-ui-handler.ts
+++ b/src/ui/game-mode-select-ui-handler.ts
@@ -1,10 +1,10 @@
 import BattleScene, { Button } from "../battle-scene";
 import { GameMode, gameModeNames } from "../game-mode";
 import { Unlockables } from "../system/unlockables";
-import OptionSelectUiHandler from "./option-select-ui-handler";
+import AbstractOptionSelectUiHandler from "./abstact-option-select-ui-handler";
 import { Mode } from "./ui";
 
-export default class GameModeSelectUiHandler extends OptionSelectUiHandler {
+export default class GameModeSelectUiHandler extends AbstractOptionSelectUiHandler {
 
   constructor(scene: BattleScene) {
     super(scene, Mode.GAME_MODE_SELECT);
@@ -59,7 +59,7 @@ export default class GameModeSelectUiHandler extends OptionSelectUiHandler {
       ui.playSelect();
     } else
       return super.processInput(button);
-      
+
     return true;
   }
 }
\ No newline at end of file
diff --git a/src/ui/option-select-ui-handler.ts b/src/ui/option-select-ui-handler.ts
index b1a7079eecd..6642233f42f 100644
--- a/src/ui/option-select-ui-handler.ts
+++ b/src/ui/option-select-ui-handler.ts
@@ -1,127 +1,39 @@
-import BattleScene, { Button } from "../battle-scene";
-import { TextStyle, addTextObject } from "./text";
+import BattleScene from "../battle-scene";
+import AbstractOptionSelectUiHandler from "./abstact-option-select-ui-handler";
 import { Mode } from "./ui";
-import UiHandler from "./uiHandler";
 
-export default abstract class OptionSelectUiHandler extends UiHandler {
-  protected handlers: Function[];
+export default class OptionSelectUiHandler extends AbstractOptionSelectUiHandler {
+  private options: string[] = [];
 
-  protected optionSelectContainer: Phaser.GameObjects.Container;
-  protected optionSelectBg: Phaser.GameObjects.NineSlice;
-  protected optionSelectText: Phaser.GameObjects.Text;
-
-  private cursorObj: Phaser.GameObjects.Image;
-
-  constructor(scene: BattleScene, mode?: Mode) {
-    super(scene, mode);
+  constructor(scene: BattleScene) {
+    super(scene, Mode.OPTION_SELECT);
   }
 
-  abstract getWindowWidth(): integer;
-
-  abstract getWindowHeight(): integer;
-
-  abstract getOptions(): string[];
-
-  setup() {
-    const ui = this.getUi();
-    
-    this.optionSelectContainer = this.scene.add.container((this.scene.game.canvas.width / 6) - 1, -48);
-    this.optionSelectContainer.setVisible(false);
-    ui.add(this.optionSelectContainer);
-
-    this.optionSelectBg = this.scene.add.nineslice(0, 0, 'window', null, this.getWindowWidth(), this.getWindowHeight(), 6, 6, 6, 6);
-    this.optionSelectBg.setOrigin(1, 1);
-    this.optionSelectContainer.add(this.optionSelectBg);
-
-    this.setupOptions();
-    this.setCursor(0);
+  getWindowWidth(): integer {
+    return 64;
   }
 
-  protected setupOptions() {
-    const options = this.getOptions();
+  getWindowHeight(): integer {
+    return (this.getOptions().length + 1) * 16;
+  }
 
-    if (this.optionSelectText)
-      this.optionSelectText.destroy();
-
-    this.optionSelectText = addTextObject(this.scene, 0, 0, options.join('\n'), TextStyle.WINDOW, { maxLines: options.length });
-    this.optionSelectText.setPositionRelative(this.optionSelectBg, 16, 9);
-    this.optionSelectText.setLineSpacing(12);
-    this.optionSelectContainer.add(this.optionSelectText);
-
-    this.optionSelectBg.width = Math.max(this.optionSelectText.displayWidth + 24, this.getWindowWidth());
-    this.optionSelectBg.height = this.getWindowHeight();
+  getOptions(): string[] {
+    return this.options;
   }
 
   show(args: any[]) {
-    const options = this.getOptions();
+    if (args.length < 2 || args.length % 2 === 1)
+      return;
 
-    if (args.length >= options.length && args[0] instanceof Function && args[1] instanceof Function) {
-      super.show(args);
-      
-      this.handlers = args.slice(0, options.length) as Function[];
+    const optionNames: string[] = [];
+    const optionFuncs: Function[] = [];
 
-      this.optionSelectContainer.setVisible(true);
-      this.setCursor(0);
-    }
-  }
+    args.map((arg, i) => (i % 2 ? optionFuncs : optionNames).push(arg));
 
-  processInput(button: Button): boolean {
-    const ui = this.getUi();
+    this.options = optionNames;
 
-    let success = false;
+    this.setupOptions();
 
-    const options = this.getOptions();
-
-    if (button === Button.ACTION || button === Button.CANCEL) {
-      success = true;
-      if (button === Button.CANCEL)
-        this.setCursor(options.length - 1);
-      const handler = this.handlers[this.cursor];
-      handler();
-      this.clear();
-    } else {
-      switch (button) {
-        case Button.UP:
-          if (this.cursor)
-            success = this.setCursor(this.cursor - 1);
-          break;
-        case Button.DOWN:
-          if (this.cursor < options.length - 1)
-            success = this.setCursor(this.cursor + 1);
-          break;
-      }
-    }
-
-    if (success)
-      ui.playSelect();
-
-    return success;
-  }
-
-  setCursor(cursor: integer): boolean {
-    const ret = super.setCursor(cursor);
-
-    if (!this.cursorObj) {
-      this.cursorObj = this.scene.add.image(0, 0, 'cursor');
-      this.optionSelectContainer.add(this.cursorObj);
-    }
-
-    this.cursorObj.setPositionRelative(this.optionSelectBg, 12, 17 + this.cursor * 16);
-
-    return ret;
-  }
-
-  clear() {
-    super.clear();
-    for (let h = 0; h < this.handlers.length; h++)
-      this.handlers[h] = null;
-    this.optionSelectContainer.setVisible(false);
-    this.eraseCursor();
-  }
-
-  eraseCursor() {
-    if (this.cursorObj)
-      this.cursorObj.destroy();
-    this.cursorObj = null;
+    super.show(optionFuncs);
   }
 }
\ No newline at end of file
diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts
index 7d34ecf0c70..377e50c021f 100644
--- a/src/ui/starter-select-ui-handler.ts
+++ b/src/ui/starter-select-ui-handler.ts
@@ -3,7 +3,6 @@ import PokemonSpecies, { allSpecies, getPokemonSpecies } from "../data/pokemon-s
 import { Species } from "../data/species";
 import { TextStyle, addTextObject, getTextColor } from "./text";
 import { Mode } from "./ui";
-import * as Utils from "../utils";
 import MessageUiHandler from "./message-ui-handler";
 import { Gender, getGenderColor, getGenderSymbol } from "../data/gender";
 import { pokemonPrevolutions } from "../data/pokemon-evolutions";
@@ -12,6 +11,8 @@ import { GameMode } from "../game-mode";
 import { Unlockables } from "../system/unlockables";
 import { GrowthRate, getGrowthRateColor } from "../data/exp";
 import { DexAttr, DexEntry } from "../system/game-data";
+import * as Utils from "../utils";
+import { Stat, getStatName } from "../data/pokemon-stat";
 
 export type StarterSelectCallback = (starters: Starter[]) => void;
 
@@ -21,6 +22,10 @@ export interface Starter {
   pokerus: boolean;
 }
 
+const ivChartSize = 24;
+const ivChartStatCoordMultipliers = [ [ 0, 1 ], [ 0.825, 0.5 ], [ 0.825, -0.5 ], [ 0, -1 ], [ -0.825, -0.5 ], [ -0.825, 0.5 ] ];
+const defaultIvChartData = new Array(12).fill(null).map(() => 0);
+
 export default class StarterSelectUiHandler extends MessageUiHandler {
     private starterSelectContainer: Phaser.GameObjects.Container;
     private starterSelectGenIconContainers: Phaser.GameObjects.Container[];
@@ -34,8 +39,13 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
     private pokemonAbilityText: Phaser.GameObjects.Text;
     private instructionsText: Phaser.GameObjects.Text;
     private starterSelectMessageBoxContainer: Phaser.GameObjects.Container;
+    private statsContainer: Phaser.GameObjects.Container;
+    private ivChart: Phaser.GameObjects.Polygon;
+    private ivStatValueTexts: Phaser.GameObjects.Text[];
 
     private genMode: boolean;
+    private statsMode: boolean;
+    private statsIvsCache: integer[];
     private dexAttrCursor: bigint = 0n;
     private genCursor: integer = 0;
 
@@ -262,6 +272,49 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
         }
       }, 0, date.getTime().toString());
 
+      this.statsContainer = this.scene.add.container(6, 16);
+
+      const ivChartBgData = new Array(6).fill(null).map((_, i: integer) => [ ivChartSize * ivChartStatCoordMultipliers[i][0], ivChartSize * ivChartStatCoordMultipliers[i][1] ] ).flat();
+
+      const ivChartBg = this.scene.add.polygon(48, 44, ivChartBgData, 0xd8e0f0, 0.625);
+      ivChartBg.setOrigin(0, 0);
+
+      const ivChartBorder = this.scene.add.polygon(ivChartBg.x, ivChartBg.y, ivChartBgData)
+        .setStrokeStyle(1, 0x484050);
+      ivChartBorder.setOrigin(0, 0);
+
+      const ivChartBgLines = [ [ 0, -1, 0, 1 ], [ -0.825, -0.5, 0.825, 0.5 ], [ 0.825, -0.5, -0.825, 0.5 ] ].map(coords => {
+        const line = new Phaser.GameObjects.Line(this.scene, ivChartBg.x, ivChartBg.y, ivChartSize * coords[0], ivChartSize * coords[1], ivChartSize * coords[2], ivChartSize * coords[3], 0xffffff)
+          .setLineWidth(0.5);
+        line.setOrigin(0, 0);
+        return line;
+      });
+
+      this.ivChart = this.scene.add.polygon(ivChartBg.x, ivChartBg.y, defaultIvChartData, 0x98d8a0, 0.75);
+      this.ivChart.setOrigin(0, 0);
+
+      this.statsContainer.add(ivChartBg);
+      ivChartBgLines.map(l => this.statsContainer.add(l));
+      this.statsContainer.add(this.ivChart);
+      this.statsContainer.add(ivChartBorder);
+
+      this.ivStatValueTexts = [];
+
+      new Array(6).fill(null).map((_, i: integer) => {
+        const statLabel = addTextObject(this.scene, ivChartBg.x + (ivChartSize) * ivChartStatCoordMultipliers[i][0] * 1.325, ivChartBg.y + (ivChartSize) * ivChartStatCoordMultipliers[i][1] * 1.325 - 4, getStatName(i as Stat), TextStyle.TOOLTIP_CONTENT);
+        statLabel.setOrigin(0.5);
+
+        this.ivStatValueTexts[i] = addTextObject(this.scene, statLabel.x, statLabel.y + 8, '0', TextStyle.TOOLTIP_CONTENT);
+        this.ivStatValueTexts[i].setOrigin(0.5)
+
+        this.statsContainer.add(statLabel);
+        this.statsContainer.add(this.ivStatValueTexts[i]);
+      });
+
+      this.statsContainer.setVisible(false);
+
+      this.starterSelectContainer.add(this.statsContainer);
+
       this.updateInstructions();
     }
   
@@ -320,69 +373,78 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
           if (!this.speciesStarterDexEntry?.caughtAttr)
             error = true;
           else if (this.starterCursors.length < 3) {
-            let isDupe = false;
-            for (let s = 0; s < this.starterCursors.length; s++) {
-              if (this.starterGens[s] === this.genCursor && this.starterCursors[s] === this.cursor) {
-                isDupe = true;
-                break;
+            ui.setModeWithoutClear(Mode.OPTION_SELECT, 'Add to Party', () => {
+              ui.setMode(Mode.STARTER_SELECT);
+              let isDupe = false;
+              for (let s = 0; s < this.starterCursors.length; s++) {
+                if (this.starterGens[s] === this.genCursor && this.starterCursors[s] === this.cursor) {
+                  isDupe = true;
+                  break;
+                }
               }
-            }
-            if (!isDupe) {
-              const cursorObj = this.starterCursorObjs[this.starterCursors.length];
-              cursorObj.setVisible(true);
-              cursorObj.setPosition(this.cursorObj.x, this.cursorObj.y);
-              const species = this.genSpecies[this.genCursor][this.cursor];
-              const defaultDexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(species);
-              const defaultProps = this.scene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
-              this.starterIcons[this.starterCursors.length].play(species.getIconKey(defaultProps.female, defaultProps.formIndex));
-              this.starterGens.push(this.genCursor);
-              this.starterCursors.push(this.cursor);
-              this.starterAttr.push(this.dexAttrCursor);
-              if (this.speciesLoaded.get(species.speciesId))
-                species.cry(this.scene);
-              if (this.starterCursors.length === 3) {
-                const cancel = () => {
-                  ui.setMode(Mode.STARTER_SELECT);
-                  this.popStarter();
-                  this.clearText();
-                };
-                ui.showText('Begin with these Pokémon?', null, () => {
-                  ui.setModeWithoutClear(Mode.CONFIRM, () => {
-                    const startRun = (gameMode: GameMode) => {
-                      this.scene.gameMode = gameMode;
-                      ui.setMode(Mode.STARTER_SELECT);
-                      const thisObj = this;
-                      const originalStarterSelectCallback = this.starterSelectCallback;
-                      this.starterSelectCallback = null;
-                      originalStarterSelectCallback(new Array(3).fill(0).map(function (_, i) {
-                        const starterSpecies = thisObj.genSpecies[thisObj.starterGens[i]][thisObj.starterCursors[i]];
-                        return {
-                          species: starterSpecies,
-                          dexAttr: thisObj.starterAttr[i],
-                          pokerus: !![ 0, 1, 2 ].filter(n => thisObj.pokerusGens[n] === starterSpecies.generation - 1 && thisObj.pokerusCursors[n] === thisObj.genSpecies[starterSpecies.generation - 1].indexOf(starterSpecies)).length
-                        };
-                      }));
-                    };
-                    if (this.scene.gameData.unlocks[Unlockables.ENDLESS_MODE]) {
-                      ui.setMode(Mode.STARTER_SELECT);
-                      ui.showText('Select a game mode.', null, () => ui.setModeWithoutClear(Mode.GAME_MODE_SELECT, startRun, cancel));
-                    } else
-                      startRun(GameMode.CLASSIC);
-                  }, cancel);
-                });
-              }
-              success = true;
-              this.updateInstructions();
-            } else
-              error = true;
+              if (!isDupe) {
+                const cursorObj = this.starterCursorObjs[this.starterCursors.length];
+                cursorObj.setVisible(true);
+                cursorObj.setPosition(this.cursorObj.x, this.cursorObj.y);
+                const species = this.genSpecies[this.genCursor][this.cursor];
+                const defaultDexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(species);
+                const defaultProps = this.scene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
+                this.starterIcons[this.starterCursors.length].play(species.getIconKey(defaultProps.female, defaultProps.formIndex));
+                this.starterGens.push(this.genCursor);
+                this.starterCursors.push(this.cursor);
+                this.starterAttr.push(this.dexAttrCursor);
+                if (this.speciesLoaded.get(species.speciesId))
+                  species.cry(this.scene);
+                if (this.starterCursors.length === 3) {
+                  const cancel = () => {
+                    ui.setMode(Mode.STARTER_SELECT);
+                    this.popStarter();
+                    this.clearText();
+                  };
+                  ui.showText('Begin with these Pokémon?', null, () => {
+                    ui.setModeWithoutClear(Mode.CONFIRM, () => {
+                      const startRun = (gameMode: GameMode) => {
+                        this.scene.gameMode = gameMode;
+                        ui.setMode(Mode.STARTER_SELECT);
+                        const thisObj = this;
+                        const originalStarterSelectCallback = this.starterSelectCallback;
+                        this.starterSelectCallback = null;
+                        originalStarterSelectCallback(new Array(3).fill(0).map(function (_, i) {
+                          const starterSpecies = thisObj.genSpecies[thisObj.starterGens[i]][thisObj.starterCursors[i]];
+                          return {
+                            species: starterSpecies,
+                            dexAttr: thisObj.starterAttr[i],
+                            pokerus: !![ 0, 1, 2 ].filter(n => thisObj.pokerusGens[n] === starterSpecies.generation - 1 && thisObj.pokerusCursors[n] === thisObj.genSpecies[starterSpecies.generation - 1].indexOf(starterSpecies)).length
+                          };
+                        }));
+                      };
+                      if (this.scene.gameData.unlocks[Unlockables.ENDLESS_MODE]) {
+                        ui.setMode(Mode.STARTER_SELECT);
+                        ui.showText('Select a game mode.', null, () => ui.setModeWithoutClear(Mode.GAME_MODE_SELECT, startRun, cancel));
+                      } else
+                        startRun(GameMode.CLASSIC);
+                    }, cancel);
+                  });
+                }
+                this.updateInstructions();
+                ui.playSelect();
+              } else
+                ui.playError();
+            }, 'Toggle IVs', () => {
+              this.toggleStatsMode();
+              ui.setMode(Mode.STARTER_SELECT);
+            });
+            success = true;
           }
         } else if (button === Button.CANCEL) {
-          if (this.starterCursors.length) {
+          if (this.statsMode) {
+            this.toggleStatsMode(false);
+            success = true;
+          } else if (this.starterCursors.length) {
             this.popStarter();
             success = true;
             this.updateInstructions();
-          } else
-            error = true;
+          }
         } else {
           const genStarters = this.starterSelectGenIconContainers[this.genCursor].getAll().length;
           const rows = Math.ceil(genStarters / 9);
@@ -556,6 +618,16 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
       this.speciesStarterDexEntry = species ? this.scene.gameData.dexData[species.speciesId] : null;
       this.dexAttrCursor = species ? this.scene.gameData.getSpeciesDefaultDexAttr(species) : 0n;
 
+      if (this.statsMode) {
+        if (this.speciesStarterDexEntry?.caughtAttr) {
+          this.statsContainer.setVisible(true);
+          this.showStats();
+        } else {
+          this.statsContainer.setVisible(false);
+          this.ivChart.setTo((this.statsIvsCache = defaultIvChartData));
+        }
+      }
+
       if (this.lastSpecies) {
         const dexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(this.lastSpecies);
         const props = this.scene.gameData.getSpeciesDexAttrProps(this.lastSpecies, dexAttr);
@@ -631,7 +703,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
             this.assetLoadCancelled = null;
             this.speciesLoaded.set(species.speciesId, true);
             this.pokemonSprite.play(species.getSpriteKey(female, formIndex, shiny));
-            this.pokemonSprite.setVisible(true);
+            this.pokemonSprite.setVisible(!this.statsMode);
           });
 
           species.generateIconAnim(this.scene, female, formIndex);
@@ -676,6 +748,47 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
       this.starterIcons[this.starterCursors.length].play('pkmn_icon__000');
     }
 
+    toggleStatsMode(on?: boolean): void {
+      if (on === undefined)
+        on = !this.statsMode;
+      if (on) {
+        this.showStats();
+        this.statsMode = true;
+        this.pokemonSprite.setVisible(false);
+      } else {
+        this.statsMode = false;
+        this.statsContainer.setVisible(false);
+        this.pokemonSprite.setVisible(!!this.speciesStarterDexEntry?.caughtAttr);
+        this.ivChart.setTo((this.statsIvsCache = defaultIvChartData));
+      }
+    }
+    
+    showStats(): void {
+      if (!this.speciesStarterDexEntry)
+        return;
+
+      this.statsContainer.setVisible(true);
+
+      const ivs = this.speciesStarterDexEntry.ivs;
+      const ivChartData = new Array(6).fill(null).map((_, i) => [ (ivs[i] / 31) * ivChartSize * ivChartStatCoordMultipliers[i][0], (ivs[i] / 31) * ivChartSize * ivChartStatCoordMultipliers[i][1] ] ).flat();
+      const lastIvChartData = this.statsIvsCache || defaultIvChartData;
+      this.statsIvsCache = ivChartData.slice(0);
+      
+      this.ivStatValueTexts.map((t: Phaser.GameObjects.Text, i: integer) => t.setText(ivs[i].toString()));
+
+      this.scene.tweens.addCounter({
+        from: 0,
+        to: 1,
+        duration: 1000,
+        ease: 'Cubic.easeOut',
+        onUpdate: (tween: Phaser.Tweens.Tween) => {
+          const progress = tween.getValue();
+          const interpolatedData = ivChartData.map((v: number, i: integer) => v * progress + (lastIvChartData[i] * (1 - progress)));
+          this.ivChart.setTo(interpolatedData);
+        }
+      });
+    }
+
     clearText() {
       this.starterSelectMessageBoxContainer.setVisible(false);
       super.clearText();
@@ -688,5 +801,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
 
       while (this.starterCursors.length)
         this.popStarter();
+
+      if (this.statsMode)
+        this.toggleStatsMode(false);
     }
   }  
\ No newline at end of file
diff --git a/src/ui/ui.ts b/src/ui/ui.ts
index c6296718dd4..5480972c154 100644
--- a/src/ui/ui.ts
+++ b/src/ui/ui.ts
@@ -19,6 +19,7 @@ import { TextStyle, addTextObject } from './text';
 import AchvBar from './achv-bar';
 import MenuUiHandler from './menu-ui-handler';
 import AchvsUiHandler from './achvs-ui-handler';
+import OptionSelectUiHandler from './option-select-ui-handler';
 
 export enum Mode {
   MESSAGE,
@@ -33,6 +34,7 @@ export enum Mode {
   STARTER_SELECT,
   EVOLUTION_SCENE,
   CONFIRM,
+  OPTION_SELECT,
   GAME_MODE_SELECT,
   MENU,
   SETTINGS,
@@ -48,6 +50,7 @@ const transitionModes = [
 
 const noTransitionModes = [
   Mode.CONFIRM,
+  Mode.OPTION_SELECT,
   Mode.GAME_MODE_SELECT,
   Mode.MENU,
   Mode.SETTINGS
@@ -85,6 +88,7 @@ export default class UI extends Phaser.GameObjects.Container {
       new StarterSelectUiHandler(scene),
       new EvolutionSceneHandler(scene),
       new ConfirmUiHandler(scene),
+      new OptionSelectUiHandler(scene),
       new GameModeSelectUiHandler(scene),
       new MenuUiHandler(scene),
       new SettingsUiHandler(scene),