diff --git a/GameServer.js b/GameServer.js
index 9a14f73433ed2829baf129c4736b480c3c63902d..a36395b416eb00c8e395ceda52f5b0ae7e4fc9da 100644
--- a/GameServer.js
+++ b/GameServer.js
@@ -15,7 +15,7 @@ GameServer.findRoom = function(roomId)
     {
         if (GameServer.playingRoom[i].roomId === roomId) return GameServer.playingRoom[i];
     }
-    console.log('[ERR] no room with num ' + roomId);
+    console.log(new Date().toLocaleTimeString('ko-KR') + ' [ERR] no room with num ' + roomId);
 }
 GameServer.findPlayerSocket = function(playerId)
 {
@@ -26,7 +26,7 @@ GameServer.findPlayerSocket = function(playerId)
     if (idx != -1) return this.currentPlayer[idx];
     else
     {
-        console.log('[ERR] wrong playerId('+ playerId +') to find');
+        console.log(new Date().toLocaleTimeString('ko-KR') + ' [ERR] wrong playerId('+ playerId +') to find');
         return null;
     }
 }
@@ -82,7 +82,7 @@ class GameRoom
     {
         this.roomId = GameServer.getRoomNumber();
         this.roomIndex = -1;
-        this.startCount = 2;
+        this.startCount = 5;
         this.maxPlayer = 100;
         this.nextRank = 100;
 
@@ -115,7 +115,7 @@ class GameRoom
         {
             GameServer.playingRoom[this.roomIndex] = this;
         }
-        console.log('[LOG] new room #'+this.roomId+' made, roomCount: ' + GameServer.playingRoom.length);
+        console.log(new Date().toLocaleTimeString('ko-KR') + ' [LOG] new room #'+this.roomId+' made, roomCount: ' + GameServer.playingRoom.length);
     }
 
     checkHopae(newHopae)
@@ -136,14 +136,14 @@ class GameRoom
         this.announceToTarget(playerInst.id, 'syncRoomScene', this.currentPlayer);
         this.currentPlayer.push(playerInst);
 
-        console.log('[' + playerInst.id + '] entered to room #' + this.roomId);
+        console.log(new Date().toLocaleTimeString('ko-KR') + ' [' + playerInst.id + '] entered to room #' + this.roomId);
 
         this.aliveCount++;
         if (this.currentPlayer.length >= this.startCount)
         {
             if (this.currentPhase === GameServer.Phase.READY)
             {
-                this.endTime = Date.now() + 10000; // 테스트용 10초
+                this.endTime = Date.now() + 30000; // 방 대기 시간
                 this.announceToRoom('setRoomCount', 
                 {
                     isEnable: true, endTime: this.endTime, playerCount: this.currentPlayer.length,
@@ -190,7 +190,6 @@ class GameRoom
                         isEnter: false, player: this.currentPlayer[i]
                     });
                     this.currentPhase = GameServer.Phase.READY;
-                    this.refreshRoom();
                 }
                 else this.announceToRoom('setRoomCount', 
                     {
@@ -202,7 +201,7 @@ class GameRoom
                 return;
             }
         }
-        console.log('[ERR] No player who have ' + playerId);
+        console.log(new Date().toLocaleTimeString('ko-KR') + ' [ERR] No player who have ' + playerId);
         return;
     }
 
@@ -223,7 +222,7 @@ class GameRoom
                 isEnable: false, endTime: 0, playerCount: this.currentPlayer.length,
                 isEnter: false, player: {id: -1}
             });
-            console.error('[ROOM#' + this.roomId + '] room Refreshed');
+            console.error(new Date().toLocaleTimeString('ko-KR') + ' [ROOM#' + this.roomId + '] room Refreshed');
         }
         else
         {
@@ -238,7 +237,7 @@ class GameRoom
             this.rateArrangePoint = 300;
             this.maxTypingPlayer = null;
             this.minTypingPlayer = null;
-            console.log('[ROOM#' + this.roomId + '] room Refreshed with End of Game');
+            console.log(new Date().toLocaleTimeString('ko-KR') + ' [ROOM#' + this.roomId + '] room Refreshed with End of Game');
         }
     }
     
@@ -261,7 +260,7 @@ class GameRoom
         };
         this.announceToRoom('syncRoomData', toSync);
 
-        console.log('[ROOM#'+this.roomId+'] Game Start with ' + this.currentPlayer.length + ' players');
+        console.log(new Date().toLocaleTimeString('ko-KR') + ' [ROOM#'+this.roomId+'] Game Start with ' + this.currentPlayer.length + ' players');
         console.table(this.currentPlayer);
         this.announceToRoom('startGame');
         this.startTime = Date.now();
@@ -309,7 +308,7 @@ class GameRoom
     {
         if (this.aliveCount > 0)
         {
-            console.log('[ERR] can not destroy room#' + this.roomId + ', cause player left');
+            console.log(new Date().toLocaleTimeString('ko-KR') + ' [ERR] can not destroy room#' + this.roomId + ', cause player left');
         }
         else
         {
@@ -358,10 +357,12 @@ class Player
         this.index = gameRoom.currentPlayer.length;
         this.nickname = playerData.nickname;
         this.playerImage = null;
+        this.mat = null;
         this.position = null;
         this.killCount = 0;
         this.earnedStrongHopae = 0;
         this.attackSucceed = 0;
+        this.skin = playerData.skin;
 
         this.isAlive = false;
         this.isInThisRoom = true;
@@ -406,7 +407,7 @@ class Player
             }
 
             room.announceToRoom('defeat', this);
-            console.log('[' + this.id + '] defeated, rank: ' + this.rank + ', ' + room.aliveCount + ' player left');
+            console.log(new Date().toLocaleTimeString('ko-KR') + ' [' + this.id + '] defeated, rank: ' + this.rank + ', ' + room.aliveCount + ' player left');
 
             if (room.aliveCount === 1)
             {
@@ -418,7 +419,7 @@ class Player
                 room.announceToRoom('gameEnd', winner.id);
                 room.announceToTarget(winner.id, 'alert', 'gameWin');
                 room.currentPhase = GameServer.Phase.GAMEEND;
-                console.log('['+winner.id+']' + ' winner! ' + winner.nickname);
+                console.log(new Date().toLocaleTimeString('ko-KR') + ' ['+winner.id+']' + ' winner! ' + winner.nickname);
             }
         }
     }
diff --git a/assets/image/UI/decisionBtn/cancel.png b/assets/image/UI/decisionBtn/cancel.png
new file mode 100644
index 0000000000000000000000000000000000000000..275343e32f25b6c0dc89d03ef98fa358fe2a8699
Binary files /dev/null and b/assets/image/UI/decisionBtn/cancel.png differ
diff --git a/assets/image/UI/decisionBtn/confirm.png b/assets/image/UI/decisionBtn/confirm.png
new file mode 100644
index 0000000000000000000000000000000000000000..b253295723dd288320b1cb0653c38d2bc73f4459
Binary files /dev/null and b/assets/image/UI/decisionBtn/confirm.png differ
diff --git a/assets/image/UI/decisionBtn/exit.png b/assets/image/UI/decisionBtn/exit.png
new file mode 100644
index 0000000000000000000000000000000000000000..45a34805ea48eac479bcd03c4e2b13b02b0d4672
Binary files /dev/null and b/assets/image/UI/decisionBtn/exit.png differ
diff --git a/assets/image/UI/decisionBtn/no.png b/assets/image/UI/decisionBtn/no.png
new file mode 100644
index 0000000000000000000000000000000000000000..65a5920f2447d9f9b6473bb398c5e23106784280
Binary files /dev/null and b/assets/image/UI/decisionBtn/no.png differ
diff --git a/assets/image/UI/decisionBtn/spectate.png b/assets/image/UI/decisionBtn/spectate.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f4376226d4273bf9939a91cf5d5c8d27fe99f90
Binary files /dev/null and b/assets/image/UI/decisionBtn/spectate.png differ
diff --git a/assets/image/UI/decisionBtn/yes.png b/assets/image/UI/decisionBtn/yes.png
new file mode 100644
index 0000000000000000000000000000000000000000..8081fa4371b52251e4dffbbf8d3c126c42c96a6b
Binary files /dev/null and b/assets/image/UI/decisionBtn/yes.png differ
diff --git a/assets/image/UI/dialog/dialog1.png b/assets/image/UI/dialog/dialog1.png
new file mode 100644
index 0000000000000000000000000000000000000000..d3fd6b13e0f32d8db746f41f6ed51c534f297aba
Binary files /dev/null and b/assets/image/UI/dialog/dialog1.png differ
diff --git a/assets/image/UI/dialog/dialog2.png b/assets/image/UI/dialog/dialog2.png
new file mode 100644
index 0000000000000000000000000000000000000000..9a2cc6d950ef251163b6714eb69f3adc306f3e90
Binary files /dev/null and b/assets/image/UI/dialog/dialog2.png differ
diff --git a/assets/image/UI/dialog/result_background.png b/assets/image/UI/dialog/result_background.png
new file mode 100644
index 0000000000000000000000000000000000000000..49a6808bde2e9cd609ea33f6ac5568a2b41d1258
Binary files /dev/null and b/assets/image/UI/dialog/result_background.png differ
diff --git a/assets/image/UI/dialog/result_example.png b/assets/image/UI/dialog/result_example.png
new file mode 100644
index 0000000000000000000000000000000000000000..f0bc5e1cb13ed1fc181bde75d894c152008b3a6e
Binary files /dev/null and b/assets/image/UI/dialog/result_example.png differ
diff --git a/assets/image/UI/dialog/result_stamp.png b/assets/image/UI/dialog/result_stamp.png
new file mode 100644
index 0000000000000000000000000000000000000000..595f521b10e14d422f03fc1e231d8c4a1d2ff5f2
Binary files /dev/null and b/assets/image/UI/dialog/result_stamp.png differ
diff --git a/assets/image/UI/tutorial/tutorialImages.png b/assets/image/UI/tutorial/tutorialImages.png
new file mode 100644
index 0000000000000000000000000000000000000000..75b85576b9217d690a2c6459209a38d6d3ad688f
Binary files /dev/null and b/assets/image/UI/tutorial/tutorialImages.png differ
diff --git a/assets/image/UI/tutorial/tutorialImages_ph.png b/assets/image/UI/tutorial/tutorialImages_ph.png
new file mode 100644
index 0000000000000000000000000000000000000000..3d596da10b382bb3db6c6f07f25645f300cc49e3
Binary files /dev/null and b/assets/image/UI/tutorial/tutorialImages_ph.png differ
diff --git a/assets/image/character/sunbi/sunbi_burning_big.png b/assets/image/character/sunbi/sunbi_burning_big.png
new file mode 100644
index 0000000000000000000000000000000000000000..5b88d03cbcd9f0f75c32a3af70c3f2fc9a253538
Binary files /dev/null and b/assets/image/character/sunbi/sunbi_burning_big.png differ
diff --git a/assets/image/character/sunbi/sunbi_burning_small.png b/assets/image/character/sunbi/sunbi_burning_small.png
new file mode 100644
index 0000000000000000000000000000000000000000..76205e1ef7baab10e878e6960adde55bf0759bba
Binary files /dev/null and b/assets/image/character/sunbi/sunbi_burning_small.png differ
diff --git a/assets/image/character/sunbi/sunbi_die.png b/assets/image/character/sunbi/sunbi_die.png
new file mode 100644
index 0000000000000000000000000000000000000000..b6a69635815489a3ce79f65dc423dc53f9f2a228
Binary files /dev/null and b/assets/image/character/sunbi/sunbi_die.png differ
diff --git a/assets/image/character/sunbi/sunbi_hit.png b/assets/image/character/sunbi/sunbi_hit.png
new file mode 100644
index 0000000000000000000000000000000000000000..b66b872c10dfaeafff0b14d243a926fc67ef4931
Binary files /dev/null and b/assets/image/character/sunbi/sunbi_hit.png differ
diff --git a/assets/image/character/sunbi/sunbi_sit.png b/assets/image/character/sunbi/sunbi_sit.png
new file mode 100644
index 0000000000000000000000000000000000000000..21320007a732060e22a27f1e7155705558846948
Binary files /dev/null and b/assets/image/character/sunbi/sunbi_sit.png differ
diff --git a/assets/image/character/sunbi/sunbi_stand.png b/assets/image/character/sunbi/sunbi_stand.png
new file mode 100644
index 0000000000000000000000000000000000000000..d705dd816603109d6f20e255b1cb6cec392e750b
Binary files /dev/null and b/assets/image/character/sunbi/sunbi_stand.png differ
diff --git a/assets/image/character/sunbi/sunbi_throw.png b/assets/image/character/sunbi/sunbi_throw.png
new file mode 100644
index 0000000000000000000000000000000000000000..d8ad86f9dccbbdaeef7cfb49faa43cfef503f2f6
Binary files /dev/null and b/assets/image/character/sunbi/sunbi_throw.png differ
diff --git a/assets/image/character/sunbi/sunbi_write.png b/assets/image/character/sunbi/sunbi_write.png
new file mode 100644
index 0000000000000000000000000000000000000000..13f84825081bd38a140805c106fb92f4021a4dfa
Binary files /dev/null and b/assets/image/character/sunbi/sunbi_write.png differ
diff --git a/assets/image/etc/wordSpace/wordSpace2.png b/assets/image/etc/wordSpace/wordSpace2.png
new file mode 100644
index 0000000000000000000000000000000000000000..6def80a0f5498d67fb4cb40c85f76b74e8fcd0a5
Binary files /dev/null and b/assets/image/etc/wordSpace/wordSpace2.png differ
diff --git a/assets/image/etc/wordSpace/wordSpace3.png b/assets/image/etc/wordSpace/wordSpace3.png
new file mode 100644
index 0000000000000000000000000000000000000000..50a492c758166608c387ebf2e52a909ddfd93c36
Binary files /dev/null and b/assets/image/etc/wordSpace/wordSpace3.png differ
diff --git a/assets/image/etc/wordSpace/wordSpace4.png b/assets/image/etc/wordSpace/wordSpace4.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b9e5009cc097d2bc69eee737f498805ba650d68
Binary files /dev/null and b/assets/image/etc/wordSpace/wordSpace4.png differ
diff --git a/assets/image/etc/wordSpace/wordSpace5.png b/assets/image/etc/wordSpace/wordSpace5.png
new file mode 100644
index 0000000000000000000000000000000000000000..1b188b9cc104b48b710b903e5774d6e919783c04
Binary files /dev/null and b/assets/image/etc/wordSpace/wordSpace5.png differ
diff --git a/assets/image/etc/wordSpace/wordspace.png b/assets/image/etc/wordSpace/wordspace.png
new file mode 100644
index 0000000000000000000000000000000000000000..915f4009385ae48210bfaf43a2717dc836b4d96a
Binary files /dev/null and b/assets/image/etc/wordSpace/wordspace.png differ
diff --git a/assets/image/etc/wordSpace/wordspace1.png b/assets/image/etc/wordSpace/wordspace1.png
new file mode 100644
index 0000000000000000000000000000000000000000..923df8f786f2fe5926090b2e0873275cffb81cee
Binary files /dev/null and b/assets/image/etc/wordSpace/wordspace1.png differ
diff --git a/assets/image/etc/wordspace.png b/assets/image/etc/wordspace.png
deleted file mode 100644
index d51616cf6f0f50325cf19a091bafd15e8ae54944..0000000000000000000000000000000000000000
Binary files a/assets/image/etc/wordspace.png and /dev/null differ
diff --git a/assets/image/word/hopaeSceneInput.png b/assets/image/word/hopaeSceneInput.png
new file mode 100644
index 0000000000000000000000000000000000000000..e27d721e167b17aca5fc43c8a1149da238f0d111
Binary files /dev/null and b/assets/image/word/hopaeSceneInput.png differ
diff --git a/index.html b/index.html
index 00242b38f276a3c0a6b7f7d1f68327cf54d116e0..fcdb3a18216aafbfb12520055a32781fd6b6b78b 100644
--- a/index.html
+++ b/index.html
@@ -3,24 +3,24 @@
 <head>
     <meta charset="utf-8"/>
     <script src="/socket.io/socket.io.js"></script>
-    <script src="js/phaser.js"></script>
-    <script src="js/ScenesData.js"></script>
-    <script src="js/Background.js"></script>
-    <script src="js/Input.js"></script>
-    <script src="js/WordSpace.js"></script>
-    <script src="js/GameCycle.js"></script>
-    <script src="js/WordObject.js"></script>
-    <script src="js/WordReader.js"></script>
-    <script src="js/CSVParsing.js"></script>
-    <script src="js/SelectWord.js"></script>
-    <script src="js/BGMsound.js"></script>
-    <script src="js/Enums.js"></script>
-    <script src="js/ResourceLoader.js"></script>
-    <script src="js/UIObject.js"></script>
+    <script src="/js/phaser.js"></script>
+    <script src="/js/ScenesData.js"></script>
+    <script src="/js/Background.js"></script>
+    <script src="/js/Input.js"></script>
+    <script src="/js/WordSpace.js"></script>
+    <script src="/js/GameCycle.js"></script>
+    <script src="/js/WordObject.js"></script>
+    <script src="/js/WordReader.js"></script>
+    <script src="/js/CSVParsing.js"></script>
+    <script src="/js/SelectWord.js"></script>
+    <script src="/js/BGMsound.js"></script>
+    <script src="/js/Enums.js"></script>
+    <script src="/js/ResourceLoader.js"></script>
+    <script src="/js/UIObject.js"></script>
     <style media='screen' type='text/css'>
         @font-face {
           font-family: sejongFont;
-          src: url('assets/font/EBS주시경B.ttf');
+          src: url('assets/font/EBS훈민정음새론SB.ttf');
           font-weight:400;
           font-weight:normal;
         }
@@ -31,18 +31,29 @@
     <style>
         img { position: relative; width: 100%; height: 100%; z-index: 0;}
         #dvLogin { position: absolute; left: 65%; top: 35%; width: 30%; height: 30%; padding: 10px; background: black; z-index: 1;}
+        #dvNewEmail { position:absolute; left: 35%; top: 35%; width: 30%; height: 30%; padding: 10px; background: black; z-index: 1; display: none; }
+        #notSupport { position: absolute; left: 25%; top: 25%; background: white; z-index: 2; width: 50%; height: 50%; display: none;}
     </style>
 </head>
 <body>
     <div id="mainTitle">
-        <img id="titleImg" src="assets/image/background/title.png" alt="title">
+        <img id="titleImg" src="/assets/image/background/title.png" alt="title">
         <div id="dvLogin">
             <input id="userEmail" type="email" placeholder="email" style="width: 100%; height: 10%;"></br>
             <input id="userPassword" type="password" placeholder="password" maxlength="17" style="width: 100%; height: 10%;"></br>
-            <button id="joinBtn" style="width: 100%; height: 10%;">이메일로 가입하기</button></br>
+            <button id="joinOpenBtn" style="width: 100%; height: 10%;">이메일로 가입하기</button></br>
             <button id="emailBtn" style="width: 100%; height: 10%;">이메일로 로그인</button></br>
-            <button id="googleBtn" style="width: 10%; height: 10%;"><img src="assets/title/googleBtn.png" style="object-fit: contain"></button></br>
+            <button id="googleBtn" style="width: 10%; height: 10%;"><img src="/assets/title/googleBtn.png" style="object-fit: contain"></button></br>
         </div>
+        <div id="dvNewEmail">
+            <input id="newEmail" type="email" placeholder="email" style="width: 100%; height: 10%;"></br>
+            <input id="newPassword" type="password" placeholder="password" maxlength="17" style="width: 100%; height: 10%;"></br>
+            <input id="newPasswordCheck" type="password" placeholder="password again" maxlength="17" style="width: 100%; height: 10%;"></br>
+            <input id="newName" placeholder="user name" maxlength="8" style="width: 100%; height: 10%;"></br>
+            <button id="joinBtn" style="width: 50%; height: 10%;">가입하기</button>
+            <button id="joinCancelBtn" style="width: 50%; height: 10%;">취소</button>
+        </div>
+        <p id="notSupport">해당하는 환경에서는 지원되지 않습니다. PC에서 이용 부탁드립니다.</p>
     </div>
 
     <script src="https://www.gstatic.com/firebasejs/6.3.3/firebase-app.js"></script>
@@ -64,8 +75,8 @@
     firebase.initializeApp(firebaseConfig);
     </script>
 
-    <script src="js/Client.js"></script>
-    <script src="js/Main.js"></script>
-    <script src="js/FirebaseClient.js"></script>
+    <script src="/js/Client.js"></script>
+    <script src="/js/main.js"></script>
+    <script src="/js/FirebaseClient.js"></script>
 </body>
 </html>
\ No newline at end of file
diff --git a/js/Background.js b/js/Background.js
index 543b0eaecc7f1672608894eba25f981dacfd3f20..4816fb82302696bd67bb6a326a128c057a0cbb73 100644
--- a/js/Background.js
+++ b/js/Background.js
@@ -13,15 +13,22 @@ BackGround.otherCharacters = [];
 
 BackGround.drawCharacter = function(scene)
 {
-    RoomData.myself.playerImage = scene.add.sprite(game.config.width / 2, game.config.height * 41 / 48, 'pyeongminWrite').setScale(0.45).setDepth(5);
-    RoomData.myself.position = new Phaser.Math.Vector2(RoomData.myself.playerImage.x, RoomData.myself.playerImage.y);
+    RoomData.myself.playerImage = scene.add.sprite(game.config.width / 2, game.config.height * 41 / 48, Enums.characterSkin[PlayerData.userData.skin] + 'Write')
+        .setScale(0.45).setDepth(5);
+    RoomData.myself.position = new Phaser.Math.Vector2(RoomData.myself.playerImage.x - 20, RoomData.myself.playerImage.y - 20);
+    RoomData.myself.mat = scene.add.sprite(RoomData.myself.position.x, RoomData.myself.position.y, 'mat')
+        .setScale(0.45).setDepth(4);
     BackGround.characterPos = BackGround.characterPos.sort(function(){return 0.5-Math.random()});
     RoomData.players.forEach(function(element){
         if(element.id != RoomData.myself.id)
         {
             element.position = BackGround.characterPos.pop();
-            element.playerImage = scene.add.sprite(element.position.x, element.position.y, 'pyeongminWrite').setScale(0.315).setDepth(5);
+            element.playerImage = scene.add.sprite(element.position.x, element.position.y, Enums.characterSkin[element.skin] + 'Write')
+                .setScale(0.315).setDepth(5);
             element.playerImage.flipX = element.position.x < game.config.width / 2 ? true : false;
+            element.mat = scene.add.sprite(element.position.x - 14 * (element.position.x < game.config.width / 2 ? -1 : 1), element.position.y - 14, 'mat')
+                .setScale(0.315).setDepth(4);
+            element.mat.flipX = element.position.x < game.config.width / 2 ? true : false;
             element.nicknameText = scene.add.text(element.position.x, element.position.y - 90, element.nickname)
                 .setOrigin(0.5,0.5).setColor('#000000').setPadding(0.5,0.5,0.5,0.5).setDepth(5.1);
 6        }
diff --git a/js/Client.js b/js/Client.js
index 5ebb9fc967d38c7df94548c528eba598c2fb730a..d0c6364546891c27ad20e3cf9e9e417d78ab33e6 100644
--- a/js/Client.js
+++ b/js/Client.js
@@ -85,7 +85,7 @@ socket.on('setRoomCount', function(msg)
             }
             ScenesData.roomScene.players.push(playerSet);
         }
-        else // remove character
+        else if (msg.id != -1) // remove character
         {
             let idx = ScenesData.roomScene.players.findIndex(function(element)
             {
@@ -205,6 +205,7 @@ socket.on('defeat', function(msg) // object player
     let playerImage = RoomData.findPlayer(msg.id).playerImage;
     let position = RoomData.findPlayer(msg.id).position;
     let nicknameText = RoomData.findPlayer(msg.id).nicknameText;
+    let earnedStrongHopae = RoomData.findPlayer(msg.id).earnedStrongHopae;
 
     if(WordSpace.CurrentPhase == 1)
         Audio.killSound(ScenesData.gameScene, 'Phase1');
@@ -218,10 +219,11 @@ socket.on('defeat', function(msg) // object player
     RoomData.players[msg.index].playerImage = playerImage;
     RoomData.players[msg.index].position = position;
     RoomData.players[msg.index].nicknameText = nicknameText;
+    RoomData.players[msg.index].earnedStrongHopae = earnedStrongHopae;
 
     let victim = RoomData.findPlayer(msg.id);
     RoomData.aliveCount--;
-    victim.playerImage.play(WordSpace.pyeongminAnims[Enums.characterAnim.gameOver]);
+    victim.playerImage.play(WordSpace.characterAnims[victim.skin][Enums.characterAnim.gameOver]);
 
     
     if (msg.lastAttack != null) 
@@ -270,7 +272,7 @@ socket.on('defeat', function(msg) // object player
                         duration: 500,
                         repeat: 0, // -1: infinity
                         yoyo: false });
-                }, 1000);
+                }, 5000);
             },
         })
 
@@ -311,6 +313,7 @@ socket.on('defeat', function(msg) // object player
         {
             var keys = Object.keys(Enums.item);
             WordSpace.generateWord.Item(ScenesData.gameScene, Enums.item[keys[keys.length * Math.random() << 0]]);
+            Audio.playSound(ScenesData.gameScene, 'getItem');
             RoomData.myself.killCount++;
         }
     }
@@ -355,14 +358,12 @@ socket.on('defeat', function(msg) // object player
                 }, 1000);
             }
         })
-
-
     }
     if(msg.id == RoomData.myself.id)
     {
         RoomData.myself = RoomData.players[msg.index];
         setTimeout(() => {
-            gameEndMenu(true);
+            gameEndMenu(false);
         }, 2000);
     }
 });
@@ -392,6 +393,7 @@ socket.on('attackSucceed', function(msg)
 {
     //console.log('client');
     let tempWord = WordSpace.generateWord.Name(ScenesData.gameScene, true, RoomData.findPlayer(msg.victimId));
+    tempWord.instantiate(ScenesData.gameScene);
     let victimPos = RoomData.findPlayer(msg.victimId).position;
     tempWord.physicsObj.setPosition(victimPos.x, victimPos.y);
     tempWord.wordObj.setPosition(tempWord.physicsObj.x, tempWord.physicsObj.y);
@@ -415,13 +417,14 @@ var gameEndMenu = function(isWin)
     let earnedMoney = 0;
     if(isWin) earnedMoney += 20;
     earnedMoney += RoomData.myself.killCount * 3;
-    earnedMoney += parseInt(WordSpace.playerTypingRate / 10);
+    earnedMoney += parseInt(WordSpace.playerTyping / 10);
     earnedMoney += Math.max(20, Math.pow(RoomData.myself.attackSucceed, 2));
     earnedMoney += parseInt(20 * (1 - (RoomData.myself.rank - 1) / (RoomData.players.length - 1)));
+    earnedMoney = parseInt(earnedMoney / 40);
 
     Input.inputField.text.destroy();
 
-    var temp = function(){
+    var endGame = function(){
 
         socket.emit('exitFromRoom', RoomData.myself.id);
         fbClient.updateUserData('killCount', RoomData.myself.killCount);
@@ -429,25 +432,29 @@ var gameEndMenu = function(isWin)
         ScenesData.changeScene('menuScene');
     }
 
+
     ScenesData.gameScene.backToMenuDialog = ScenesData.gameScene.rexUI.add.dialog({
         x: game.config.width / 2,
         y: game.config.height / 2,
 
-        background: ScenesData.gameScene.add.sprite(game.config.width / 2, game.config.height / 2, 'panel').setOrigin(0.5, 0.5),
+        background: ScenesData.gameScene.add.sprite(game.config.width / 2, game.config.height / 2, 'resultDialog').setOrigin(0.5, 0.5),
 
         content: ScenesData.gameScene.rexUI.add.dialog({
             x: game.config.width / 2,
             y: game.config.height / 2,
             choices: [
-                UIObject.createLabel(ScenesData.gameScene, game.config.width / 2 - 100, game.config.height / 2 - 100, 10.2, 'playerStand', 0.7, 'center'),
-                UIObject.createLabel(ScenesData.gameScene, game.config.width / 2 + 120, game.config.height / 2 - 150, 10.2, 
-                    'button', 1, 'center', '등수 : ' + RoomData.myself.rank + '등', 30).layout(),
-                UIObject.createLabel(ScenesData.gameScene, game.config.width / 2 + 120, game.config.height / 2 - 50, 10.2, 
-                    'button', 1, 'center', '킬 수 : ' + RoomData.myself.killCount + '킬', 30).layout(),
-                UIObject.createLabel(ScenesData.gameScene, game.config.width / 2 + 120, game.config.height / 2 + 50, 10.2, 
-                    'button', 1, 'center', '획득 강호패 : ' + RoomData.myself.earnedStrongHopae + '개', 30).layout(),
-                UIObject.createLabel(ScenesData.gameScene, game.config.width / 2 + 120, game.config.height / 2 + 150, 10.2, 
-                    'button', 1, 'center', '획득 골드 : ' + earnedMoney + '원', 30).layout()
+                ScenesData.gameScene.add.sprite(game.config.width / 2 - 200, game.config.height / 2 - 100, Enums.characterSkin[PlayerData.userData.skin] + 'Stand')
+                    .setOrigin(0.5, 0.5).setDepth(10.2).setScale(0.7),
+                ScenesData.gameScene.add.text(game.config.width / 2 + 400, game.config.height / 2 - 220, RoomData.myself.rank + '등')
+                    .setOrigin(1, 0.5).setColor('#000000').setDepth(10.2).setPadding(5,5,5,5).setFont('50pt sejongFont'),
+                ScenesData.gameScene.add.text(game.config.width / 2 + 400, game.config.height / 2 - 80, RoomData.myself.killCount + '회')
+                    .setOrigin(1, 0.5).setColor('#000000').setDepth(10.2).setPadding(5,5,5,5).setFont('50pt sejongFont'),
+                ScenesData.gameScene.add.text(game.config.width / 2 + 400, game.config.height / 2 + 80, RoomData.myself.earnedStrongHopae + '개')
+                    .setOrigin(1, 0.5).setColor('#000000').setDepth(10.2).setPadding(5,5,5,5).setFont('50pt sejongFont'),
+                ScenesData.gameScene.add.text(game.config.width / 2 + 400, game.config.height / 2 + 220, '+' + earnedMoney + '냥')
+                    .setOrigin(1, 0.5).setColor('#000000').setDepth(10.2).setPadding(5,5,5,5).setFont('50pt sejongFont'),
+                UIObject.createLabel(ScenesData.gameScene, game.config.width / 2 - 250, game.config.height / 2 + 220, 10.2, 'nameBgr' + RoomData.myself.nickname.length, 2, 
+                    'center', RoomData.myself.nickname, 50, '#ffffff', 0.45, 0.5)
             ],
     
             align: {
@@ -455,31 +462,33 @@ var gameEndMenu = function(isWin)
             }
         }),
         actions: [
-            UIObject.createLabel(ScenesData.gameScene, game.config.width / 2 - 120, game.config.height / 2 + 300, 10.2, 'button', 1, 'center', '나가기').layout(),
-            UIObject.createLabel(ScenesData.gameScene, game.config.width / 2 + 120, game.config.height / 2 + 300, 10.2, 'button', 1, 'center', '관전하기').layout()
+            UIObject.createLabel(ScenesData.gameScene, game.config.width / 2 - 200, game.config.height / 2 + 350, 10.2, 'exitBtn', 1, 'center', '                      ').layout(),
+            UIObject.createLabel(ScenesData.gameScene, game.config.width / 2 + 200, game.config.height / 2 + 350, 10.2, 'spectateBtn', 1, 'center', '                      ').layout()
         ],
 
         space: {
             action: 10,
 
-            left: 20,
-            right: 20,
-            top: 20,
-            bottom: 20,
+            left: 50, right: 50, top: 50, bottom: 50,
         },
 
         align: {
             actions: 'center' // 'center'|'left'|'right'
         }
     }).setDepth(10.2);
+    
+    if(isWin) ScenesData.gameScene.winMark = 
+        ScenesData.gameScene.add.sprite(game.config.width / 2 + 500, game.config.height / 2 + 400, 'resultStamp').setOrigin(0.5, 0.5).setDepth(10.2);
 
     ScenesData.gameScene.backToMenuDialog
         .on('button.click', function (button, groupName, index) {
-            if(index == 0) temp();
+            if(index == 0) endGame();
             else
             {
+                if(isWin) ScenesData.gameScene.winMark.destroy();
                 ScenesData.gameScene.backToMenuDialog.setVisible(false);
-                ScenesData.gameScene.backToMenuBtn = UIObject.createButton(ScenesData.gameScene, UIObject.createLabel(ScenesData.gameScene, 100, 900, 10.2, 'pyeongminThrow', 0.5, 'center'), 1, 0, 2, temp);
+                ScenesData.gameScene.backToMenuBtn = UIObject.createButton(ScenesData.gameScene, 
+                    UIObject.createLabel(ScenesData.gameScene, 200, 900, 10.2, 'spectateBtn', 1, 'center'), -1, -1, -1, endGame);
             }
         }, ScenesData.gameScene)
         .on('button.over', function (button, groupName, index) {
diff --git a/js/Enums.js b/js/Enums.js
index 29489bb82268dba7dbeb79861d1d84e0f7cf3a25..e1bc20f2225bec50238474ad95917398df702828 100644
--- a/js/Enums.js
+++ b/js/Enums.js
@@ -1,4 +1,5 @@
 var Enums = Enums || {};
 
 Enums.characterAnim =  { sit: 0, write: 1, notBurning: 2, smallBurning: 3, bigBurning: 4, throw: 5, hit: 6, gameOver: 7 }
-Enums.item = {invincible: "무적", nameList: "명단", charge: "충전", clean: "청소", heavy: "중량", dark: "암흑"}
\ No newline at end of file
+Enums.item = {invincible: "무적", nameList: "명단", charge: "충전", clean: "청소", heavy: "중량", dark: "암흑"}
+Enums.characterSkin = ["pyeongmin", "sunbi"]
\ No newline at end of file
diff --git a/js/FirebaseClient.js b/js/FirebaseClient.js
index e968b1abd0a739d59b0860a1c24d17dc52dca4a6..6d4ee163bb08246dcd1681424d176b87a7467a93 100644
--- a/js/FirebaseClient.js
+++ b/js/FirebaseClient.js
@@ -20,6 +20,17 @@ FirebaseClient.prototype.initEvent = function()
 	this.googleBtn.addEventListener('click', this.onGoogleBtnClick.bind(this));
 	this.emailBtn.addEventListener('click', this.onEmailBtnClick.bind(this));
 	this.joinBtn.addEventListener('click', this.createEmailUser.bind(this));
+	
+	document.getElementById('joinOpenBtn').addEventListener('click', function()
+	{
+		document.getElementById('dvNewEmail').style.display = 'block';
+		document.getElementById('dvLogin').style.display = 'none';
+	});
+	document.getElementById('joinCancelBtn').addEventListener('click', function()
+	{
+		document.getElementById('dvNewEmail').style.display = 'none';
+		document.getElementById('dvLogin').style.display = 'block';
+	})
 }
 
 FirebaseClient.prototype.logOut = function()
@@ -125,56 +136,76 @@ FirebaseClient.prototype.onEmailBtnClick = function()
 
 FirebaseClient.prototype.createEmailUser = function()
 {
-	var email = document.getElementById('userEmail').value.trim();
-	var password = document.getElementById('userPassword').value.trim();
+	var email = document.getElementById('newEmail').value.trim();
+	var password = document.getElementById('newPassword').value.trim();
+	var passCheck = document.getElementById('newPasswordCheck').value.trim();
+	var newUserName = document.getElementById('newName').value.trim();
 	// 유효성 검증
-	if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email))
+	if (!(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)))
+	{
+		alert('잘못된 이메일입니다.');
+		return;
+	}
+	else if (password != passCheck)
 	{
+		alert('비밀번호와 비밀번호 확인이 다릅니다.')
+		return;
+	}
+	else if (newUserName.length === 0)
+	{
+		alert('닉네임을 작성해주세요.')
+		return;
+	}
+	else
+	{
+
 		var cbCreateUserWithEmail = function(user){
 			console.log('이메일 가입 성공 : ', JSON.stringify(user));
 			//프로필 업데이트 - 이메일 가입시 유저이름 파라미터를 보내지 않으므로 가입 성공 후 처리
 			firebase.auth().currentUser.updateProfile({
-				displayName: email,
+				displayName: newUserName,
 			}).then(function() {
 				console.log('userName 업데이트 성공')
 			}).catch(function(error) {
 				console.error('userName 업데이트 실패 : ', error );
 			});
-			/*
-			//인증 메일 발송
-			this.auth.useDeviceLanguage(); // 이메일 기기언어로 세팅
-			user.sendEmailVerification().then(function() {
-				console.log('인증메일 발송 성공')
-			}).catch(function(error) {
-				console.error('인증메일 발송 에러', error);
-			});*/
+		/*
+		//인증 메일 발송
+		this.auth.useDeviceLanguage(); // 이메일 기기언어로 세팅
+		user.sendEmailVerification().then(function() {
+			console.log('인증메일 발송 성공')
+		}).catch(function(error) {
+			console.error('인증메일 발송 에러', error);
+		});*/
 		}
+		document.getElementById('dvLogin').style.display = 'block';
+		document.getElementById('dvNewEmail').style.display = 'block';
 		var cbAfterPersistence = function(){
-			return this.auth.createUserWithEmailAndPassword(email, password)
-				.then(cbCreateUserWithEmail.bind(this))
-				.catch(function(error) {
-					console.error('이메일 가입시 에러 : ', error);
-					switch(error.code){
-						case "auth/email-already-in-use":
-							alert('이미 사용중인 이메일 입니다.');
-							break;
-						case "auth/invalid-email":
-							alert('유효하지 않은 메일입니다');
-							break;
-						case "auth/operation-not-allowed":
-							alert('이메일 가입이 중지되었습니다.');
-							break;
-						case "auth/weak-password":
-							alert("비밀번호를 6자리 이상 필요합니다");
-							break;
-					}
-				});
+		return this.auth.createUserWithEmailAndPassword(email, password)
+			.then(cbCreateUserWithEmail.bind(this))
+			.catch(function(error) {
+				console.error('이메일 가입시 에러 : ', error);
+				switch(error.code){
+					case "auth/email-already-in-use":
+						alert('이미 사용중인 이메일 입니다.');
+						break;
+					case "auth/invalid-email":
+						alert('유효하지 않은 메일입니다');
+						break;
+					case "auth/operation-not-allowed":
+						alert('이메일 가입이 중지되었습니다.');
+						break;
+					case "auth/weak-password":
+						alert("비밀번호를 6자리 이상 필요합니다");
+						break;
+				}
+			});
 		}
 		this.auth.setPersistence(firebase.auth.Auth.Persistence.SESSION)
 			.then(cbAfterPersistence.bind(this))
 			.catch(function(error) {
 				console.error('인증 상태 설정 중 에러 발생' , error);
-			});	
+			});
 	}
 }
 
@@ -233,6 +264,8 @@ FirebaseClient.prototype.updateUserData = function(key, valueChanged, replace =
 		case 'killCount':
 			beforeData.killCount = replace ? (valueChanged) : (beforeData.killCount + valueChanged);
 			break;
+		case 'skin':
+			beforeData.skin = valueChanged;
 		default:
 			console.log('[ERROR] database has no key for ' + key);
 			break;
@@ -243,34 +276,45 @@ FirebaseClient.prototype.updateUserData = function(key, valueChanged, replace =
 
 document.addEventListener('DOMContentLoaded', function()
 {
-	window.fbClient = new FirebaseClient();
-	document.onkeydown = function(e)
-	{
-		if (!fbClient.isGameStarted && e.keyCode === 13)
+	var filter = "win16|win32|win64|mac|macintel";
+	if ( navigator.platform ){
+		if ( filter.indexOf(navigator.platform.toLowerCase())<0 ){
+			document.getElementById('dvLogin').style.display = 'none';
+			document.getElementById('notSupport').style.display = 'block';
+		}
+		else 
 		{
-			fbClient.onEmailBtnClick();
+			window.fbClient = new FirebaseClient();	
+			
+			document.onkeydown = function(e)
+			{
+				if (!fbClient.isGameStarted && e.keyCode === 13)
+				{
+					fbClient.onEmailBtnClick();
+				}
+				else if (fbClient.isGameStarted && e.keyCode === 27)
+				{
+					fbClient.logOut();
+				}
+			}
 		}
 	}
     console.log('done load');
 });
 
-document.onkeydown = function(e)
-{
-	if (fbClient.isGameStarted && e.keyCode === 27) fbClient.logOut();
-}
-
 class UserData
 {
     constructor()
     {
-        this.userName = prompt("유저의 이름을 입력해주세요.");
+        this.userName = fbClient.auth.currentUser.displayName;
         this.exp = 0;
         this.rank = -1;
         this.hopae = [];
 		this.recentHopae = null;
 		this.title = [];
 		this.money = 0;
-		this.item = [];
+		this.item = [0];
 		this.killCount = 0;
+		this.skin = 0;
     }
 }
\ No newline at end of file
diff --git a/js/Input.js b/js/Input.js
index fe8ef149a77fa0632e0b9011f2a44da8aa1244c7..75a07771b0b2c5a6d9cb94e3360e112b698d68a1 100644
--- a/js/Input.js
+++ b/js/Input.js
@@ -4,6 +4,7 @@ Input.input = [];
 Input.converted = '';
 Input.convInput = ''; // converted input
 Input.finalInput = '';
+Input.lastSuccess = '';
 
 Input.isShifted = false;
 Input.isEntered = false;
@@ -23,26 +24,16 @@ Input.gameSceneEnterReaction = function()
 {
     if (RoomData.myself.isAlive && !Input.isEntered)
     {
-        if (Input.attackMode) WordSpace.attack(Input.removeConVow(Input.finalInput), Input.attackOption.wordGrade);
+        if (Input.attackMode)
+        {
+            WordSpace.attack(Input.removeConVow(Input.finalInput), Input.attackOption.wordGrade);
+            Input.inputField.inputBackground.setFrame(4);
+        }
         else WordSpace.findWord(Input.finalInput);
         Input.reset();
         Input.isEntered = true;
     }
 }
-Input.menuSceneEnterReaction = function()
-{
-    Input.finalInput = Input.removeConVow(Input.finalInput);
-    if (Input.finalInput.length > 1)
-    {
-        PlayerData.nickname = Input.finalInput;
-        Input.reset();
-    }
-    else 
-    {
-        alert('정확한 가명을 입력해주세요.');
-        Input.reset();
-    }
-}
 
 Input.reset = function()
 {
@@ -209,7 +200,12 @@ Input.convert = function()
         this.convInput = this.convInput.slice(1, 2);
     }
     Input.finalInput = Input.converted + Input.convInput;
-    return true;
+    if (Input.finalInput.length > 6) return false;
+    else 
+    {
+        this.lastSuccess = this.finalInput;
+        return true;
+    }
     //console.log('_____end_convert_____');    
 }
 
@@ -318,17 +314,24 @@ Input.removeConVow = function(_wordText)
 
 Input.inputField = 
 {
-    generate: function(scene, enterCallback, text, isHopaeScene = false)
+    generate: function(scene, enterCallback, text)
     {
-        this.text = text;
+        this.text = text.getElement('text');
+        this.inputBackground = text.getElement('background');
+
+        if(ScenesData.currentScene == ScenesData.gameScene) Input.inputField.inputBackground.setFrame(4);
 
-        scene.input.keyboard.on('keyup', function() {Input.pressCount--; Input.justPressed = ''; 
-            if(isHopaeScene)
+        scene.input.keyboard.on('keydown', function() {
+            if(ScenesData.currentScene == ScenesData.hopaeScene && Input.finalInput.length > 1) Input.inputField.inputBackground.setFrame(Input.finalInput.length - 2);
+        })
+
+        scene.input.keyboard.on('keyup', function() {Input.pressCount--; Input.justPressed = '';
+            if(ScenesData.currentScene == ScenesData.hopaeScene)
             {
-                ScenesData.hopaeScene.checkBtn.setEnable(Input.checkProperInput(Input.inputField.text.text) ? true : false);
-                if(Input.finalInput.length > 4) ScenesData.hopaeScene.warningText.setVisible(true);
-                else ScenesData.hopaeScene.warningText.setVisible(false);
-            }})
+                ScenesData.hopaeScene.checkBtn.setEnable(Input.checkProperInput(Input.inputField.text.text) && (Input.finalInput.length > 1) ? true : false);
+                ScenesData.hopaeScene.warningText.setVisible(WordReader.getWordTyping(Input.finalInput) > 9 ? true : false);
+            }
+        })
         scene.input.keyboard.on('keydown-SHIFT', function() {Input.isShifted = true});
         scene.input.keyboard.on('keyup-SHIFT', function() {Input.isShifted = false});
         scene.input.keyboard.on('keydown-DELETE', function() {Input.reset()});
@@ -403,11 +406,14 @@ Input.pushInput = function(inputKey)
             }
         }
         else output = inputKey.charCodeAt(0);
-        this.input.push(output);
+        if (this.finalInput.length <= this.maxInput) this.input.push(output);
         //console.log(Input.input);
         if (!this.convert() || this.finalInput.length > this.maxInput) 
         {
-            this.input.pop();
+            this.converted = this.lastSuccess;
+            this.finalInput = this.lastSuccess;
+            this.convInput = '';
+            this.input = [];
             this.convert();
         }
         this.inputField.text.setText(Input.finalInput);
diff --git a/js/ResourceLoader.js b/js/ResourceLoader.js
index bfe82244dd137686798f98dcd8cacbeab62fbb66..15bde11fba70a59b618e815d591c558494776220 100644
--- a/js/ResourceLoader.js
+++ b/js/ResourceLoader.js
@@ -5,13 +5,12 @@ ResourceLoader.loadBackGround = function(scene)
     scene.load.image('weightWarning', 'assets/image/background/weightWarning.png');
     scene.load.image('baseBackground', 'assets/image/background/yellowBack.png');
     scene.load.image('gameBackground', 'assets/image/background/background_brain.png');
-    scene.load.image('menuBackground', 'assets/placeholder/menuBackground.png');
+    scene.load.image('menuBackground', 'assets/image/UI/main/mainBackground.png');
     scene.load.image('roomBackground', 'assets/placeholder/roomBackground.png');
 }
 
 ResourceLoader.loadImage = function(scene)
 {
-    scene.load.image('inputfield', 'assets/image/etc/wordspace.png');
     for (let i = 0; i < 4; i++)
     {
         for (let j = 2; j < 7; j++)
@@ -41,14 +40,48 @@ ResourceLoader.loadImage = function(scene)
     scene.load.spritesheet('pyeongminGameOver', 'assets/image/character/pyeongmin/balladang/pyeong_balladang.png', { frameWidth: 720, frameHeight: 700 });
     scene.load.image('pyeongminStand', 'assets/image/character/pyeongmin/pyeong_stand.png');
     
+    scene.load.spritesheet('sunbiSit', 'assets/image/character/sunbi/sunbi_sit.png', { frameWidth: 521, frameHeight: 610 });
+    scene.load.spritesheet('sunbiWrite', 'assets/image/character/sunbi/sunbi_write.png', { frameWidth: 521, frameHeight: 610 });
+    scene.load.spritesheet('sunbiThrow', 'assets/image/character/sunbi/sunbi_throw.png', { frameWidth: 521, frameHeight: 610 });
+    scene.load.spritesheet('sunbiBurningSmall', 'assets/image/character/sunbi/sunbi_burning_small.png', { frameWidth: 521, frameHeight: 610 });
+    scene.load.spritesheet('sunbiBurningBig', 'assets/image/character/sunbi/sunbi_burning_big.png', { frameWidth: 521, frameHeight: 610 });
+    scene.load.spritesheet('sunbiGameOver', 'assets/image/character/sunbi/sunbi_die.png', { frameWidth: 720, frameHeight: 700 });
+    scene.load.image('sunbiStand', 'assets/image/character/sunbi/sunbi_stand.png');
+    
     scene.load.spritesheet('wordBreak', 'assets/image/word/wordbreak.png', { frameWidth: 180, frameHeight: 180 });
+    scene.load.spritesheet('hopaeSceneInput', 'assets/image/word/hopaeSceneInput.png', { frameWidth: 239, frameHeight: 45 });
+    scene.load.spritesheet('gameSceneInput', 'assets/image/etc/wordSpace/wordspace.png', { frameWidth: 253, frameHeight: 67 });
+    scene.load.image('attackPaper', 'assets/image/etc/paper_crumbled.png');
+    scene.load.image('itemBag', 'assets/image/etc/itembag2.png');
+    scene.load.image('mat', 'assets/image/etc/mat.png');
+
+    scene.load.image('button', 'assets/placeholder/button.png');
+    scene.load.image('panel', 'assets/placeholder/panel.png');
+    
+    scene.load.image('dialog1', 'assets/image/UI/dialog/dialog1.png');
+    scene.load.image('dialog2', 'assets/image/UI/dialog/dialog2.png');
+    scene.load.image('resultDialog', 'assets/image/UI/dialog/result_background.png');
+    scene.load.image('resultStamp', 'assets/image/UI/dialog/result_stamp.png');
+    scene.load.image('friendlyPlayBtn', 'assets/image/UI/main/friendlyPlay.png');
+    scene.load.image('rankPlayBtn', 'assets/image/UI/main/rankPlay.png');
+    scene.load.image('shopBtn', 'assets/image/UI/main/shop.png');
+    scene.load.image('hopaeManageBtn', 'assets/image/UI/main/hopaeManage.png');
+    scene.load.image('helpBtn', 'assets/image/UI/main/help.png');
+
+    
+    scene.load.image('cancelBtn', 'assets/image/UI/decisionBtn/cancel.png');
+    scene.load.image('confirmBtn', 'assets/image/UI/decisionBtn/confirm.png');
+    scene.load.image('exitBtn', 'assets/image/UI/decisionBtn/exit.png');
+    scene.load.image('noBtn', 'assets/image/UI/decisionBtn/no.png');
+    scene.load.image('spectateBtn', 'assets/image/UI/decisionBtn/spectate.png');
+    scene.load.image('yesBtn', 'assets/image/UI/decisionBtn/yes.png');
+    
+
+    
     scene.load.spritesheet('phase1', 'assets/image/etc/scroll/startPhase/startPhase.png', { frameWidth: 280, frameHeight: 920 });
     scene.load.spritesheet('phase2', 'assets/image/etc/scroll/bonPhase/bonPhase.png', { frameWidth: 280, frameHeight: 920 });
     scene.load.spritesheet('phase3', 'assets/image/etc/scroll/poongPhase/poongPhase.png', { frameWidth: 280, frameHeight: 920 });
-    scene.load.image('attackPaper', 'assets/image/etc/paper_crumbled.png');
-    scene.load.image('panel', 'assets/placeholder/panel.png');
-    scene.load.image('button', 'assets/placeholder/button.png');
-    scene.load.image('itemBag', 'assets/image/etc/itembag2.png');
+    scene.load.spritesheet('tutorialImage', 'assets/image/UI/tutorial/tutorialImages.png', { frameWidth: 1080, frameHeight: 615 });
 }
 
 ResourceLoader.loadAnimation = function(scene)
@@ -77,46 +110,52 @@ ResourceLoader.loadAnimation = function(scene)
         frameRate: 20,
         repeat: 0
     });
-    WordSpace.pyeongminAnims[Enums.characterAnim.sit] = scene.anims.create({
-        key: 'pyeongminSitAnim',
-        frames: scene.anims.generateFrameNumbers('pyeongminSit'),
-        frameRate: 10,
-        repeat: 0
-    });
-    WordSpace.pyeongminAnims[Enums.characterAnim.write] = scene.anims.create({
-        key: 'pyeongminWriteAnim',
-        frames: scene.anims.generateFrameNumbers('pyeongminWrite'),
-        frameRate: 10,
-        repeat: 0
-    });
-    WordSpace.pyeongminAnims[Enums.characterAnim.notBurning] = scene.anims.create({
-        key: 'pyeongminnotBurningAnim',
-        frames: scene.anims.generateFrameNumbers('pyeongminWrite'),
-        frameRate: 10,
-        repeat: -1
-    });
-    WordSpace.pyeongminAnims[Enums.characterAnim.smallBurning] = scene.anims.create({
-        key: 'pyeongminsmallBurningAnim',
-        frames: scene.anims.generateFrameNumbers('pyeongminBurningSmall'),
-        frameRate: 10,
-        repeat: -1
-    });
-    WordSpace.pyeongminAnims[Enums.characterAnim.bigBurning] = scene.anims.create({
-        key: 'pyeongminbigBurningAnim',
-        frames: scene.anims.generateFrameNumbers('pyeongminBurningBig'),
-        frameRate: 10,
-        repeat: -1
-    });
-    WordSpace.pyeongminAnims[Enums.characterAnim.throw] = scene.anims.create({
-        key: 'pyeongminThrowAnim',
-        frames: scene.anims.generateFrameNumbers('pyeongminThrow'),
-        frameRate: 10,
-        repeat: 0
-    });
-    WordSpace.pyeongminAnims[Enums.characterAnim.gameOver] = scene.anims.create({
-        key: 'pyeongminGameOverAnim',
-        frames: scene.anims.generateFrameNumbers('pyeongminGameOver'),
-        frameRate: 10,
-        repeat: 0
-    });
+
+    for(let i = 0; i < 2; i++)
+    {
+        WordSpace.characterAnims[i][Enums.characterAnim.sit] = scene.anims.create({
+            key: Enums.characterSkin[i] + 'SitAnim',
+            frames: scene.anims.generateFrameNumbers(Enums.characterSkin[i] + 'Sit'),
+            frameRate: 10,
+            repeat: 0
+        });
+        WordSpace.characterAnims[i][Enums.characterAnim.write] = scene.anims.create({
+            key: Enums.characterSkin[i] + 'WriteAnim',
+            frames: scene.anims.generateFrameNumbers(Enums.characterSkin[i] + 'Write'),
+            frameRate: 10,
+            repeat: 0
+        });
+        WordSpace.characterAnims[i][Enums.characterAnim.notBurning] = scene.anims.create({
+            key: Enums.characterSkin[i] + 'notBurningAnim',
+            frames: scene.anims.generateFrameNumbers(Enums.characterSkin[i] + 'Write'),
+            frameRate: 10,
+            repeat: -1
+        });
+        WordSpace.characterAnims[i][Enums.characterAnim.smallBurning] = scene.anims.create({
+            key: Enums.characterSkin[i] + 'smallBurningAnim',
+            frames: scene.anims.generateFrameNumbers(Enums.characterSkin[i] + 'BurningSmall'),
+            frameRate: 10,
+            repeat: -1
+        });
+        WordSpace.characterAnims[i][Enums.characterAnim.bigBurning] = scene.anims.create({
+            key: Enums.characterSkin[i] + 'bigBurningAnim',
+            frames: scene.anims.generateFrameNumbers(Enums.characterSkin[i] + 'BurningBig'),
+            frameRate: 10,
+            repeat: -1
+        });
+        WordSpace.characterAnims[i][Enums.characterAnim.throw] = scene.anims.create({
+            key: Enums.characterSkin[i] + 'ThrowAnim',
+            frames: scene.anims.generateFrameNumbers(Enums.characterSkin[i] + 'Throw'),
+            frameRate: 10,
+            repeat: 0
+        });
+        WordSpace.characterAnims[i][Enums.characterAnim.gameOver] = scene.anims.create({
+            key: Enums.characterSkin[i] + 'GameOverAnim',
+            frames: scene.anims.generateFrameNumbers(Enums.characterSkin[i] + 'GameOver'),
+            frameRate: 10,
+            repeat: 0
+        });
+    }
+    
+    
 }
\ No newline at end of file
diff --git a/js/ScenesData.js b/js/ScenesData.js
index 2c67ec57f89b1d11cfa342b912d75f412da69c32..d8360999e1f83d73509aa795a4f19de7a41aff9d 100644
--- a/js/ScenesData.js
+++ b/js/ScenesData.js
@@ -34,157 +34,188 @@ var menuScene = new Phaser.Class(
     
     create: function()
     {
-        BackGround.drawBackground(this);
+        ResourceLoader.loadAnimation(this);
+        BackGround.drawMenu(this);
         Audio.playSound(this, 'login');
-        if(PlayerData.userData.hopae === undefined || PlayerData.userData.hopae.length == 0)
+        ScenesData.menuScene.tutorialFrame = 0;
+        ScenesData.menuScene.tutorialImage = UIObject.createButton(this, UIObject.createLabel(this, game.config.width / 2, game.config.height / 2, 11,
+            'tutorialImage', 1, 'center'), -2, -2, -2,
+            function()  
+            {
+                ScenesData.menuScene.tutorialFrame = (ScenesData.menuScene.tutorialFrame + 1) % 9;
+                if(ScenesData.menuScene.tutorialFrame >= 8)
+                {
+                    ScenesData.menuScene.tutorialImage.getBackground().setFrame(0);
+                    if(PlayerData.userData.hopae === undefined || PlayerData.userData.hopae.length == 0) ScenesData.changeScene('hopaeScene');
+                    else
+                    {
+                        ScenesData.menuScene.tutorialFrame = 0;
+                        ScenesData.menuScene.tutorialImage.setVisible(false);
+                        ScenesData.menuScene.helpBtn.setEnable(true);
+                        ScenesData.menuScene.gameStartBtn.setEnable(true);
+                        ScenesData.menuScene.shopBtn.setEnable(true);
+                        ScenesData.menuScene.hopaeBtn.setEnable(true);
+                        ScenesData.menuScene.currentHopaeBtn.setEnable(true);
+                    }
+                }
+                ScenesData.menuScene.tutorialImage.getBackground().setFrame(ScenesData.menuScene.tutorialFrame);
+            }).setVisible(false);
+            
+        if(PlayerData.userData.hopae === undefined || PlayerData.userData.hopae.length == 0) ScenesData.menuScene.tutorialImage.setVisible(true).popUp(1000);
+        else
         {
-            PlayerData.userData.money += 1;
-            ScenesData.changeScene('hopaeScene');
-            return;
-        }
-        PlayerData.currentHopae = (PlayerData.userData.recentHopae == null) ? PlayerData.userData.hopae[0] : PlayerData.userData.recentHopae;
-        PlayerData.nickname = PlayerData.currentHopae.name;
+            PlayerData.currentHopae = (PlayerData.userData.recentHopae == null) ? PlayerData.userData.hopae[0] : PlayerData.userData.recentHopae;
+            PlayerData.nickname = PlayerData.currentHopae.name;
 
-        this.userName = this.add.text(100, 100, '내 이름 : ' + PlayerData.userData.userName).setOrigin(0, 0.5).setColor('#000000').setDepth(9.9).setPadding(5,5,5,5).setFontSize(40);
-        this.money = this.add.text(100, 200, '소지 엽전 : ' + PlayerData.userData.money).setOrigin(0, 0.5).setColor('#000000').setDepth(9.9).setPadding(5,5,5,5).setFontSize(40);
+            this.userName = this.add.text(250, 75, PlayerData.userData.userName).setOrigin(0, 0.5).setColor('#000000').setDepth(9.9).setPadding(5,5,5,5).setFont('40pt sejongFont');
+            this.money = this.add.text(950, 70, PlayerData.userData.money).setOrigin(1, 0.5).setColor('#ffffff').setDepth(9.9).setPadding(5,5,5,5).setFont('40pt sejongFont');
 
-        this.organizeHopae = function()
-        {
-            this.myHopae = [];
-            this.myHopae.push({
-                    name: PlayerData.currentHopae.name,
-                    type: PlayerData.currentHopae.type,
-                });
-            for(let i = 0; i < PlayerData.userData.hopae.length; i++)
-                if(PlayerData.userData.hopae[i].name != PlayerData.currentHopae.name)
-                    this.myHopae.push({
-                            name: PlayerData.userData.hopae[i].name,
-                            type: PlayerData.userData.hopae[i].type,
+            this.organizeHopae = function()
+            {
+                this.myHopae = [];
+                this.myHopae.push({
+                        name: PlayerData.currentHopae.name,
+                        type: PlayerData.currentHopae.type,
+                    });
+                for(let i = 0; i < PlayerData.userData.hopae.length; i++)
+                    if(PlayerData.userData.hopae[i].name != PlayerData.currentHopae.name)
+                        this.myHopae.push({
+                                name: PlayerData.userData.hopae[i].name,
+                                type: PlayerData.userData.hopae[i].type,
+                            });
+            }
+
+            this.createHopaeMenu = function()
+            {
+                this.hopaeMenuObject = [];
+                for(let i = 0; i < this.myHopae.length; i++)
+                {
+                    let temp = UIObject.createButton(this, UIObject.createLabel(this, 100, 300, 5,
+                        'nameBgr' + ScenesData.menuScene.myHopae[i].name.length, 1, 'left', ScenesData.menuScene.myHopae[i].name, 25, '#ffffff', 0.45, 0.5), 0, 0, 0, 
+                        function()
+                        {
+                            PlayerData.currentHopae = ScenesData.menuScene.myHopae[i];
+                            PlayerData.nickname = ScenesData.menuScene.myHopae[i].name;
+                            ScenesData.menuScene.organizeHopae();
+                            ScenesData.menuScene.currentHopaeBtn.destroy();
+                            ScenesData.menuScene.createCurrentHopae();
+                            ScenesData.menuScene.hopaeMenuObject.forEach(function(element){
+                                ScenesData.menuScene.tweens.add({
+                                    targets: element,
+                                    y: 0,
+                                    duration: 200,
+                                    ease: 'Linear',
+                                    loop: 0,
+                                    onComplete: function(){element.destroy();}
+                                });
+                            });
                         });
-        }
+                    ScenesData.menuScene.tweens.add({
+                        targets: temp,
+                        y: 50 * i,
+                        duration: 500,
+                        ease: 'Bounce',
+                        loop: 0
+                    });
+                    this.hopaeMenuObject.push(temp);
+                }
+            }
 
-        this.createHopaeMenu = function()
-        {
-            this.hopaeMenuObject = [];
-            for(let i = 0; i < this.myHopae.length; i++)
+            this.createCurrentHopae = function()
             {
-                let temp = UIObject.createButton(this, UIObject.createLabel(this, 100, 300, 5,
-                    'nameBgr' + ScenesData.menuScene.myHopae[i].name.length, 1, 'left', ScenesData.menuScene.myHopae[i].name, 25, '#ffffff', 0.45, 0.5), 0, 0, 0, 
+                this.currentHopaeBtn = UIObject.createButton(this, UIObject.createLabel(this, 100, 300, 5,
+                    'nameBgr' + PlayerData.nickname.length, 1, 'left', PlayerData.nickname, 25, '#ffffff', 0.45, 0.5), 0, 0, 0, 
                     function()
                     {
-                        PlayerData.currentHopae = ScenesData.menuScene.myHopae[i];
-                        PlayerData.nickname = ScenesData.menuScene.myHopae[i].name;
-                        ScenesData.menuScene.organizeHopae();
                         ScenesData.menuScene.currentHopaeBtn.destroy();
-                        ScenesData.menuScene.createCurrentHopae();
-                        ScenesData.menuScene.hopaeMenuObject.forEach(function(element){
-                            ScenesData.menuScene.tweens.add({
-                                targets: element,
-                                y: 0,
-                                duration: 200,
-                                ease: 'Linear',
-                                loop: 0,
-                                onComplete: function(){element.destroy();}
-                            });
-                        });
-                    });
-                ScenesData.menuScene.tweens.add({
-                    targets: temp,
-                    y: 50 * i,
-                    duration: 500,
-                    ease: 'Bounce',
-                    loop: 0
-                });
-                this.hopaeMenuObject.push(temp);
+                        ScenesData.menuScene.createHopaeMenu();
+                    })
             }
-        }
 
-        this.createCurrentHopae = function()
-        {
-            this.currentHopaeBtn = UIObject.createButton(this, UIObject.createLabel(this, 100, 300, 5,
-                'nameBgr' + PlayerData.nickname.length, 1, 'left', PlayerData.nickname, 25, '#ffffff', 0.45, 0.5), 0, 0, 0, 
-                function()
-                {
-                    ScenesData.menuScene.currentHopaeBtn.destroy();
-                    ScenesData.menuScene.createHopaeMenu();
-                })
-        }
+            this.organizeHopae();
+            this.createCurrentHopae();
 
-        this.organizeHopae();
-        this.createCurrentHopae();
+            this.myCharacter = this.add.sprite(game.config.width / 2, game.config.height / 2, Enums.characterSkin[PlayerData.userData.skin] + 'Stand')
+                .setOrigin(0.5, 0.5).setDepth(5).setScale(0.8);
 
-        this.myCharacter = this.add.sprite(game.config.width / 2, game.config.height / 2 - 200, 'pyeongminStand').setOrigin(0.5, 0.5).setDepth(5).setScale(0.8);
+            this.roomEnterDialog = this.rexUI.add.dialog({
+                x: game.config.width / 2,
+                y: game.config.height / 2,
 
-        this.roomEnterDialog = this.rexUI.add.dialog({
-            x: game.config.width / 2,
-            y: game.config.height / 2,
+                background: this.add.sprite(game.config.width / 2, game.config.height / 2, 'dialog1').setOrigin(0.5, 0.5),
+                
+                content: this.add.text(game.config.width / 2, game.config.height / 2, '대기실에 참가하시겠습니까?', {
+                    font: '50pt sejongFont'
+                }).setColor('#000000'),
 
-            background: this.add.sprite(game.config.width / 2, game.config.height / 2, 'panel').setOrigin(0.5, 0.5),
-            
-            content: this.add.text(0, 0, '대기실에 참가하시겠습니까?', {
-                font: '50pt sejongFont'
-            }),
+                actions: [
+                    UIObject.createLabel(this, 0, 0, 0, 'yesBtn', 1, 'center', '                      '),
+                    UIObject.createLabel(this, 0, 0, 0, 'noBtn', 1, 'center', '                      ')
+                ],
 
-            actions: [
-                UIObject.createLabel(this, 0, 0, 0, 'button', 1, 'center', '예', 50),
-                UIObject.createLabel(this, 0, 0, 0, 'button', 1, 'center', '아니오', 50)
-            ],
+                space: {
+                    content: 25, action: 100,
 
-            space: {
-                content: 25,
-                action: 100,
+                    left: 50, right: 50, top: 50, bottom: 50,
+                },
 
-                left: 20,
-                right: 20,
-                top: 20,
-                bottom: 20,
-            },
+                align: {
+                    actions: 'center' // 'center'|'left'|'right'
+                },
 
-            align: {
-                actions: 'center' // 'center'|'left'|'right'
-            },
+                expand: {
+                    content: false, // Content is a pure text object
+                }
+            }).layout().setDepth(11).setVisible(false);
 
-            expand: {
-                content: false, // Content is a pure text object
-            }
-        }).layout().setDepth(11).setVisible(false);
+            this.roomEnterDialog
+                .on('button.click', function (button, groupName, index) {
+                    if(index == 0) socket.emit('enterRoom', {nickname: PlayerData.nickname, skin: PlayerData.userData.skin});
+                    else
+                    {
+                        this.roomEnterDialog.setVisible(false);
+                        this.gameStartBtn.setEnable(true);
+                    }
+                }, this)
+                .on('button.over', function (button, groupName, index) {
+                    //console.log('button over');
+                })
+                .on('button.out', function (button, groupName, index) {
+                    //console.log('button out');
+            });
 
-        this.roomEnterDialog
-            .on('button.click', function (button, groupName, index) {
-                if(index == 0) socket.emit('enterRoom', PlayerData.nickname);
-                else
+            
+            this.gameStartBtn = UIObject.createButton(this, UIObject.createLabel(this, game.config.width / 2, 950, 5, 'friendlyPlayBtn', 1, 'center', '게임 시작', 50), -1, -1, -1, 
+                function()
                 {
-                    this.roomEnterDialog.setVisible(false);
-                    this.gameStartBtn.setEnable(true);
-                }
-            }, this)
-            .on('button.over', function (button, groupName, index) {
-                //console.log('button over');
-            })
-            .on('button.out', function (button, groupName, index) {
-                //console.log('button out');
-        });
-
-        
-        this.gameStartBtn = UIObject.createButton(this, UIObject.createLabel(this, game.config.width / 2, 900, 5, 'pyeongminWrite', 0.5, 'center'), 1, 0, 2, 
-            function()
-            {
-                ScenesData.menuScene.gameStartBtn.setEnable(false);
-                ScenesData.menuScene.roomEnterDialog.setVisible(true);
-                ScenesData.menuScene.roomEnterDialog.popUp(200);
-            })
-        
-        this.shopBtn = UIObject.createButton(this, UIObject.createLabel(this, game.config.width - 100, 900, 5, 'pyeongminThrow', 0.5, 'center'), 1, 0, 2, 
-            function()
-            {
-                console.log('상점 입장');
-            })
-        
-        this.hopaeBtn = UIObject.createButton(this, UIObject.createLabel(this, 100, 900, 5, 'pyeongminThrow', 0.5, 'center'), 1, 0, 2, 
-            function()
-            {
-                ScenesData.changeScene('hopaeScene');
-            })
+                    ScenesData.menuScene.gameStartBtn.setEnable(false);
+                    ScenesData.menuScene.roomEnterDialog.setVisible(true);
+                    ScenesData.menuScene.roomEnterDialog.popUp(200);
+                })
+            
+            this.shopBtn = UIObject.createButton(this, UIObject.createLabel(this, game.config.width - 100, 950, 5, 'shopBtn', 1, 'center'), -1, -1, -1, 
+                function()
+                {
+                    ScenesData.changeScene('shopScene');
+                })
+            
+            this.hopaeBtn = UIObject.createButton(this, UIObject.createLabel(this, 100, 950, 5, 'hopaeManageBtn', 1, 'center'), -1, -1, -1, 
+                function()
+                {
+                    if(PlayerData.userData.hopae.length > 4) console.log('호패가 5개입니다.');
+                    else ScenesData.changeScene('hopaeScene');
+                })
+            this.helpBtn = UIObject.createButton(this, UIObject.createLabel(this, game.config.width - 100, 75, 5, 'helpBtn', 1, 'center'), -1, -1, -1, 
+                function()
+                {
+                    ScenesData.menuScene.tutorialImage.setVisible(true).popUp(200);
+                    ScenesData.menuScene.helpBtn.setEnable(false);
+                    ScenesData.menuScene.gameStartBtn.setEnable(false);
+                    ScenesData.menuScene.shopBtn.setEnable(false);
+                    ScenesData.menuScene.hopaeBtn.setEnable(false);
+                    ScenesData.menuScene.currentHopaeBtn.setEnable(false);
+                })
+        }
     }
 });
 
@@ -216,65 +247,56 @@ var hopaeScene = new Phaser.Class(
 
     create: function()
     {
-        BackGround.drawBackground(this);
-        
-        Input.inputField.generate(this, function(){}, 
-            UIObject.createLabel(this, game.config.width / 2, game.config.height / 2, 10, 'nameBgr6', 2, 'center', '', 50, '#ffffff').getElement('text').setOrigin(0.45,0.5), true);
-            
-        UIObject.createLabel(this, game.config.width / 2, game.config.height / 2 - 200, 2, 'panel', 1, 'center', 
+        BackGround.drawMenu(this);
+        if(!(PlayerData.userData.hopae === undefined || PlayerData.userData.hopae.length == 0))
+        {
+            this.userName = this.add.text(250, 75, PlayerData.userData.userName).setOrigin(0, 0.5).setColor('#000000').setDepth(9.9).setPadding(5,5,5,5).setFont('40pt sejongFont');
+            this.money = this.add.text(950, 70, PlayerData.userData.money).setOrigin(1, 0.5).setColor('#ffffff').setDepth(9.9).setPadding(5,5,5,5).setFont('40pt sejongFont');
+        }
+        this.inputBackground = UIObject.createLabel(this, game.config.width / 2, game.config.height / 2, 10, 'hopaeSceneInput', 2, 'center', '', 50, '#ffffff', 0.45, 0.5);
+        Input.inputField.generate(this, function(){}, this.inputBackground);
+        UIObject.createLabel(this, game.config.width / 2, game.config.height / 2 - 200, 2, 'dialog2', 1, 'center', 
             '호패는 오직 한글만 입력이 가능합니다.\n띄어쓰기도 사용할 수 없습니다.', 50, '#000000').layout();
 
         this.checkDialog = this.rexUI.add.dialog({
             x: game.config.width / 2,
             y: game.config.height / 2,
 
-            background: this.add.sprite(game.config.width / 2, game.config.height / 2, 'panel').setOrigin(0.5, 0.5),
+            background: this.add.sprite(game.config.width / 2, game.config.height / 2, 'dialog1').setOrigin(0.5, 0.5),
             
-            content: this.add.text(0, 0, '이 이름으로 하시겠습니까?' + (PlayerData.userData.hopae.length == 0 ? '\n(최초 호패는 비용이 들지 않습니다.)' : '\n변경에는 엽전이 소모됩니다.'), {
-                font: '50pt sejongFont',
-                color: '#000000',
-                align: 'center'
+            content: this.add.text(0, 0, '이 이름으로 하시겠습니까?' + (PlayerData.userData.hopae === undefined || PlayerData.userData.hopae.length == 0 ? 
+                '\n(최초 호패는 비용이 들지 않습니다.)' : '\n변경에는 엽전이 소모됩니다.'), {
+                font: '50pt sejongFont', color: '#000000', align: 'center'
             }),
 
             actions: [
-                UIObject.createLabel(this, 0, 0, 0, 'button', 1, 'center', '예', 50),
-                UIObject.createLabel(this, 0, 0, 0, 'button', 1, 'center', '아니오', 50)
+                UIObject.createLabel(this, 0, 0, 0, 'yesBtn', 1, 'center', '                      '),
+                UIObject.createLabel(this, 0, 0, 0, 'noBtn', 1, 'center', '                      ')
             ],
 
             space: {
-                content: 25,
-                action: 100,
-
-                left: 20,
-                right: 20,
-                top: 20,
-                bottom: 20,
-            },
-
-            align: {
-                actions: 'center' // 'center'|'left'|'right'
+                content: 25, action: 100,
+                left: 50, right: 50, top: 50, bottom: 50,
             },
 
-            expand: {
-                content: false, // Content is a pure text object
-            }
+            align: { actions: 'center' },
+            expand: { content: false }
         }).layout().setDepth(11).setVisible(false);
 
         this.checkDialog
         .on('button.click', function (button, groupName, index) {
             if(index == 0)
             {
-                if(PlayerData.userData.money > 0)
+                if(PlayerData.userData.hopae === undefined || PlayerData.userData.hopae.length == 0 || PlayerData.userData.money > 0)
                 {
                     fbClient.updateUserData('hopae', {name: Input.inputField.text.text, type: 'wood'});
-                    fbClient.updateUserData('money', -1);
+                    if(PlayerData.userData.hopae === undefined || PlayerData.userData.hopae.length == 0) fbClient.updateUserData('money', -1);
                     ScenesData.changeScene('menuScene');
                 }
                 else
                 {
                     this.checkDialog.setVisible(false);
-
-                    this.errorMsg = UIObject.createButton(this, UIObject.createLabel(this, game.config.width / 2, game.config.height / 2, 10, 'panel', 1, 'center', 
+                    this.errorMsg = UIObject.createButton(this, UIObject.createLabel(this, game.config.width / 2, game.config.height / 2, 10, 'dialog1', 1, 'center', 
                         '엽전이 부족합니다', 50, '#000000').layout().popUp(200), 0, 0, 0, 
                         function()
                         {
@@ -295,10 +317,9 @@ var hopaeScene = new Phaser.Class(
         .on('button.out', function (button, groupName, index) {
             //console.log('button out');
         });
-        this.warningText = UIObject.createLabel(this, game.config.width / 2, game.config.height / 2 - 100, 5, 'panel', 1, 'center', 
+        this.warningText = UIObject.createLabel(this, game.config.width / 2, game.config.height / 2 - 100, 5, 'dialog1', 1, 'center', 
             '이름 타수가 많아 플레이에 패널티가 있을 수 있습니다', 40, '#000000').setVisible(false).layout();
-            
-        this.checkBtn = UIObject.createButton(this, UIObject.createLabel(this, game.config.width / 2, 900, 5, 'pyeongminWrite', 0.5, 'center'), 1, 0, 2, 
+        this.checkBtn = UIObject.createButton(this, UIObject.createLabel(this, game.config.width / 2, 900, 5, 'confirmBtn', 1, 'center', '                      '), -2, -2, -2, 
             function()
             {
                 if(Input.checkProperInput(Input.inputField.text.text))
@@ -306,10 +327,10 @@ var hopaeScene = new Phaser.Class(
                     ScenesData.hopaeScene.checkBtn.setEnable(false);
                     ScenesData.hopaeScene.checkDialog.setVisible(true).popUp(200);
                 }
-            })
+            }).setEnable(false);
         if(!(PlayerData.userData.hopae === undefined || PlayerData.userData.hopae.length == 0))
         {
-            this.backBtn = UIObject.createButton(this, UIObject.createLabel(this, 100, 900, 5, 'pyeongminWrite', 0.5, 'center'), 1, 0, 2, 
+            this.backBtn = UIObject.createButton(this, UIObject.createLabel(this, 200, 900, 5, 'exitBtn', 1, 'center', '                      '), -2, -2, -2, 
             function()
             {
                 ScenesData.changeScene('menuScene');
@@ -318,6 +339,135 @@ var hopaeScene = new Phaser.Class(
     }
 });
 
+var shopScene = new Phaser.Class(
+{
+    Extends: Phaser.Scene,
+
+    initialize: 
+
+    function shopScene ()
+    {
+        Phaser.Scene.call(this, {key: 'shopScene'});
+    },
+
+    preload: function()
+    {
+        ScenesData.shopScene = this;
+        this.load.scenePlugin({
+            key: 'rexuiplugin',
+            url: 'https://raw.githubusercontent.com/rexrainbow/phaser3-rex-notes/master/plugins/dist/rexuiplugin.min.js',
+            sceneKey: 'rexUI'
+        });
+        this.load.scenePlugin({
+            key: 'rexbuttonplugin',
+            url: 'https://raw.githubusercontent.com/rexrainbow/phaser3-rex-notes/master/plugins/dist/rexbuttonplugin.min.js',
+            sceneKey: 'button'
+        });
+    },
+
+    create: function()
+    {
+        BackGround.drawBackground(this);
+
+        this.currentSkin = this.add.sprite(500, game.config.height / 2, Enums.characterSkin[PlayerData.userData.skin] + 'Stand')
+            .setOrigin(0.5, 0.5).setDepth(5).setScale(0.8);
+        this.money = this.add.text(200, 70, PlayerData.userData.money + "냥").setOrigin(1, 0.5).setColor('#000000').setDepth(9.9).setPadding(5,5,5,5).setFont('40pt sejongFont');
+
+
+
+        this.pyeongminItem = {
+            price: 0,
+            itemName: this.add.text(game.config.width - 500, 300, '평민').setOrigin(1, 0.5).setColor('#000000').setDepth(9.9).setPadding(5,5,5,5).setFont('40pt sejongFont'),
+            itemPrice: this.add.text(game.config.width - 200, 300, '0냥').setOrigin(1, 0.5).setColor('#000000').setDepth(9.9).setPadding(5,5,5,5).setFont('40pt sejongFont'),
+            buyBtn: UIObject.createButton(this, UIObject.createLabel(this, game.config.width - 600, 300, 5, 'button', 1, 'center', '구매하기'), -1, -1, -1, 
+                function()
+                {
+                    if(PlayerData.userData.money >= ScenesData.shopScene.pyeongminItem.price)
+                    {
+                        ScenesData.shopScene.pyeongminItem.buyBtn.setVisible(false);
+                        ScenesData.shopScene.pyeongminItem.itemPrice.setText('보유중');
+                        fbClient.updateUserData('item', 0);
+                        fbClient.updateUserData('money', -ScenesData.shopScene.pyeongminItem.price);
+                        ScenesData.shopScene.money.setText(PlayerData.userData.money + '냥');
+                        ScenesData.shopScene.pyeongminItem.useBtn.setVisible(true);
+                    }
+                }),
+            useBtn: UIObject.createButton(this, UIObject.createLabel(this, game.config.width - 800, 300, 5, 'button', 1, 'center', '사용하기'), -1, -1, -1, 
+                function()
+                {
+                    if(PlayerData.userData.item.includes(0))
+                    {
+                        ScenesData.shopScene.pyeongminItem.useBtn.setVisible(false);
+                        ScenesData.shopScene.sunbiItem.useBtn.setVisible(true);
+                        fbClient.updateUserData('skin', 0);
+                        ScenesData.shopScene.currentSkin.destroy();
+                        ScenesData.shopScene.currentSkin = ScenesData.shopScene.add.sprite(500, game.config.height / 2, Enums.characterSkin[PlayerData.userData.skin] + 'Stand')
+                            .setOrigin(0.5, 0.5).setDepth(5).setScale(0.8);
+                    }
+                })
+        }
+        
+        this.pyeongminItem.buyBtn.setEnable(PlayerData.userData.money < ScenesData.shopScene.pyeongminItem.price ? false : true);
+        if(PlayerData.userData.item.includes(0))
+        {
+            this.pyeongminItem.buyBtn.setVisible(false);
+            this.pyeongminItem.itemPrice.setText('보유중');
+        }
+        if(PlayerData.userData.skin == 0 || !PlayerData.userData.item.includes(0)) this.pyeongminItem.useBtn.setVisible(false);
+        
+
+
+        this.sunbiItem = {
+            price: 100,
+            itemName: this.add.text(game.config.width - 500, 400, '선비').setOrigin(1, 0.5).setColor('#000000').setDepth(9.9).setPadding(5,5,5,5).setFont('40pt sejongFont'),
+            itemPrice: this.add.text(game.config.width - 200, 400, '100냥').setOrigin(1, 0.5).setColor('#000000').setDepth(9.9).setPadding(5,5,5,5).setFont('40pt sejongFont'),
+            buyBtn: UIObject.createButton(this, UIObject.createLabel(this, game.config.width - 800, 400, 5, 'button', 1, 'center', '구매하기'), -1, -1, -1, 
+                function()
+                {
+                    if(PlayerData.userData.money >= ScenesData.shopScene.sunbiItem.price)
+                    {
+                        ScenesData.shopScene.sunbiItem.buyBtn.setVisible(false);
+                        ScenesData.shopScene.sunbiItem.itemPrice.setText('보유중');
+                        fbClient.updateUserData('item', 1);
+                        fbClient.updateUserData('money', -ScenesData.shopScene.sunbiItem.price);
+                        ScenesData.shopScene.money.setText(PlayerData.userData.money + '냥');
+                        ScenesData.shopScene.sunbiItem.useBtn.setVisible(true);
+                    }
+                }),
+            useBtn: UIObject.createButton(this, UIObject.createLabel(this, game.config.width - 800, 400, 5, 'button', 1, 'center', '사용하기'), -1, -1, -1, 
+                function()
+                {
+                    if(PlayerData.userData.item.includes(1))
+                    {
+                        ScenesData.shopScene.sunbiItem.useBtn.setVisible(false);
+                        ScenesData.shopScene.pyeongminItem.useBtn.setVisible(true);
+                        fbClient.updateUserData('skin', 1);
+                        ScenesData.shopScene.currentSkin.destroy();
+                        ScenesData.shopScene.currentSkin = ScenesData.shopScene.add.sprite(500, game.config.height / 2, Enums.characterSkin[PlayerData.userData.skin] + 'Stand')
+                            .setOrigin(0.5, 0.5).setDepth(5).setScale(0.8);
+                    }
+                })
+        }
+        
+        this.sunbiItem.buyBtn.setEnable(PlayerData.userData.money < ScenesData.shopScene.sunbiItem.price ? false : true);
+        if(PlayerData.userData.item.includes(1))
+        {
+            this.sunbiItem.buyBtn.setVisible(false);
+            this.sunbiItem.itemPrice.setText('보유중');
+        }
+        if(PlayerData.userData.skin == 1 || !PlayerData.userData.item.includes(1)) this.sunbiItem.useBtn.setVisible(false);
+
+        
+            
+        this.backBtn = UIObject.createButton(this, UIObject.createLabel(this, 200, 900, 5, 'exitBtn', 1, 'center', '                      '), -2, -2, -2, 
+        function()
+        {
+            ScenesData.changeScene('menuScene');
+        });
+    }
+});
+
+
 var roomScene = new Phaser.Class(
 {
     Extends: Phaser.Scene,
@@ -438,7 +588,6 @@ var gameScene = new Phaser.Class(
     {
         WordSpace.gameTimer = new Phaser.Time.Clock(this);
         WordSpace.gameTimer.start();
-        ResourceLoader.loadAnimation(this);
         CSVParsing.CSVParse(this);
         BackGround.drawBackground(this);
         BackGround.drawBrain(this);
@@ -456,7 +605,7 @@ var gameScene = new Phaser.Class(
         WordSpace.wordPhysicsGroup = this.physics.add.group();
             
         Input.inputField.generate(this, Input.gameSceneEnterReaction, 
-            UIObject.createLabel(ScenesData.gameScene, game.config.width / 2, game.config.height * 25 / 36, 10, 'inputfield', 1, 'center', '', 25, '#000000').getElement('text'));
+            UIObject.createLabel(ScenesData.gameScene, game.config.width / 2, game.config.height * 25 / 36, 10, 'gameSceneInput', 1, 'center', '', 25, '#000000'));
         
         WordSpace.attackGauge.generate(this);
         WordSpace.spaceInitiate(this);
@@ -464,8 +613,6 @@ var gameScene = new Phaser.Class(
 
         WordSpace.startCycle(this);
         
-        WordSpace.setPlayerTyping.initiate(this);
-        
         WordSpace.nameQueue.initiate();
         
         this.warningImage = this.add.sprite(game.config.width / 2, game.config.height / 2, 'weightWarning').setDisplaySize(game.config.width, game.config.height).setDepth(0.1).setAlpha(0)
@@ -488,17 +635,9 @@ var gameScene = new Phaser.Class(
         if(ScenesData.currentScene == ScenesData.gameScene && WordSpace.gameTimer != null)
         {
             WordSpace.deltaTime = this.sys.game.loop.delta;
-            WordSpace.wordForcedGroup.forEach(function(element)
-            {
-                element.attract();
-            });
-            WordSpace.nameGroup.forEach(function(element)
-            {
-                element.attract();
-            })
-            WordSpace.attackPaperGroup.getChildren().forEach(function(element){
-                element.moveObject(element);
-            });
+            WordSpace.wordForcedGroup.forEach(function(element) { element.attract(); });
+            WordSpace.nameGroup.forEach(function(element) { element.attract(); });
+            WordSpace.attackPaperGroup.getChildren().forEach(function(element) { element.moveObject(element); });
             
             WordSpace.setPlayerTyping.add('');
 
diff --git a/js/UIObject.js b/js/UIObject.js
index 189b28f9189342ded8c0e0b11eea6c9a5ebff0e8..4c98c3d909384fe800eda7360c558552aa634923 100644
--- a/js/UIObject.js
+++ b/js/UIObject.js
@@ -12,7 +12,7 @@ UIObject.createLabel = function (scene, x, y, depth, image, size, align, text =
         text: scene.add.text(x, y, text, {
             font: textSize + 'pt sejongFont',
             align: 'center'
-        }).setDepth(depth).setOrigin(textOriginX, textOriginY).setColor(textColor),
+        }).setDepth(depth).setOrigin(textOriginX, textOriginY).setColor(textColor).setPadding(30, 30, 30, 30),
 
         space: {
             left: 10,
@@ -52,33 +52,41 @@ UIObject.createButton = function(scene, buttonGameObject, overFrame, outFrame, d
             clickInterval: 100
         }
     });
-    buttonGameObject = buttonGameObject.getElement('background');
+    let buttonGameObjectBackground = buttonGameObject.getElement('background');
     temp.enabled = true;    
-    buttonGameObject.setFrame(outFrame).setInteractive()
+    buttonGameObjectBackground.setFrame(outFrame > 0 ? outFrame : 0).setInteractive()
     .on('pointerover', () => {
         if(temp.enabled)
         {
-            buttonGameObject.setFrame(overFrame);
+            if(overFrame > 0) buttonGameObjectBackground.setFrame(overFrame);
+            if(overFrame != -2) buttonGameObject.setScale(1.1);
         }
     })
     .on('pointerdown', () => {
         if(temp.enabled)
         {
-            buttonGameObject.setFrame(downFrame);
+            if(downFrame > 0) buttonGameObjectBackground.setFrame(downFrame);
+            if(downFrame != -2) buttonGameObject.setScale(0.9);
             clickCallback();
         }
     })
     .on('pointerup', () => {
-        buttonGameObject.setFrame(overFrame);
+        if(temp.enabled)
+        {
+            if(overFrame > 0) buttonGameObjectBackground.setFrame(overFrame);
+            if(overFrame != -2) buttonGameObject.setScale(1.1);
+        }
     })
     .on('pointerout', () => {
-        buttonGameObject.setFrame(outFrame);
+        if(outFrame > 0) buttonGameObjectBackground.setFrame(outFrame);
+        if(outFrame != -2) buttonGameObject.setScale(1);
     })
     temp.setEnable = function(isEnable)
     {
         temp.enabled = isEnable;
         return temp;
     }
+    temp.getBackground = function() { return buttonGameObjectBackground; }
 
     return temp;
 }
\ No newline at end of file
diff --git a/js/WordObject.js b/js/WordObject.js
index 0d64576cb3f3776e7a02febbe6039dca3ae4ce60..257e3fc9f2819925690b6ce1c910b4f60a34163d 100644
--- a/js/WordObject.js
+++ b/js/WordObject.js
@@ -57,10 +57,6 @@ class WordObject
         setTimeout(function() {
             breakAnim.destroy();
         }, 200);
-        RoomData.myself.playerImage.play(WordSpace.pyeongminAnims[Enums.characterAnim.write]);
-        RoomData.myself.playerImage.anims.chain(WordSpace.pyeongminAnims[Enums.characterAnim.sit]);
-
-        Audio.playSound(ScenesData.gameScene, 'killWord');
     }
     
     attract()
@@ -112,6 +108,9 @@ class NormalWord extends WordObject
         super.destroy();
         if(isNormallyRemoved)
         {
+            Audio.playSound(ScenesData.gameScene, 'killWord');
+            RoomData.myself.playerImage.play(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.write]);
+            RoomData.myself.playerImage.anims.chain(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.sit]);
             switch(this.wordGrade)
             {
                 case 0: WordSpace.attackGauge.add(2.5); break;
@@ -150,8 +149,8 @@ class AttackWord extends WordObject
         let textColor = '#000000'
         super.instantiate(scene, spriteName, textColor, lenRate);
         this.maskBackground = scene.physics.add.sprite(this.physicsObj.x, this.physicsObj.y, 'wordBgr' + this.wordGrade + '_' + Math.min(Math.max(2, this.wordText.length), 6))
-        .setTint(Phaser.Display.Color.GetColor(120, 120, 120)).setScale(this.scale);
-        this.maskBackground.alpha = this.isDark ? 1 : 0.5;
+        .setTint(Phaser.Display.Color.GetColor(40, 40, 40)).setScale(this.scale).setDepth(1.1);
+        this.maskBackground.alpha = this.isDark ? 1 : 0.7;
         this.shape = scene.make.graphics();
         var rect = new Phaser.Geom.Rectangle(0, 0, this.maskBackground.width * this.scale, this.maskBackground.height * this.scale);
         this.shape.fillStyle(0xffffff).fillRectShape(rect);
@@ -191,6 +190,9 @@ class AttackWord extends WordObject
         super.destroy();
         if(isNormallyRemoved)
         {
+            Audio.playSound(ScenesData.gameScene, 'killWord');
+            RoomData.myself.playerImage.play(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.write]);
+            RoomData.myself.playerImage.anims.chain(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.sit]);
             switch(this.wordGrade)
             {
                 case 0: WordSpace.attackGauge.add(2.5); break;
@@ -261,10 +263,7 @@ class NameWord extends WordObject
             if(this.isStrong)
             {
                 this.physicsObj.setScale(this.follower.t < 0.2 ? 0.2 : this.follower.t * this.scale);
-                this.wordObj.setFont({
-                    font: (this.follower.t < 0.2 ? 0.05 : this.follower.t * this.scale * this.fontScale) +'pt sejongFont',
-                    fontStyle: (this.wordWeight > 5 ? 'bold' : '')
-                });
+                this.wordObj.setScale((this.follower.t < 0.2 ? 0.2 : this.follower.t * this.scale) * 0.9);
             }
         }
     }
@@ -273,6 +272,9 @@ class NameWord extends WordObject
         super.destroy();
         if(isNormallyRemoved)
         {
+            Audio.playSound(ScenesData.gameScene, 'killWord');
+            RoomData.myself.playerImage.play(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.write]);
+            RoomData.myself.playerImage.anims.chain(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.sit]);
             ScenesData.gameScene.physics.world.removeCollider(this.physicsObj.wordCollider);
             WordSpace.wordGroup.forEach(function(element)
             {
@@ -300,10 +302,6 @@ class NameWord extends WordObject
                 duration: 2000,
                 repeat: 0
             });
-            //이동경로 디버그
-            /*var graphics = ScenesData.gameScene.add.graphics();
-            graphics.lineStyle(2, 0xffffff, 1);
-            this.path.draw(graphics);*/
         }
     }
 }
@@ -358,6 +356,9 @@ class ItemWord extends WordObject
         super.destroy();
         if(isNormallyRemoved)
         {
+            Audio.playSound(ScenesData.gameScene, 'killWord');
+            RoomData.myself.playerImage.play(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.write]);
+            RoomData.myself.playerImage.anims.chain(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.sit]);
             WordSpace.attackGauge.add(0.5);
             switch(this.itemType)
             {
diff --git a/js/WordSpace.js b/js/WordSpace.js
index a9d9896940222836306b5d7dad5ee9792d254070..8e4491c0ea027be42ea0822e15f89f265331a5f2 100644
--- a/js/WordSpace.js
+++ b/js/WordSpace.js
@@ -12,6 +12,9 @@ WordSpace.isTimerOn = false;
 WordSpace.isInvincible = false;
 WordSpace.pyeongminAnims = [];
 
+WordSpace.characterAnims = Array(2).fill(null).map(() => Array());
+
+
 WordSpace.wordGroup = [];
 WordSpace.nameGroup = [];
 WordSpace.attackPaperGroup = null;
@@ -117,14 +120,12 @@ WordSpace.attackGauge =
         if (this.value + plus > 11) this.value = 11;
         else this.value += plus;
         this.setRect();
-        this.text.setText('게이지: ' + this.value.toFixed(1));
     },
     sub: function(minus)
     {
         if (this.value - minus < 0) this.value = 0;
         else this.value -= minus;
         this.setRect();
-        this.text.setText('게이지: ' + this.value.toFixed(1));
     },
     resetValue: function() {this.value = 0;},
     cutValue: function(cutOut) {this.value *= (1-cutOut);},
@@ -141,7 +142,6 @@ WordSpace.attackGauge =
         };
         this.currentCycle = scene.time.addEvent(option);
 
-        this.text = scene.add.text(100,100,'게이지: ' + this.value.toFixed(1)).setDepth(9.9).setColor('#000000');
         //this.rectUI.setColor(this.gradeColor[0]);
     },
     pauseCycle: function(bool) {this.currentCycle.paused = bool;},
@@ -195,7 +195,6 @@ WordSpace.generateWord =
     Item: function(scene, itemType, lenRate)
     {
         word = new ItemWord(itemType);
-        Audio.playSound(ScenesData.gameScene, 'getItem');
         WordSpace.pushWord(scene, word, lenRate);
         return word;
     }
@@ -266,7 +265,7 @@ WordSpace.findWord = function(wordText)
         }
         WordSpace.setPlayerTyping.add(wordText);
     }
-    else if (wordText === '공격' && WordSpace.attackGauge.value >= 3 && WordSpace.nameGroup.length > 0) // 공격모드 진입.
+    else if (wordText === '공격' && WordSpace.attackGauge.value >= 2 && WordSpace.nameGroup.length > 0) // 공격모드 진입.
     {
         console.log('attack mode');
         let tempAttackOption = this.attackGauge.getAttackOption();
@@ -274,21 +273,22 @@ WordSpace.findWord = function(wordText)
         Input.attackOption.wordGrade = tempAttackOption.wordGrade;
         Input.maxInput = Input.attackOption.wordCount;
         Input.attackMode = true;
+        Input.inputField.inputBackground.setFrame(Input.maxInput - 2);
         WordSpace.attackGauge.pauseCycle(true);
         WordSpace.setPlayerTyping.add(wordText);
         switch(tempAttackOption.wordCount)
         {
             case 2:
-                RoomData.myself.playerImage.play(WordSpace.pyeongminAnims[Enums.characterAnim.notBurning]);
+                RoomData.myself.playerImage.play(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.notBurning]);
                 break;
             case 3:
-                RoomData.myself.playerImage.play(WordSpace.pyeongminAnims[Enums.characterAnim.smallBurning]);
+                RoomData.myself.playerImage.play(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.smallBurning]);
                 break;
             case 4:
-                RoomData.myself.playerImage.play(WordSpace.pyeongminAnims[Enums.characterAnim.smallBurning]);
+                RoomData.myself.playerImage.play(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.smallBurning]);
                 break;
             case 5:
-                RoomData.myself.playerImage.play(WordSpace.pyeongminAnims[Enums.characterAnim.bigBurning]);
+                RoomData.myself.playerImage.play(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.bigBurning]);
                 break;
             default:
                 console.log('Improper attack option.');
@@ -337,13 +337,8 @@ WordSpace.setPlayerTyping =
     {
         this.totalTyping += wordText != null ? WordReader.getWordTyping(wordText) : 0;
         WordSpace.playerTyping = this.totalTyping / WordSpace.gameTimer.now * 60 * 1000;
-        this.text.setText('현재 타수 : ' + WordSpace.playerTyping.toFixed(1));
         this.writeWord = wordText != '' ? true : false;
     },
-    initiate: function(scene)
-    {
-        this.text = scene.add.text(100,200,'현재 타수 : ' + WordSpace.playerTyping.toFixed(1)).setDepth(9.9).setColor('#000000');
-    },
     reset: function()
     {
         this.totalTyping = 0;
@@ -403,8 +398,8 @@ WordSpace.attack = function(wordText, grade)
 
         WordSpace.attackGauge.resetValue();
         WordSpace.setPlayerTyping.add(wordText);
-        RoomData.myself.playerImage.play(WordSpace.pyeongminAnims[Enums.characterAnim.throw]);
-        RoomData.myself.playerImage.anims.chain(WordSpace.pyeongminAnims[Enums.characterAnim.sit]);
+        RoomData.myself.playerImage.play(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.throw]);
+        RoomData.myself.playerImage.anims.chain(WordSpace.characterAnims[PlayerData.userData.skin][Enums.characterAnim.sit]);
         Input.attackOption.isHeavy = false;
         Input.attackOption.isDark = false;
     }
@@ -474,12 +469,8 @@ WordSpace.nameQueue =
     getCount: function(player)
     {
         WordSpace.nameQueue.counter = 0;
-        WordSpace.nameGroup.forEach(function(element){
-            if(element.id == player.id) WordSpace.nameQueue.counter++;
-        })
-        WordSpace.wordGroup.forEach(function(element){
-            if(element instanceof NameWord && element.ownerId == player.id) WordSpace.nameQueue.counter++;
-        })
+        WordSpace.nameGroup.forEach(function(element){ if(element.ownerId == player.id) WordSpace.nameQueue.counter++; });
+        WordSpace.wordGroup.forEach(function(element){ if(element instanceof NameWord && element.ownerId == player.id) WordSpace.nameQueue.counter++; });
         return WordSpace.nameQueue.counter;
     },
     counter: 0,
@@ -503,7 +494,8 @@ WordSpace.changePhase = function(newPhase)
 
     //WordSpace.pauseCycle(true);
     // 여기서 종이 드르륵 열면됨
-    let phaseChangeBgr = ScenesData.gameScene.add.sprite(game.config.width / 2, game.config.height / 2, 'phase' + newPhase).setOrigin(0.5, 0.5).setDepth(9.9).play('phase' + newPhase + 'Anim');
+    let phaseChangeBgr = ScenesData.gameScene.add.sprite(game.config.width / 2, game.config.height / 2, 'phase' + newPhase).setOrigin(0.5, 0.5).setDepth(9.9)
+        .play('phase' + newPhase + 'Anim');
     //ScenesData.gameScene.scene.pause('gameScene');
     setTimeout(function()
     {
@@ -526,7 +518,6 @@ WordSpace.resetGame = function()
     WordSpace.isGameOver = false;
     WordSpace.isTimerOn = false;
     WordSpace.isInvincible = false;
-    WordSpace.pyeongminAnims = [];
 
     WordSpace.wordGroup = [];
     WordSpace.nameGroup = [];
diff --git a/js/main.js b/js/main.js
index bd670fe2e9d623bf31c748ab32d95644e35347b5..d428a83b5885640ba9b3364a26fd76fdd1f66b1a 100644
--- a/js/main.js
+++ b/js/main.js
@@ -14,7 +14,7 @@ var config = {
         }
     },
     backgroundColor: Phaser.Display.Color.HexStringToColor('#ffffff').color,//GetColor(245,208,138),
-    scene: [ menuScene, hopaeScene, roomScene, gameScene ]
+    scene: [ menuScene, hopaeScene, shopScene, roomScene, gameScene ]
 };
 
 var game = null;
diff --git a/server.js b/server.js
index c194651066114d1cb94f0fb4cf821e0fa0251a90..be10c14d90148f7ecd150a053986b6561c1cc2c8 100644
--- a/server.js
+++ b/server.js
@@ -13,10 +13,10 @@ app.get('/', function(req, res) {
 });
 
 // http 기본 포트(80)에 서버 열기
-server.listen(8080, function() {
-    console.log('[SERVER] Listening on port ' + server.address().port);
+server.listen(80, function() {
+    console.log(new Date().toLocaleTimeString('ko-KR') + ' [SERVER] Listening on port ' + server.address().port);
     GameServer.serverNumber = Math.floor(Math.random() * 1000 + 1);
-    console.log('[SERVER] server number is ' + GameServer.serverNumber);
+    console.log(new Date().toLocaleTimeString('ko-KR') + ' [SERVER] server number is ' + GameServer.serverNumber);
 
 });
 
@@ -29,12 +29,13 @@ io.on('connection', function(socket)
         {
             id: GameServer.getPlayerNumber(),
             nickname: '게스트',
+            skin: 0,
             currentRoom: null,
             playingData: null,
             isReceivable: false
         };
         GameServer.currentPlayer.push(socket);
-        console.log('['+socket.playerData.id+'] client request');
+        console.log(new Date().toLocaleTimeString('ko-KR') + ' ['+socket.playerData.id+'] client request');
         socket.emit('setId', 
         {
             str: 'your number is ' + socket.playerData.id,
@@ -45,11 +46,12 @@ io.on('connection', function(socket)
 
     socket.on('enterRoom', function(msg) // string new_nickname
     {
-        if(msg.length < 1) socket.emit('alert' ,'errNicknameEmpty');
+        if(msg.nickname.length < 1) socket.emit('alert' ,'errNicknameEmpty');
         else
         {
-            socket.playerData.nickname = msg;
-            console.log('['+socket.playerData.id+'] nickname set to ' + msg);
+            socket.playerData.nickname = msg.nickname;
+            socket.playerData.skiin = msg.skin;
+            console.log(new Date().toLocaleTimeString('ko-KR') + ' ['+socket.playerData.id+'] nickname set to ' + msg.nickname);
             GameServer.enterEmptyRoom(socket);
         }
     });
@@ -100,7 +102,7 @@ io.on('connection', function(socket)
             }, 1000);
         }
         catch (e) {
-            console.error('[ERR] error catched on setPlayerTyping (' + e + ')');
+            console.error(new Date().toLocaleTimeString('ko-KR') + ' [ERR] error catched on setPlayerTyping (' + e + ')');
             socket.disconnect();
         }
     });
@@ -110,6 +112,7 @@ io.on('connection', function(socket)
         socket.playerData.currentRoom.aliveCount--;
         //console.log('counted, ' + socket.playerData.currentRoom.aliveCount);
         socket.playerData.playingData.isAlive = true;
+        if (socket.playerData.currentRoom.currentPhase != GameServer.Phase.COUNT) socket.disconnect();
         if (socket.playerData.currentRoom.aliveCount === 0 && socket.playerData.currentRoom.currentPlayer.length >= socket.playerData.currentRoom.startCount)
         {
             socket.playerData.currentRoom.startRoom();
@@ -121,25 +124,21 @@ io.on('connection', function(socket)
             room.startTimer = setTimeout(function()
             {
                 let deads = room.currentPlayer.filter(element => !element.isAlive);
-                if (room.aliveCount != 0 && room.currentPlayer.length - deads.length >= room.startCount)
-                {
-                    console.error('[ROOM#'+room.roomId+'] FORCE START!!!');
-                    room.startRoom();
-                    deads.forEach(function(element)
+                deads.forEach(function(element)
                     {
-                        element.defeat();
+                        room.currentSocket[element.index].disconnect();
+                        room.exitRoom(element.id);
                     });
-                    clearTimeout(room.startTimer);
+                if (room.aliveCount != 0 && room.currentPlayer.length >= room.startCount)
+                {
+                    console.error(new Date().toLocaleTimeString('ko-KR') + ' [ROOM#'+room.roomId+'] FORCE START!!!');
+                    room.startRoom();
                 }
                 else if (deads.length > 0)
                 {
-                    deads.forEach(function(element)
-                    {
-                        room.currentSocket[element.index].disconnect();
-                        room.exitRoom(element.id);
-                    });
                     room.refreshRoom();
                 }
+                clearTimeout(room.startTimer);
             }, 2000);
         }
     });
@@ -202,7 +201,7 @@ io.on('connection', function(socket)
         let data = socket.playerData;
         if (data === undefined)
         {
-            console.error('[ERROR] data is undefined');
+            console.error(new Date().toLocaleTimeString('ko-KR') + ' [ERROR] data is undefined');
             console.table(GameServer.currentPlayer);
             GameServer.disconnectCount--;
         }
@@ -223,7 +222,7 @@ io.on('connection', function(socket)
 
 var disconnectUser = function(data, reason)
 {
-    console.log('['+ data.id +'] client disconnected, reason: ' + reason);
+    console.log(new Date().toLocaleTimeString('ko-KR') + ' ['+ data.id +'] client disconnected, reason: ' + reason);
     let idxToDel = GameServer.currentPlayer.findIndex(function(element)
     {
         return element.playerData.id === data.id;
@@ -245,5 +244,5 @@ var disconnectUser = function(data, reason)
         }
         GameServer.currentPlayer.splice(idxToDel, 1);
     }
-    console.log('['+ data.id +'] disconnect complete');
+    //console.log('['+ data.id +'] disconnect complete');
 }
\ No newline at end of file