diff --git a/Assets/Materials/Star.png b/Assets/Materials/Star.png
new file mode 100644
index 0000000000000000000000000000000000000000..124822a14bc41b997d135f8d9c48d6ea5a687d6a
--- /dev/null
+++ b/Assets/Materials/Star.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:34ecbda60b006fc11f5a89226d61f92d9eaba8a5b6ba3759a91a217cd9a3c0ef
+size 1112824
diff --git a/Assets/Materials/Star.png.meta b/Assets/Materials/Star.png.meta
new file mode 100644
index 0000000000000000000000000000000000000000..c5800a216b6991a6d878be46760c6814efcf5494
--- /dev/null
+++ b/Assets/Materials/Star.png.meta
@@ -0,0 +1,120 @@
+fileFormatVersion: 2
+guid: c4ceb1587b633354ab111cd5d87044df
+TextureImporter:
+  internalIDToNameTable: []
+  externalObjects: {}
+  serializedVersion: 11
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    sRGBTexture: 1
+    linearTexture: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapsPreserveCoverage: 0
+    alphaTestReferenceValue: 0.5
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: 0.25
+    normalMapFilter: 0
+  isReadable: 0
+  streamingMipmaps: 0
+  streamingMipmapsPriority: 0
+  vTOnly: 0
+  grayScaleToAlpha: 0
+  generateCubemap: 6
+  cubemapConvolution: 0
+  seamlessCubemap: 0
+  textureFormat: 1
+  maxTextureSize: 2048
+  textureSettings:
+    serializedVersion: 2
+    filterMode: 1
+    aniso: 1
+    mipBias: 0
+    wrapU: 1
+    wrapV: 1
+    wrapW: 0
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 1
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: 0.5, y: 0.5}
+  spritePixelsToUnits: 100
+  spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+  spriteGenerateFallbackPhysicsShape: 1
+  alphaUsage: 1
+  alphaIsTransparency: 1
+  spriteTessellationDetail: -1
+  textureType: 8
+  textureShape: 1
+  singleChannelComponent: 0
+  flipbookRows: 1
+  flipbookColumns: 1
+  maxTextureSizeSet: 0
+  compressionQualitySet: 0
+  textureFormatSet: 0
+  ignorePngGamma: 0
+  applyGammaDecoding: 0
+  platformSettings:
+  - serializedVersion: 3
+    buildTarget: DefaultTexturePlatform
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  - serializedVersion: 3
+    buildTarget: Standalone
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  - serializedVersion: 3
+    buildTarget: WebGL
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  spriteSheet:
+    serializedVersion: 2
+    sprites: []
+    outline: []
+    physicsShape: []
+    bones: []
+    spriteID: 5e97eb03825dee720800000000000000
+    internalID: 0
+    vertices: []
+    indices: 
+    edges: []
+    weights: []
+    secondaryTextures: []
+  spritePackingTag: 
+  pSDRemoveMatte: 0
+  pSDShowRemoveMatteOption: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scenes/Main_Menu.unity b/Assets/Scenes/Main_Menu.unity
index 891f42c778d21cfe5a5323f886a3c83648c4b884..f14e92f2382d3e6359a6fc3754ca6fa3c8173730 100644
--- a/Assets/Scenes/Main_Menu.unity
+++ b/Assets/Scenes/Main_Menu.unity
@@ -1198,18 +1198,20 @@ RectTransform:
   m_LocalPosition: {x: 0, y: 0, z: 0}
   m_LocalScale: {x: 1, y: 1, z: 1}
   m_Children:
+  - {fileID: 1309968695}
   - {fileID: 2063570489}
   - {fileID: 2117995410}
   - {fileID: 1280026351}
   - {fileID: 2134235715}
+  - {fileID: 1584547855}
   m_Father: {fileID: 1339590799}
   m_RootOrder: 0
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 0.5, y: 0.5}
   m_AnchorMax: {x: 0.5, y: 0.5}
-  m_AnchoredPosition: {x: 3, y: -2}
+  m_AnchoredPosition: {x: 0, y: -2}
   m_SizeDelta: {x: 100, y: 100}
-  m_Pivot: {x: -0.2, y: 0.8}
+  m_Pivot: {x: -0.23, y: 0.8}
 --- !u!1 &451601672
 GameObject:
   m_ObjectHideFlags: 0
@@ -3384,7 +3386,7 @@ RectTransform:
   m_LocalScale: {x: 1, y: 1, z: 1}
   m_Children: []
   m_Father: {fileID: 443158127}
-  m_RootOrder: 2
+  m_RootOrder: 3
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 0.5, y: 0.5}
   m_AnchorMax: {x: 0.5, y: 0.5}
@@ -3516,17 +3518,17 @@ MonoBehaviour:
   m_OnClick:
     m_PersistentCalls:
       m_Calls:
-      - m_Target: {fileID: 952847394}
-        m_TargetAssemblyTypeName: MainMenu, Assembly-CSharp
-        m_MethodName: PlayGame
-        m_Mode: 1
+      - m_Target: {fileID: 654873303}
+        m_TargetAssemblyTypeName: UnityEngine.GameObject, UnityEngine
+        m_MethodName: SetActive
+        m_Mode: 6
         m_Arguments:
           m_ObjectArgument: {fileID: 0}
           m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
           m_IntArgument: 0
           m_FloatArgument: 0
           m_StringArgument: 
-          m_BoolArgument: 0
+          m_BoolArgument: 1
         m_CallState: 2
 --- !u!114 &1289507568
 MonoBehaviour:
@@ -3699,6 +3701,81 @@ CanvasRenderer:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 1298821070}
   m_CullTransparentMesh: 1
+--- !u!1 &1309968694
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1309968695}
+  - component: {fileID: 1309968697}
+  - component: {fileID: 1309968696}
+  m_Layer: 5
+  m_Name: Background
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1309968695
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1309968694}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 443158127}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: -73, y: 53.4}
+  m_SizeDelta: {x: 600, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1309968696
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1309968694}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.13336597, g: 0.29615134, b: 0.3490566, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 0}
+  m_Type: 0
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!222 &1309968697
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1309968694}
+  m_CullTransparentMesh: 1
 --- !u!1 &1339590798
 GameObject:
   m_ObjectHideFlags: 0
@@ -3822,6 +3899,81 @@ RectTransform:
   m_AnchoredPosition: {x: 0, y: 37}
   m_SizeDelta: {x: 100, y: 100}
   m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &1584547854
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1584547855}
+  - component: {fileID: 1584547857}
+  - component: {fileID: 1584547856}
+  m_Layer: 5
+  m_Name: Star
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1584547855
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1584547854}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 443158127}
+  m_RootOrder: 5
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: -329.2, y: 53.6}
+  m_SizeDelta: {x: 28, y: 28}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1584547856
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1584547854}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.8773585, g: 0.5894473, b: 0.38487893, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 21300000, guid: c4ceb1587b633354ab111cd5d87044df, type: 3}
+  m_Type: 0
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!222 &1584547857
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1584547854}
+  m_CullTransparentMesh: 1
 --- !u!1 &1632776586
 GameObject:
   m_ObjectHideFlags: 0
@@ -4861,7 +5013,7 @@ RectTransform:
   m_LocalScale: {x: 1, y: 1, z: 1}
   m_Children: []
   m_Father: {fileID: 443158127}
-  m_RootOrder: 0
+  m_RootOrder: 1
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 0.5, y: 0.5}
   m_AnchorMax: {x: 0.5, y: 0.5}
@@ -5075,7 +5227,7 @@ RectTransform:
   m_LocalScale: {x: 1, y: 1, z: 1}
   m_Children: []
   m_Father: {fileID: 443158127}
-  m_RootOrder: 1
+  m_RootOrder: 2
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 0.5, y: 0.5}
   m_AnchorMax: {x: 0.5, y: 0.5}
@@ -5154,7 +5306,7 @@ RectTransform:
   m_LocalScale: {x: 1, y: 1, z: 1}
   m_Children: []
   m_Father: {fileID: 443158127}
-  m_RootOrder: 3
+  m_RootOrder: 4
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 0.5, y: 0.5}
   m_AnchorMax: {x: 0.5, y: 0.5}
diff --git a/Assets/Scripts/WaveMode/WaveScoreboard.cs b/Assets/Scripts/WaveMode/WaveScoreboard.cs
index 59daf3f7944dc98df39bd8244c94bd5f4f7ac9b9..bdfe50b887e9a19aa4d82fa43b1f7309e1a99eb0 100644
--- a/Assets/Scripts/WaveMode/WaveScoreboard.cs
+++ b/Assets/Scripts/WaveMode/WaveScoreboard.cs
@@ -1,11 +1,14 @@
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
+using UnityEngine.UI;
 
 public class WaveScoreboard : MonoBehaviour
 {
     private Transform entryContainer;
     private Transform entryTemplate;
+    private List<Transform> scoreEntryTransformList;
+
     private void Awake()
     {
         Debug.Log("WaveScoreboard awake called");
@@ -14,14 +17,137 @@ public class WaveScoreboard : MonoBehaviour
 
         entryTemplate.gameObject.SetActive(false);
 
+        // test add new entry
+        // AddScoreEntry(10000, 14, "Haha");
+
+        string jsonString = PlayerPrefs.GetString("scoreTable");
+        Scores scores = JsonUtility.FromJson<Scores>(jsonString);
+
+        // sort entry list by score
+        for (int i = 0; i < scores.scoreEntryList.Count; i++)
+        {
+            for (int j = i+1; j < scores.scoreEntryList.Count; j++)
+            {
+                if (scores.scoreEntryList[j].score > scores.scoreEntryList[i].score)
+                {
+                    // swap
+                    ScoreEntry temp = scores.scoreEntryList[i];
+                    scores.scoreEntryList[i] = scores.scoreEntryList[j];
+                    scores.scoreEntryList[j] = temp;
+                }
+            }
+        }
+
+        scoreEntryTransformList = new List<Transform>();
+        foreach (ScoreEntry scoreEntry in scores.scoreEntryList)
+        {
+            CreateScoreEntryTransform(scoreEntry, entryContainer, scoreEntryTransformList);
+        }
+
+        // Debug.Log(PlayerPrefs.GetString("scoreTable"));
+    }
+
+    private void CreateScoreEntryTransform(ScoreEntry scoreEntry, Transform container, List<Transform> transformList)
+    {
         float templateHeight = 30f;
-        for (int i=0; i<5; i++)
+        Transform entryTransform = Instantiate(entryTemplate, container);
+        RectTransform entryRectTransform = entryTransform.GetComponent<RectTransform>();
+        entryRectTransform.anchoredPosition = new Vector2(0, -templateHeight * transformList.Count);
+        entryTransform.gameObject.SetActive(true);
+
+        int rank = transformList.Count + 1;
+        string rankString;
+        switch (rank)
         {
-            Transform entryTransform = Instantiate(entryTemplate, entryContainer);
-            RectTransform entryRectTransform = entryTransform.GetComponent<RectTransform>();
+            default:
+                rankString = rank + "TH"; break;
+
+            case 1: rankString = "1ST"; break;
+            case 2: rankString = "2ND"; break;
+            case 3: rankString = "3RD"; break;
 
-            entryRectTransform.anchoredPosition = new Vector2(0,-templateHeight * i);
-            entryTransform.gameObject.SetActive(true);
         }
+
+        entryTransform.Find("Rank").GetComponent<Text>().text = rankString;
+
+        string name = scoreEntry.name;
+        entryTransform.Find("Name").GetComponent<Text>().text = name;
+
+        int wave = scoreEntry.wave;
+        entryTransform.Find("Wave").GetComponent<Text>().text = wave.ToString();
+
+        int score = scoreEntry.score;
+        entryTransform.Find("Score").GetComponent<Text>().text = score.ToString();
+
+        // set visible odds
+        entryTransform.Find("Background").gameObject.SetActive(rank % 2 == 1);
+
+        if (rank == 1)
+        {
+            Color colorFirst = Color.green;
+
+            // highlight first
+            entryTransform.Find("Rank").GetComponent<Text>().color = colorFirst;
+            entryTransform.Find("Name").GetComponent<Text>().color = colorFirst;
+            entryTransform.Find("Wave").GetComponent<Text>().color = colorFirst;
+            entryTransform.Find("Score").GetComponent<Text>().color = colorFirst;
+
+        }
+
+        // set star
+        switch (rank)
+        {
+            default:
+                entryTransform.Find("Star").gameObject.SetActive(false);
+                break;
+
+            case 1:
+                entryTransform.Find("Star").GetComponent<Image>().color = new Color32(255, 221, 0, 255);
+                break;
+
+            case 2:
+                entryTransform.Find("Star").GetComponent<Image>().color = Color.white;
+                break;
+
+            case 3:
+                entryTransform.Find("Star").GetComponent<Image>().color = new Color32(224, 151, 99, 255);
+                break;
+        }
+
+        transformList.Add(entryTransform);
+    }
+
+    private void AddScoreEntry(int score, int wave, string name)
+    {
+        // create scoreEntry
+        ScoreEntry scoreEntry = new ScoreEntry { name = name, score = score, wave = wave };
+
+        // load saved scores
+        string jsonString = PlayerPrefs.GetString("scoreTable");
+        Scores scores = JsonUtility.FromJson<Scores>(jsonString);
+        
+        // add new entry to scores
+        scores.scoreEntryList.Add(scoreEntry);
+        
+        // ssave updated scores
+        string json = JsonUtility.ToJson(scores);
+        PlayerPrefs.SetString("scoreTable", json);
+        PlayerPrefs.Save();
+    }
+
+    private class Scores
+    {
+        public List<ScoreEntry> scoreEntryList;
+
+    }
+
+    // Represents a single score entry
+    [System.Serializable]
+    private class ScoreEntry
+    {
+        public int score;
+        public int wave;
+        public string name;
+
     }
 }