diff --git a/packages/tosu/src/api/types/v2.ts b/packages/tosu/src/api/types/v2.ts
index dc8fcfda..9855c76f 100644
--- a/packages/tosu/src/api/types/v2.ts
+++ b/packages/tosu/src/api/types/v2.ts
@@ -368,6 +368,10 @@ export interface Pp {
     fc: number;
     maxAchievedThisPlay: number;
 }
+export interface Pp2 {
+    current: number;
+    fc: number;
+}
 
 export interface Leaderboard {
     isFailed: boolean;
@@ -438,6 +442,7 @@ export interface Series {
 }
 
 export interface ResultsScreen {
+    playerName: string;
     mode: NumberName;
     score: number;
     accuracy: number;
@@ -446,6 +451,7 @@ export interface ResultsScreen {
     mods: NumberName;
     maxCombo: number;
     rank: string;
+    pp: Pp2;
     createdAt: string;
 }
 
diff --git a/packages/tosu/src/api/utils/buildResultV2.ts b/packages/tosu/src/api/utils/buildResultV2.ts
index 3f4275e9..62638b54 100644
--- a/packages/tosu/src/api/utils/buildResultV2.ts
+++ b/packages/tosu/src/api/utils/buildResultV2.ts
@@ -389,18 +389,17 @@ export const buildResult = (instanceManager: InstanceManager): ApiAnswer => {
             graph: beatmapPpData.strainsAll
         },
         resultsScreen: {
+            playerName: resultsScreenData.PlayerName,
+
             mode: {
-                number: gamePlayData.Mode,
-                name: Modes[gamePlayData.Mode] || ''
+                number: resultsScreenData.Mode,
+                name: Modes[resultsScreenData.Mode] || ''
             },
 
             score: resultsScreenData.Score,
-            accuracy: calculateAccuracy({
-                hits: resultScreenHits,
-                mode: gamePlayData.Mode
-            }),
+            accuracy: resultsScreenData.Accuracy,
 
-            name: resultsScreenData.PlayerName,
+            name: resultsScreenData.PlayerName, // legacy, remove it later
             hits: resultScreenHits,
             mods: {
                 number: resultsScreenData.Mods,
@@ -408,6 +407,10 @@ export const buildResult = (instanceManager: InstanceManager): ApiAnswer => {
             },
             maxCombo: resultsScreenData.MaxCombo,
             rank: resultsScreenData.Grade,
+            pp: {
+                current: resultsScreenData.pp,
+                fc: resultsScreenData.fcPP
+            },
             createdAt: resultsScreenData.Date
         },
         folders: {
diff --git a/packages/tosu/src/entities/ResultsScreenData/index.ts b/packages/tosu/src/entities/ResultsScreenData/index.ts
index 1b79e419..ebf02f48 100644
--- a/packages/tosu/src/entities/ResultsScreenData/index.ts
+++ b/packages/tosu/src/entities/ResultsScreenData/index.ts
@@ -1,8 +1,13 @@
+import { Calculator } from '@kotrikd/rosu-pp';
 import { wLogger } from '@tosu/common';
 
 import { AbstractEntity } from '@/entities/AbstractEntity';
 import { OsuInstance } from '@/objects/instanceManager/osuInstance';
-import { calculateGrade } from '@/utils/calculators';
+import {
+    calculateAccuracy,
+    calculateGrade,
+    calculatePassedObjects
+} from '@/utils/calculators';
 import { netDateBinaryToDate } from '@/utils/converters';
 import { OsuMods } from '@/utils/osuMods.types';
 
@@ -20,6 +25,11 @@ export class ResultsScreenData extends AbstractEntity {
     HitMiss: number;
     Grade: string;
     Date: string;
+    Accuracy: number;
+    pp: number;
+    fcPP: number;
+
+    previousBeatmap: string;
 
     constructor(osuInstance: OsuInstance) {
         super(osuInstance);
@@ -42,15 +52,20 @@ export class ResultsScreenData extends AbstractEntity {
         this.HitKatu = 0;
         this.HitMiss = 0;
         this.Date = '';
+        this.Accuracy = 0;
+        this.pp = 0;
+        this.fcPP = 0;
     }
 
     updateState() {
         try {
-            const { process, patterns, allTimesData } =
+            const { process, patterns, allTimesData, beatmapPpData, menuData } =
                 this.osuInstance.getServices([
                     'process',
                     'patterns',
-                    'allTimesData'
+                    'allTimesData',
+                    'beatmapPpData',
+                    'menuData'
                 ]);
             if (process === null) {
                 throw new Error('Process not found');
@@ -68,13 +83,13 @@ export class ResultsScreenData extends AbstractEntity {
                 process.readInt(rulesetsAddr - 0xb) + 0x4
             );
             if (rulesetAddr === 0) {
-                wLogger.debug('RSD(init) rulesetAddr is zero');
+                wLogger.debug('RSD(updateState) rulesetAddr is zero');
                 return;
             }
 
             const resultScreenBase = process.readInt(rulesetAddr + 0x38);
             if (resultScreenBase === 0) {
-                wLogger.debug('RSD(init) resultScreenBase is zero');
+                wLogger.debug('RSD(updateState) resultScreenBase is zero');
                 return;
             }
 
@@ -106,17 +121,25 @@ export class ResultsScreenData extends AbstractEntity {
             this.HitKatu = process.readShort(resultScreenBase + 0x90);
             // HitMiss    int16   `mem:"[Ruleset + 0x38] + 0x92"`
             this.HitMiss = process.readShort(resultScreenBase + 0x92);
+
+            const hits = {
+                300: this.Hit300,
+                geki: 0,
+                100: this.Hit100,
+                katu: 0,
+                50: this.Hit50,
+                0: this.HitMiss
+            };
+
             this.Grade = calculateGrade({
                 mods: this.Mods,
                 mode: this.Mode,
-                hits: {
-                    300: this.Hit300,
-                    geki: 0,
-                    100: this.Hit100,
-                    katu: 0,
-                    50: this.Hit50,
-                    0: this.HitMiss
-                }
+                hits
+            });
+
+            this.Accuracy = calculateAccuracy({
+                mode: this.Mode,
+                hits
             });
 
             this.Date = netDateBinaryToDate(
@@ -124,6 +147,49 @@ export class ResultsScreenData extends AbstractEntity {
                 process.readInt(resultScreenBase + 0xa0)
             ).toISOString();
 
+            const key = `${menuData.MD5}${this.Mods}${this.Mode}${this.PlayerName}`;
+            if (this.previousBeatmap === key) {
+                return;
+            }
+
+            const currentBeatmap = beatmapPpData.getCurrentBeatmap();
+            if (!currentBeatmap) {
+                wLogger.debug("RSD(updateState) can't get current map");
+                return;
+            }
+
+            const scoreParams = {
+                passedObjects: calculatePassedObjects(
+                    this.Mode,
+                    this.Hit300,
+                    this.Hit100,
+                    this.Hit50,
+                    this.HitMiss,
+                    this.HitKatu,
+                    this.HitGeki
+                ),
+                combo: this.MaxCombo,
+                mods: this.Mods,
+                nMisses: this.HitMiss,
+                n50: this.Hit50,
+                n100: this.Hit100,
+                n300: this.Hit300
+            };
+
+            const curPerformance = new Calculator(scoreParams).performance(
+                currentBeatmap
+            );
+            const fcPerformance = new Calculator({
+                combo: curPerformance.difficulty.maxCombo,
+                mods: this.Mods,
+                nMisses: 0,
+                acc: this.Accuracy
+            }).performance(currentBeatmap);
+
+            this.pp = curPerformance.pp;
+            this.fcPP = fcPerformance.pp;
+
+            this.previousBeatmap = key;
             this.resetReportCount('RSD(updateState)');
         } catch (exc) {
             this.reportError(
diff --git a/packages/tosu/src/objects/instanceManager/osuInstance.ts b/packages/tosu/src/objects/instanceManager/osuInstance.ts
index e1f0706a..93d3724c 100644
--- a/packages/tosu/src/objects/instanceManager/osuInstance.ts
+++ b/packages/tosu/src/objects/instanceManager/osuInstance.ts
@@ -299,6 +299,11 @@ export class OsuInstance {
                             resultsScreenData.init();
                             beatmapPpData.resetCurrentAttributes();
                         }
+
+                        // Reset ResultScreen if we in song select
+                        if (resultsScreenData.PlayerName) {
+                            resultsScreenData.init();
+                        }
                         break;
 
                     case 2: