SlideShare a Scribd company logo
Developing Cross-Platform Networked Game with XNA 2.0 Game Studio 2008. 5. 24. 김의열  (eykim@microsoft.com) Xbox & HW STE Microsoft Korea EDD R&D
Agenda XNA & Cross-Platform Game Development Preview: Net Rumble Initializing Game Services Creating a Session Finding and Joining a Session Managing Players Joining and Leaving Managing Players from Lobby to Gameplay Sending & Receiving Data Ending the Game DEMO TIPS Q & A
XNA & Cross-Platform Game Development (1) What is the cross-platform game? LIVE Server PC Xbox360
XNA & Cross-Platform Game Development (2) .NET Framework for Windows, & .NET Compact Framework for Xbox 360 공통된  XNA Framework –  하나의  source code 로 각  platform 에서 컴파일 및 실행 가능 추가적인  source code 나  architecture  없이  cross-platform networking  지원 Framework Your Game
Preview: Net Rumble (DEMO) Download from XNA Creators’ Club ( http://creators.xna.com/ ) > Education > Starter kits > Net Rumble DEMO
Preview: Net Rumble (FSM) GamerJoined GamerLeft GameStarted SessionEnded Create(…) StartGame() EndGame() Dispose() GameEnded HostChanged
Initiating Gamer Services Networking API call  이전에  Gamer Services 가 반드시  initialize 되어야 함 Components.Add(new GamerServicesComponent(this)); Gamer 들의  LIVE sign in/out  관리 Gamer 의  Profile  정보 제공 Gamerscore, Gamerzone, Gamer Picture, Region, Motto, Reputation, … SignedInGamer 의  GameDefaults  정보 제공  (preferred settings) Controller sensitivity, Game difficulty, Auto-aim, Axis inversion, … SignedInGamer 의  Privileges  정보 제공 AllowCommunication, AllowOnlineSessions, AllowProfileViewing, LIVE-enabled or guest 자동으로  GamerServicesDispatcher.Update()  호출 , Gamer.SignedInGamers collection 을 업데이트
Initiating Game Services: Code Initializing 에 시간이 많이 소요되므로  constructor 에서 수행 Guide 를 통해  LIVE sign in/out 을 수행 Gamer.SignedInGamers 를 통해  local 에  sign-in 한  Gamer 의  collection 을 가져옴 using Microsoft.Xna.Framework.GamerServices …  public NetRumbleGame() { … Components.Add(new GamerServicesComponent(this)); … } if (!Guide.IsVisible) { Guide.ShowSignIn(1, false); } bool signedIntoLive = false; if (Gamer.SignedInGamers.Count > 0) { foreach (SignedInGamer signedInGamer in Gamer.SignedInGamers) { if (signedInGamer.IsSignedInToLive)  { signedIntoLive = true; break; } } State = signedIntoLive ? MainMenuState.SignedInLive : MainMenuState.SignedInLocal; } else { State = MainMenuState.SignedOut; }
Creating a Session Network session 은  gamer 의 집합과 속성으로 이루어짐 . AllGamers, LocalGamers, RemoteGamers, Host, … SessionType, SessionState, SessionProperties, … IsEveryoneReady, IsHost, … NetworkSession.Create(…) 를 통해  session  생성 .  public static NetworkSession Create(NetworkSessionType sessionType, int maxLocalGamers, int maxGamers); public static NetworkSession Create(NetworkSessionType sessionType, int maxLocalGamers, int maxGamers, int privateGamerSlots, NetworkSessionProperties sessionProperties); .BeginCreate(…) ~ .EndCreate(…) 를 통한 비동기식 방식 가능 . NetworkSession 을 생성한  player 는  host 가 됨 . NetworkException, GamerPrivilegeException 관심 있는 이벤트를  subscribe.
Creating a Session – Network Requirements Xbox 360 Console Windows-Based Computer Run an XNA Framework Game LIVE Silver membership +  Creators Club membership No memberships Required Use System Link LIVE Silver membership +  Creators Club membership No memberships Required Sign-on to Xbox Live and  Games for Windows - LIVE Servers LIVE Silver membership +  Creators Club membership LIVE Silver membership +  Creators Club membership Use LIVE Matchmaking LIVE Gold membership +  Creators Club membership LIVE Gold membership +  Creators Club membership
Creating a Session: Code (1) NetworkSession.Create(…) 은  NetworkSession 을 반환한다 . enum  을 활용하여  NetworkSessionProperties  이용 . BeginCreate(…) ~ EndCreate(…) 를 이용하여 비동기적으로  session 을 생성할 수 있다 . AllowHostMigration? AllowJoinInProgress? using Microsoft.Xna.Framework.Net; … enum SessionProperties { GameMode, ScoreToWin } enum GameMode { FreeForAll, CaptureTheFlag } … NetworkSessionProperties sessionProperties  = new NetworkSessionProperties(); sessionProperties[(int)SessionProperties.GameMode]  = (int)GameMode.FreeForAll; sessionProperties[(int)SessionProperties.ScoreToWin] = 1000; … NetworkSession session; int maxLocalGamers = 1; int maxGamers = 8; int privateGamerSlots =2; session = NetworkSession.Create(NetworkSessionType.SystemLink,  maxLocalGamers, maxGamers, privateGamerSlots, sessionProperties); NetworkSession networkSession = null; … IAsyncResult asyncResult = NetworkSession.BeginCreate(sessionType, 1, World.MaximumPlayers, null, null); … if ((asyncResult != null) && asyncResult.IsCompleted) { networkSession = NetworkSession.EndCreate(asyncResult); … networkSession.AllowHostMigration = true; networkSession.AllowJoinInProgress = false; … }
Creating a Session: Code (2) Session 을 생성한 후에는  NetworkSession 에서 발생하는 이벤트를  subscribe 하여 적절하게 반응한다 . GameEnded  이벤트 GameStarted  이벤트 GamerJoined  이벤트 GamerLeft  이벤트 HostChanged  이벤트 SessionEnded  이벤트 EventHandler<GameStartedEventArgs> gameStartedHandler; EventHandler<GamerJoinedEventArgs> gamerJoinedHandler; EventHandler<NetworkSessionEndedEventArgs> sessionEndedHandler; … public override void LoadContent() { … networkSession.GamerJoined += gamerJoinedHandler; networkSession.GameStarted += gameStartedHandler; networkSession.SessionEnded += sessionEndedHandler; … } … void networkSession_GamerJoined(object sender, GamerJoinedEventArgs e) { … } …
Finding and Joining a Session NetworkSession.Find( … ) 를 통해 원하는  session 의 집합  AvailableNetworkSessionCollection 을 가져옴 .  public static AvailableNetworkSessionCollection Find(NetworkSessionType sessionType, int maxLocalGamers, NetworkSessionProperties searchProperties); .BeginFind( … ) ~ .EndFind( … ) 를 통한 비동기식 방식 가능 . AvailableNetworkSession 에서 다음과 같은 정보를 가져올 수 있다 . HostGamertag, CurrentGamerCount, OpenPrivateGamerSlots, OpenPublicGamerSlots, … 원하는  AvailableNetworkSession 을  NetworkSession.Join( … ) 에 인자로 넘겨주면 해당  session 을 반환하고  Join 이 일어난다 . session = NetworkSession.Join(availableSessions[selectedSessionIndex]; NetworkException, GamerPrivilegeException 관심 있는 이벤트를  subscribe.
Finding and Joining a Session: Code (1) NetworkSession.Create(…) 에 사용하였던 것과 같은 방식으로  NetworkSessionProperties  구성 . availableSessions 로부터  HostGamertag, CurrentGamerCount, OpenPrivateGamerSlots,  등등의 정보를 가져옴 . Quick Match 의 경우는 바로  availableSessions[0] 을 통해  join. using Microsoft.Xna.Framework.Net; … enum SearchProperties { GameMode, ScoreToWin } enum GameMode { FreeForAll, CaptureTheFlag } … NetworkSessionProperties searchProperties  = new NetworkSessionProperties(); searchProperties[(int)SearchProperties.GameMode]  = (int)GameMode.FreeForAll; searchProperties[(int)SearchProperties.ScoreToWin] = 1000; searchProperties[2] = 3; … AvailableNetworkSessionCollection availableSessions; int maxLocalGamers = 1; availableSessions = NetworkSession.Find(NetworkSessionType.PlayerMatch,  maxLocalGamers, searchProperties); if (availableSessions != null) { foreach (AvailableNetworkSession availableSession in availableSessions) { if (availableSession.CurrentGamerCount < World.MaximumPlayers) { MenuEntries.Add(availableSession.HostGamertag + &quot; (&quot; + availableSession.CurrentGamerCount.ToString() + &quot;/&quot; + World.MaximumPlayers.ToString() + &quot;)&quot;); } } }
Finding and Joining a Session: Code (2) NetworkSession.Join 에 참여를 원하는  availableSession 을 넘겨주면 바로  join  완료 . Session 에  join 한 후에는  NetworkSession 에서 발생하는 이벤트를 적절하게  subscribe 한다 . Session 이 종료될 때는  subscribe 했던 이벤트를  unsubscribe. NetworkSession session; … session = NetworkSession.Join(availableSessions[selectedSessionIndex]); EventHandler<GameStartedEventArgs> gameStartedHandler; EventHandler<GamerJoinedEventArgs> gamerJoinedHandler; EventHandler<NetworkSessionEndedEventArgs> sessionEndedHandler; … public override void LoadContent() { … networkSession.GamerJoined += gamerJoinedHandler; networkSession.GameStarted += gameStartedHandler; networkSession.SessionEnded += sessionEndedHandler; … } … void networkSession_GamerJoined(object sender, GamerJoinedEventArgs e) { … } …
Managing Players Joining and Leaving NetworkSession 은  Gamer 들의  list 를 보유  public GamerCollection<NetworkGamer> AllGamers {get;} public GamerCollection<LocalNetworkGamer> LocalGamers {get;} public GamerCollection<NetworkGamer> RemoteGamers {get;}  public NetworkGamer Host {get;} Session 의  gamer list 는  machine  간에 서로 같음이 보장 . Local gamer / Remote gamer Host gamer / guest gamer session 에  gamer 가  joined  할 때  session.GamerJoined  이벤트 발생 . session 에  gamer 가  left  할 때  session.GamerLeft  이벤트 발생 . Gamer.Tag object 를 이용해  player 의 상태와 연결하는 데 사용한다 .
Managing Players Joining and Leaving: Code NetworkSession.GamerJoined, NetworkSession.GamerLeft  이벤트는  session  생성 당시  subscribe 하기로 등록된 상태 GamerJoined  이벤트에 따라  joined 한  player 에  data  할당 Object type 인  Gamer.Tag 를 이용하여  game 에 사용되는  player class 를 연결 GamerLeft  이벤트에 따라  left 한  player 의  data cleanup void networkSession_GamerJoined(object sender, GamerJoinedEventArgs e) { for (int i = 0; i < networkSession.AllGamers.Count; i++) { if (networkSession.AllGamers[i] == e.Gamer) { PlayerData playerData = new PlayerData(); e.Gamer.Tag = playerData; … } } // Code for broadcasting the new player information … } void networkSession_GamerLeft(object sender, GamerLeftEventArgs e) { PlayerData playerData = e.Gamer.Tag as PlayerData; if ((playerData != null) && (playerData.Ship != null)) { playerData.Ship.Die(null, true); // Remove the player } }
Managing Players from Lobby to Gameplay 각  Gamer 는  IsReady  속성을 가지고 있음 . 생성된  NetworkSession 은  IsEveryoneReady  속성을 가지고 있음 . 각  Gamer 의  .IsReady  값을 초기화하기 위한  .ResetReady()  메소드 . NetworkSession 은  NetworkSessionState 를 가진다 . NetworkSessionState.Lobby NetworkSessionState.Playing NetworkSessionState.Ended Lobby 에서  Playing 으로  state 를  transit 하기 위해  Host 가  NetworkSession.StartGame()  호출 .
Managing Players from Lobby to Gameplay: Code LocalGamer 가  IsReady 가 아니라면  Ready 하라는 메시지 IsEveryoneReady 가 아니라면 모두  Ready 하기를 기다리라는 메시지 모두  Ready  상태가 되면  Host 가 아닌 경우는 대기 , Host 라면  .StartGame() 와 호출 ,  게임 시작 . NetworkSession.GameStarted 이벤트의  EventHandler 에서  world 를 생성 및 초기화 . if (!networkSession.LocalGamers[0].IsReady) { MenuEntries[0] = &quot;Press X to Mark as Ready&quot;; } else if (!networkSession.IsEveryoneReady) { MenuEntries[0] = &quot;Waiting for all players to mark as ready...&quot;; } else if (!networkSession.IsHost) { MenuEntries[0] = &quot;Waiting for the host to start game...&quot;; } else { MenuEntries[0] = &quot;Starting the game...&quot;; networkSession.StartGame(); } void networkSession_GameStarted(object sender, GameStartedEventArgs e) { if ((networkSession != null) && networkSession.IsHost && (world != null)) { world.GenerateWorld(); } }
Sending & Receiving Data: Network Topology Server-Client model vs. Peer-to-Peer model NetworkSession 의  host 가  game logic 상  server  역할을 의미하지는 않음 . Host 의 역할은  session 의  description 을  own 하고 , session 의  property 와  state 를  change/update 하고 , player 를  session 에서 제거하는 것에만 국한 . HostMigration 이 허용되는 경우 자동으로 새  host 가 선출됨  (NetworkSession.HostChanged  이벤트 발생 ) Server-Client model 의 경우  server gamer 가 갑자기  disconnect 되는 상황 등 고려
Sending & Receiving Data Reliable UDP 에 기반한  packet  전송 LocalNetworkGamer 의  SendData(…) 함수 호출 public void SendData(PacketWriter data, SendDataOptions options); public void SendData(byte[] data, SendDataOptions options); public void SendData(byte[] data, int offset, int count, SendDataOptions options, NetworkGamer recipient); PacketWriter 를 이용하거나  byte 들의  array 를 전달 특정  NetworkGamer 에게 전달하거나  broadcast 상황에 맞는  SendDataOptions .None: Unreliable, out-of-order .InOrder: Unreliable, in-order .Reliable: Reliable, out-of-order .ReliableInOrder: Reliable, in-order LocalNetworkGamer 가  .IsDataAvailable 일 때  ReceiveData(…)  호출 public int ReceiveData(PacketReader data, out NetworkGamer sender); public int ReceiveData(byte[] data, int offset, out NetworkGamer sender);
Sending & Receiving Data: Code (1) PacketWriter  혹은  byte[]  이용 . PacketWriter 는  SendData  수행 후 자동으로  clear 되므로 하나의  instance  생성 후 재사용 . Gamer state data 는  SendDataOptions.InOrder  사용 . GamerJoined, GamerLeft  등 중요한 이벤트에 대해서는  .ReliableInOrder  활용 . 꼭 정보가 필요한 사람에게만 전달하여  traffic 을 최소화 . PacketWriter packetWriter = new PacketWriter(); … PlayerData playerData = networkSession.LocalGamers[0].Tag as PlayerData; if ((playerData != null) && (playerData.Ship != null)) { packetWriter.Write((int)World.PacketTypes.ShipData); packetWriter.Write(playerData.Ship.Position); packetWriter.Write(playerData.Ship.Velocity); packetWriter.Write(playerData.Ship.Rotation); packetWriter.Write(playerData.Ship.Life); packetWriter.Write(playerData.Ship.Shield); packetWriter.Write(playerData.Ship.Score); networkSession.LocalGamers[0].SendData(packetWriter, SendDataOptions.InOrder); } void networkSession_GamerJoined(object sender, GamerJoinedEventArgs e) { … if ((networkSession.LocalGamers.Count > 0) && !e.Gamer.IsLocal) { PlayerData playerData=networkSession.LocalGamers[0].Tag as PlayerData; if (playerData != null) { packetWriter.Write((int)World.PacketTypes.PlayerData); … networkSession.LocalGamers[0].SendData(packetWriter, SendDataOptions.ReliableInOrder, e.Gamer); } } }
Sending & Receiving Data: Code (2) PacketReader  혹은  byte[]  이용 . .IsDataAvailable 로 받은  packet 이 있는지 확인 .ReceiveData 에  packetReader 와  out sender 를 인자로 전달하여 누가 보냈는지 추적 . Packet 의 구조에 따라 적절하게  PacketRead  함수 사용 . PacketReader packetReader = new PacketReader(); … while (networkSession.LocalGamers[0].IsDataAvailable) { NetworkGamer sender; networkSession.LocalGamers[0].ReceiveData(packetReader, out sender); PacketTypes packetType = (PacketTypes)packetReader.ReadInt32(); switch (packetType) { … case PacketTypes.ShipData: if ((sender != null) && !sender.IsLocal) { UpdateShipData(sender); } break; case PacketTypes.WorldData: if (!networkSession.IsHost && Initialized) { UpdateWorldData(); } break; … } }
Latency & Packet Loss Simulation SystemLink 에 비해 전송이 원활하지 않은 상황을  simulation NeetworkSession  인스턴스의 속성 TimeSpan SimulatedLatency Float SimulatedPacketLoss SendDataOptions 들은  simulation  상황에 관계 없이 존중됨 . 일반적인  internet 을 통한  network game play Latency up to 200ms Packet loss up to 0.1 (10%)
Ending the Game NetworkSession 은  NetworkSessionState 를 가진다 . NetworkSessionState.Lobby NetworkSessionState.Playing NetworkSessionState.Ended Playing 에서  Lobby 로  state 를  transit 하기 위해  NetworkSession.EndGame()  호출 . Lobby 로 돌아갈 수도 있고  NetworkSession.Dispose() 를 통해  session 을 종료할 수도 있음 . 다른  player 에 의해  session 이 종료된 경우  NetworkSessionState.Ended state 로 이동 . NetworkSession.SessionEnded  이벤트의  argument 로  NetworkSessionEndReason 이 제공 . .ClientSignedOut, .HostEndedSession, .RemovedByHost, .Disconnected
Ending the Game: Code 조건에 따라서  Host 인  gamer 가  .EndGame()  호출 . NetworkSession.GameEnded 의  EventHandler 에서  world 의 제거 및 후처리 . EndGame()  후  lobby 로 돌아갈 것인가  session 을 종료할 것인가는  design 하기 나름 . Session 이 종료될 때  subscribe 했던 이벤트를  unsubscribe. void networkSession_GameEnded(object sender, GameEndedEventArgs e) { if ((world != null) && !world.GameWon && !world.GameExited) { world.GameExited = true; } if (!IsExiting && ((world == null) || world.GameExited)) {  …  } } … if (world.GameExited) { … if (world != null) { world.Dispose(); world = null; } if (networkSession != null) { networkSession.Dispose(); networkSession = null; } … } switch (packetType) { … case PacketTypes.GameWon: … if (networkSession.IsHost && (networkSession.SessionState == NetworkSessionState.Playing)) {  networkSession.EndGame();  } break; }
DEMO Xbox360  연결하기 Xbox360 용으로 컴파일 및 게임 실행 Cross-platform  매치 : Net Rumble
TIP 1: Control & Balance Input 을  xbox360 과  keyboard/mouse 로부터 동시에 받도록 코드 구성 게임의 성격에 따라 컨트롤의 밸런스에 주의 GamePadState gamePad; KeyboardState keyboard; … protected override void Update(GameTime gameTime) { gamePad = GamePad.GetState(PlayerIndex.One); keyboard = Keyboard.GetState(); gamePadUp = gamePad.DPad.Up == ButtonState.Pressed || gamePad.ThumbSticks.Left.Y > 0.5f; gamePadDown = gamePad.DPad.Down == ButtonState.Pressed || gamePad.ThumbSticks.Left.Y < -0.5f; float moveFactorPerSecond = 0.5f * (float)gameTime.ElapsedRealTime.TotalMilliseconds/1000.0f; if (gamePadUp || keyboard.IsKeyDown(Keys.Up)) rightPaddlePosition -= moveFactorPerSecond; if (gamePadDown || keyboard.IsKeyDown(Keys.Down)) rightPaddlePosition += moveFactorPerSecond; … } ?
TIP 2: SafeArea 화면의 가장자리에 중요한  UI  정보를 출력하지 않는다 . VGA  케이블로 연결된  PC  모니터 : 100%  혹은 이하 SCART  케이블로 연결된 구형 모니터 :  약  92% 컴포넌트 케이블로 연결된  HDTV  모니터 : 93~95% 일부 구형 모니터 : 80~90% SafeArea
TIP 3: No Foreign References XNA Framework 에서 제공하는  dll 외의  dll 들을 함부로 호출하면  Xbox360 에서 정상적으로 컴파일 / 실행되지 않을 수 있음 . mscorlib.~ System.~ Microsoft.Xna.Framework.~ Microsoft.Xna.Framework.dll (XNA Graphic Engine) Microsoft.Xna.Framework.Game.dll (XNA Game Application Model) Microsoft.Xna.Framework.Conponent.Pipeline.dll (XNA Content Pipeline)
Q & A Any questions? Refer to Creators Club ( http://creators.xna.com ) & MSDN!! E-mail: eykim@microsoft.com
Ad

More Related Content

Viewers also liked (6)

Akamai Korea - Tech Day (2015/03/11) HTTP/2
Akamai Korea - Tech Day (2015/03/11) HTTP/2Akamai Korea - Tech Day (2015/03/11) HTTP/2
Akamai Korea - Tech Day (2015/03/11) HTTP/2
SangJin Kang
 
HTTP 발표자료 - 김연수
HTTP 발표자료 - 김연수HTTP 발표자료 - 김연수
HTTP 발표자료 - 김연수
Yeon Soo Kim
 
Embedded linux 악성코드 동향 20150323 v1.0 공개판
Embedded linux 악성코드 동향 20150323 v1.0 공개판Embedded linux 악성코드 동향 20150323 v1.0 공개판
Embedded linux 악성코드 동향 20150323 v1.0 공개판
Minseok(Jacky) Cha
 
Play framework: lessons learned
Play framework: lessons learnedPlay framework: lessons learned
Play framework: lessons learned
Peter Hilton
 
임베디드 리눅스 악성코드로 본 사물인터넷 보안 차민석 20150406_코드게이트 발표판
임베디드 리눅스 악성코드로 본 사물인터넷 보안 차민석 20150406_코드게이트 발표판임베디드 리눅스 악성코드로 본 사물인터넷 보안 차민석 20150406_코드게이트 발표판
임베디드 리눅스 악성코드로 본 사물인터넷 보안 차민석 20150406_코드게이트 발표판
Minseok(Jacky) Cha
 
Victoria's Secret Angels Campaign
Victoria's Secret Angels CampaignVictoria's Secret Angels Campaign
Victoria's Secret Angels Campaign
John White
 
Akamai Korea - Tech Day (2015/03/11) HTTP/2
Akamai Korea - Tech Day (2015/03/11) HTTP/2Akamai Korea - Tech Day (2015/03/11) HTTP/2
Akamai Korea - Tech Day (2015/03/11) HTTP/2
SangJin Kang
 
HTTP 발표자료 - 김연수
HTTP 발표자료 - 김연수HTTP 발표자료 - 김연수
HTTP 발표자료 - 김연수
Yeon Soo Kim
 
Embedded linux 악성코드 동향 20150323 v1.0 공개판
Embedded linux 악성코드 동향 20150323 v1.0 공개판Embedded linux 악성코드 동향 20150323 v1.0 공개판
Embedded linux 악성코드 동향 20150323 v1.0 공개판
Minseok(Jacky) Cha
 
Play framework: lessons learned
Play framework: lessons learnedPlay framework: lessons learned
Play framework: lessons learned
Peter Hilton
 
임베디드 리눅스 악성코드로 본 사물인터넷 보안 차민석 20150406_코드게이트 발표판
임베디드 리눅스 악성코드로 본 사물인터넷 보안 차민석 20150406_코드게이트 발표판임베디드 리눅스 악성코드로 본 사물인터넷 보안 차민석 20150406_코드게이트 발표판
임베디드 리눅스 악성코드로 본 사물인터넷 보안 차민석 20150406_코드게이트 발표판
Minseok(Jacky) Cha
 
Victoria's Secret Angels Campaign
Victoria's Secret Angels CampaignVictoria's Secret Angels Campaign
Victoria's Secret Angels Campaign
John White
 

Similar to XNA2.0 Network Programming (20)

AWS 클라우드 기반 게임 아키텍처 사례 - AWS Summit Seoul 2017
AWS 클라우드 기반 게임 아키텍처 사례 - AWS Summit Seoul 2017AWS 클라우드 기반 게임 아키텍처 사례 - AWS Summit Seoul 2017
AWS 클라우드 기반 게임 아키텍처 사례 - AWS Summit Seoul 2017
Amazon Web Services Korea
 
2회 오픈소스 게임 서버 엔진 스터디 캠프 - CloudBread
2회 오픈소스 게임 서버 엔진 스터디 캠프 - CloudBread2회 오픈소스 게임 서버 엔진 스터디 캠프 - CloudBread
2회 오픈소스 게임 서버 엔진 스터디 캠프 - CloudBread
Dae Kim
 
(Fios#03) 4. 파워셸 포렌식 조사 기법
(Fios#03) 4. 파워셸 포렌식 조사 기법(Fios#03) 4. 파워셸 포렌식 조사 기법
(Fios#03) 4. 파워셸 포렌식 조사 기법
INSIGHT FORENSIC
 
[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기
[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기
[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기
flashscope
 
CSGG: Database Team Project
CSGG: Database Team ProjectCSGG: Database Team Project
CSGG: Database Team Project
Seong Heum Park
 
클라우드 기반 Unity 게임 서버 구축, 60분이면 충분하다
클라우드 기반 Unity 게임 서버 구축, 60분이면 충분하다클라우드 기반 Unity 게임 서버 구축, 60분이면 충분하다
클라우드 기반 Unity 게임 서버 구축, 60분이면 충분하다
Dae Kim
 
Flappy bird 만들기 세미나 자료(유니티 4.3버전)
Flappy bird 만들기 세미나 자료(유니티 4.3버전)Flappy bird 만들기 세미나 자료(유니티 4.3버전)
Flappy bird 만들기 세미나 자료(유니티 4.3버전)
Changwon National University
 
Startup JavaScript 9 - Socket.IO 실시간 통신
Startup JavaScript 9 - Socket.IO 실시간 통신Startup JavaScript 9 - Socket.IO 실시간 통신
Startup JavaScript 9 - Socket.IO 실시간 통신
Circulus
 
유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기
유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기
유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기
Kiyoung Moon
 
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
강 민우
 
나만의 엔진 개발하기
나만의 엔진 개발하기나만의 엔진 개발하기
나만의 엔진 개발하기
YEONG-CHEON YOU
 
Java term project final
Java term project finalJava term project final
Java term project final
KimSoohyun15
 
Casual Game for Windows Mobile
Casual Game for Windows MobileCasual Game for Windows Mobile
Casual Game for Windows Mobile
Seo Jinho
 
Scouter Tutorial & Sprint
Scouter Tutorial & SprintScouter Tutorial & Sprint
Scouter Tutorial & Sprint
GunHee Lee
 
Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)
beom kyun choi
 
브릿지 Unity3D 기초 스터디 1회
브릿지 Unity3D 기초 스터디 1회브릿지 Unity3D 기초 스터디 1회
브릿지 Unity3D 기초 스터디 1회
BridgeGames
 
회사소개서 브로셔V1.0
회사소개서 브로셔V1.0회사소개서 브로셔V1.0
회사소개서 브로셔V1.0
원택 황
 
Network programming report
Network programming reportNetwork programming report
Network programming report
Jongwon
 
게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
Amazon Web Services Korea
 
AWS 클라우드 기반 게임 아키텍처 사례 - AWS Summit Seoul 2017
AWS 클라우드 기반 게임 아키텍처 사례 - AWS Summit Seoul 2017AWS 클라우드 기반 게임 아키텍처 사례 - AWS Summit Seoul 2017
AWS 클라우드 기반 게임 아키텍처 사례 - AWS Summit Seoul 2017
Amazon Web Services Korea
 
2회 오픈소스 게임 서버 엔진 스터디 캠프 - CloudBread
2회 오픈소스 게임 서버 엔진 스터디 캠프 - CloudBread2회 오픈소스 게임 서버 엔진 스터디 캠프 - CloudBread
2회 오픈소스 게임 서버 엔진 스터디 캠프 - CloudBread
Dae Kim
 
(Fios#03) 4. 파워셸 포렌식 조사 기법
(Fios#03) 4. 파워셸 포렌식 조사 기법(Fios#03) 4. 파워셸 포렌식 조사 기법
(Fios#03) 4. 파워셸 포렌식 조사 기법
INSIGHT FORENSIC
 
[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기
[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기
[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기
flashscope
 
CSGG: Database Team Project
CSGG: Database Team ProjectCSGG: Database Team Project
CSGG: Database Team Project
Seong Heum Park
 
클라우드 기반 Unity 게임 서버 구축, 60분이면 충분하다
클라우드 기반 Unity 게임 서버 구축, 60분이면 충분하다클라우드 기반 Unity 게임 서버 구축, 60분이면 충분하다
클라우드 기반 Unity 게임 서버 구축, 60분이면 충분하다
Dae Kim
 
Flappy bird 만들기 세미나 자료(유니티 4.3버전)
Flappy bird 만들기 세미나 자료(유니티 4.3버전)Flappy bird 만들기 세미나 자료(유니티 4.3버전)
Flappy bird 만들기 세미나 자료(유니티 4.3버전)
Changwon National University
 
Startup JavaScript 9 - Socket.IO 실시간 통신
Startup JavaScript 9 - Socket.IO 실시간 통신Startup JavaScript 9 - Socket.IO 실시간 통신
Startup JavaScript 9 - Socket.IO 실시간 통신
Circulus
 
유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기
유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기
유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기
Kiyoung Moon
 
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
강 민우
 
나만의 엔진 개발하기
나만의 엔진 개발하기나만의 엔진 개발하기
나만의 엔진 개발하기
YEONG-CHEON YOU
 
Java term project final
Java term project finalJava term project final
Java term project final
KimSoohyun15
 
Casual Game for Windows Mobile
Casual Game for Windows MobileCasual Game for Windows Mobile
Casual Game for Windows Mobile
Seo Jinho
 
Scouter Tutorial & Sprint
Scouter Tutorial & SprintScouter Tutorial & Sprint
Scouter Tutorial & Sprint
GunHee Lee
 
Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)
beom kyun choi
 
브릿지 Unity3D 기초 스터디 1회
브릿지 Unity3D 기초 스터디 1회브릿지 Unity3D 기초 스터디 1회
브릿지 Unity3D 기초 스터디 1회
BridgeGames
 
회사소개서 브로셔V1.0
회사소개서 브로셔V1.0회사소개서 브로셔V1.0
회사소개서 브로셔V1.0
원택 황
 
Network programming report
Network programming reportNetwork programming report
Network programming report
Jongwon
 
게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
Amazon Web Services Korea
 
Ad

More from SangJin Kang (11)

웹에 빠른 날개를 달아주는 웹 성능 향상 이야기
웹에 빠른 날개를 달아주는 웹 성능 향상 이야기웹에 빠른 날개를 달아주는 웹 성능 향상 이야기
웹에 빠른 날개를 달아주는 웹 성능 향상 이야기
SangJin Kang
 
Web Performance Optimization with HTTP/3
Web Performance Optimization with HTTP/3Web Performance Optimization with HTTP/3
Web Performance Optimization with HTTP/3
SangJin Kang
 
How to Replicate PostgreSQL Database
How to Replicate PostgreSQL DatabaseHow to Replicate PostgreSQL Database
How to Replicate PostgreSQL Database
SangJin Kang
 
Scalability strategies for cloud based system architecture
Scalability strategies for cloud based system architectureScalability strategies for cloud based system architecture
Scalability strategies for cloud based system architecture
SangJin Kang
 
HTTP/3 시대의 웹 성능 최적화 기술 이해하기
HTTP/3 시대의 웹 성능 최적화 기술 이해하기HTTP/3 시대의 웹 성능 최적화 기술 이해하기
HTTP/3 시대의 웹 성능 최적화 기술 이해하기
SangJin Kang
 
수요자 중심의 클라우드 운영 및 전략 (CIO Summit 2019)
수요자 중심의 클라우드 운영 및 전략 (CIO Summit 2019)수요자 중심의 클라우드 운영 및 전략 (CIO Summit 2019)
수요자 중심의 클라우드 운영 및 전략 (CIO Summit 2019)
SangJin Kang
 
How to develop and localize Xbox 360 titles
How to develop and localize Xbox 360 titlesHow to develop and localize Xbox 360 titles
How to develop and localize Xbox 360 titles
SangJin Kang
 
HTTP 프로토콜의 이해와 활용
HTTP 프로토콜의 이해와 활용HTTP 프로토콜의 이해와 활용
HTTP 프로토콜의 이해와 활용
SangJin Kang
 
HTTP/2와 웹 성능 최적화 방안
HTTP/2와 웹 성능 최적화 방안HTTP/2와 웹 성능 최적화 방안
HTTP/2와 웹 성능 최적화 방안
SangJin Kang
 
HTML5 for web app. development
HTML5 for web app. developmentHTML5 for web app. development
HTML5 for web app. development
SangJin Kang
 
Agile - SCRUM을 통한 개발관리
Agile - SCRUM을 통한 개발관리Agile - SCRUM을 통한 개발관리
Agile - SCRUM을 통한 개발관리
SangJin Kang
 
웹에 빠른 날개를 달아주는 웹 성능 향상 이야기
웹에 빠른 날개를 달아주는 웹 성능 향상 이야기웹에 빠른 날개를 달아주는 웹 성능 향상 이야기
웹에 빠른 날개를 달아주는 웹 성능 향상 이야기
SangJin Kang
 
Web Performance Optimization with HTTP/3
Web Performance Optimization with HTTP/3Web Performance Optimization with HTTP/3
Web Performance Optimization with HTTP/3
SangJin Kang
 
How to Replicate PostgreSQL Database
How to Replicate PostgreSQL DatabaseHow to Replicate PostgreSQL Database
How to Replicate PostgreSQL Database
SangJin Kang
 
Scalability strategies for cloud based system architecture
Scalability strategies for cloud based system architectureScalability strategies for cloud based system architecture
Scalability strategies for cloud based system architecture
SangJin Kang
 
HTTP/3 시대의 웹 성능 최적화 기술 이해하기
HTTP/3 시대의 웹 성능 최적화 기술 이해하기HTTP/3 시대의 웹 성능 최적화 기술 이해하기
HTTP/3 시대의 웹 성능 최적화 기술 이해하기
SangJin Kang
 
수요자 중심의 클라우드 운영 및 전략 (CIO Summit 2019)
수요자 중심의 클라우드 운영 및 전략 (CIO Summit 2019)수요자 중심의 클라우드 운영 및 전략 (CIO Summit 2019)
수요자 중심의 클라우드 운영 및 전략 (CIO Summit 2019)
SangJin Kang
 
How to develop and localize Xbox 360 titles
How to develop and localize Xbox 360 titlesHow to develop and localize Xbox 360 titles
How to develop and localize Xbox 360 titles
SangJin Kang
 
HTTP 프로토콜의 이해와 활용
HTTP 프로토콜의 이해와 활용HTTP 프로토콜의 이해와 활용
HTTP 프로토콜의 이해와 활용
SangJin Kang
 
HTTP/2와 웹 성능 최적화 방안
HTTP/2와 웹 성능 최적화 방안HTTP/2와 웹 성능 최적화 방안
HTTP/2와 웹 성능 최적화 방안
SangJin Kang
 
HTML5 for web app. development
HTML5 for web app. developmentHTML5 for web app. development
HTML5 for web app. development
SangJin Kang
 
Agile - SCRUM을 통한 개발관리
Agile - SCRUM을 통한 개발관리Agile - SCRUM을 통한 개발관리
Agile - SCRUM을 통한 개발관리
SangJin Kang
 
Ad

XNA2.0 Network Programming

  • 1. Developing Cross-Platform Networked Game with XNA 2.0 Game Studio 2008. 5. 24. 김의열 ([email protected]) Xbox & HW STE Microsoft Korea EDD R&D
  • 2. Agenda XNA & Cross-Platform Game Development Preview: Net Rumble Initializing Game Services Creating a Session Finding and Joining a Session Managing Players Joining and Leaving Managing Players from Lobby to Gameplay Sending & Receiving Data Ending the Game DEMO TIPS Q & A
  • 3. XNA & Cross-Platform Game Development (1) What is the cross-platform game? LIVE Server PC Xbox360
  • 4. XNA & Cross-Platform Game Development (2) .NET Framework for Windows, & .NET Compact Framework for Xbox 360 공통된 XNA Framework – 하나의 source code 로 각 platform 에서 컴파일 및 실행 가능 추가적인 source code 나 architecture 없이 cross-platform networking 지원 Framework Your Game
  • 5. Preview: Net Rumble (DEMO) Download from XNA Creators’ Club ( http://creators.xna.com/ ) > Education > Starter kits > Net Rumble DEMO
  • 6. Preview: Net Rumble (FSM) GamerJoined GamerLeft GameStarted SessionEnded Create(…) StartGame() EndGame() Dispose() GameEnded HostChanged
  • 7. Initiating Gamer Services Networking API call 이전에 Gamer Services 가 반드시 initialize 되어야 함 Components.Add(new GamerServicesComponent(this)); Gamer 들의 LIVE sign in/out 관리 Gamer 의 Profile 정보 제공 Gamerscore, Gamerzone, Gamer Picture, Region, Motto, Reputation, … SignedInGamer 의 GameDefaults 정보 제공 (preferred settings) Controller sensitivity, Game difficulty, Auto-aim, Axis inversion, … SignedInGamer 의 Privileges 정보 제공 AllowCommunication, AllowOnlineSessions, AllowProfileViewing, LIVE-enabled or guest 자동으로 GamerServicesDispatcher.Update() 호출 , Gamer.SignedInGamers collection 을 업데이트
  • 8. Initiating Game Services: Code Initializing 에 시간이 많이 소요되므로 constructor 에서 수행 Guide 를 통해 LIVE sign in/out 을 수행 Gamer.SignedInGamers 를 통해 local 에 sign-in 한 Gamer 의 collection 을 가져옴 using Microsoft.Xna.Framework.GamerServices … public NetRumbleGame() { … Components.Add(new GamerServicesComponent(this)); … } if (!Guide.IsVisible) { Guide.ShowSignIn(1, false); } bool signedIntoLive = false; if (Gamer.SignedInGamers.Count > 0) { foreach (SignedInGamer signedInGamer in Gamer.SignedInGamers) { if (signedInGamer.IsSignedInToLive) { signedIntoLive = true; break; } } State = signedIntoLive ? MainMenuState.SignedInLive : MainMenuState.SignedInLocal; } else { State = MainMenuState.SignedOut; }
  • 9. Creating a Session Network session 은 gamer 의 집합과 속성으로 이루어짐 . AllGamers, LocalGamers, RemoteGamers, Host, … SessionType, SessionState, SessionProperties, … IsEveryoneReady, IsHost, … NetworkSession.Create(…) 를 통해 session 생성 . public static NetworkSession Create(NetworkSessionType sessionType, int maxLocalGamers, int maxGamers); public static NetworkSession Create(NetworkSessionType sessionType, int maxLocalGamers, int maxGamers, int privateGamerSlots, NetworkSessionProperties sessionProperties); .BeginCreate(…) ~ .EndCreate(…) 를 통한 비동기식 방식 가능 . NetworkSession 을 생성한 player 는 host 가 됨 . NetworkException, GamerPrivilegeException 관심 있는 이벤트를 subscribe.
  • 10. Creating a Session – Network Requirements Xbox 360 Console Windows-Based Computer Run an XNA Framework Game LIVE Silver membership + Creators Club membership No memberships Required Use System Link LIVE Silver membership + Creators Club membership No memberships Required Sign-on to Xbox Live and Games for Windows - LIVE Servers LIVE Silver membership + Creators Club membership LIVE Silver membership + Creators Club membership Use LIVE Matchmaking LIVE Gold membership + Creators Club membership LIVE Gold membership + Creators Club membership
  • 11. Creating a Session: Code (1) NetworkSession.Create(…) 은 NetworkSession 을 반환한다 . enum 을 활용하여 NetworkSessionProperties 이용 . BeginCreate(…) ~ EndCreate(…) 를 이용하여 비동기적으로 session 을 생성할 수 있다 . AllowHostMigration? AllowJoinInProgress? using Microsoft.Xna.Framework.Net; … enum SessionProperties { GameMode, ScoreToWin } enum GameMode { FreeForAll, CaptureTheFlag } … NetworkSessionProperties sessionProperties = new NetworkSessionProperties(); sessionProperties[(int)SessionProperties.GameMode] = (int)GameMode.FreeForAll; sessionProperties[(int)SessionProperties.ScoreToWin] = 1000; … NetworkSession session; int maxLocalGamers = 1; int maxGamers = 8; int privateGamerSlots =2; session = NetworkSession.Create(NetworkSessionType.SystemLink, maxLocalGamers, maxGamers, privateGamerSlots, sessionProperties); NetworkSession networkSession = null; … IAsyncResult asyncResult = NetworkSession.BeginCreate(sessionType, 1, World.MaximumPlayers, null, null); … if ((asyncResult != null) && asyncResult.IsCompleted) { networkSession = NetworkSession.EndCreate(asyncResult); … networkSession.AllowHostMigration = true; networkSession.AllowJoinInProgress = false; … }
  • 12. Creating a Session: Code (2) Session 을 생성한 후에는 NetworkSession 에서 발생하는 이벤트를 subscribe 하여 적절하게 반응한다 . GameEnded 이벤트 GameStarted 이벤트 GamerJoined 이벤트 GamerLeft 이벤트 HostChanged 이벤트 SessionEnded 이벤트 EventHandler<GameStartedEventArgs> gameStartedHandler; EventHandler<GamerJoinedEventArgs> gamerJoinedHandler; EventHandler<NetworkSessionEndedEventArgs> sessionEndedHandler; … public override void LoadContent() { … networkSession.GamerJoined += gamerJoinedHandler; networkSession.GameStarted += gameStartedHandler; networkSession.SessionEnded += sessionEndedHandler; … } … void networkSession_GamerJoined(object sender, GamerJoinedEventArgs e) { … } …
  • 13. Finding and Joining a Session NetworkSession.Find( … ) 를 통해 원하는 session 의 집합 AvailableNetworkSessionCollection 을 가져옴 . public static AvailableNetworkSessionCollection Find(NetworkSessionType sessionType, int maxLocalGamers, NetworkSessionProperties searchProperties); .BeginFind( … ) ~ .EndFind( … ) 를 통한 비동기식 방식 가능 . AvailableNetworkSession 에서 다음과 같은 정보를 가져올 수 있다 . HostGamertag, CurrentGamerCount, OpenPrivateGamerSlots, OpenPublicGamerSlots, … 원하는 AvailableNetworkSession 을 NetworkSession.Join( … ) 에 인자로 넘겨주면 해당 session 을 반환하고 Join 이 일어난다 . session = NetworkSession.Join(availableSessions[selectedSessionIndex]; NetworkException, GamerPrivilegeException 관심 있는 이벤트를 subscribe.
  • 14. Finding and Joining a Session: Code (1) NetworkSession.Create(…) 에 사용하였던 것과 같은 방식으로 NetworkSessionProperties 구성 . availableSessions 로부터 HostGamertag, CurrentGamerCount, OpenPrivateGamerSlots, 등등의 정보를 가져옴 . Quick Match 의 경우는 바로 availableSessions[0] 을 통해 join. using Microsoft.Xna.Framework.Net; … enum SearchProperties { GameMode, ScoreToWin } enum GameMode { FreeForAll, CaptureTheFlag } … NetworkSessionProperties searchProperties = new NetworkSessionProperties(); searchProperties[(int)SearchProperties.GameMode] = (int)GameMode.FreeForAll; searchProperties[(int)SearchProperties.ScoreToWin] = 1000; searchProperties[2] = 3; … AvailableNetworkSessionCollection availableSessions; int maxLocalGamers = 1; availableSessions = NetworkSession.Find(NetworkSessionType.PlayerMatch, maxLocalGamers, searchProperties); if (availableSessions != null) { foreach (AvailableNetworkSession availableSession in availableSessions) { if (availableSession.CurrentGamerCount < World.MaximumPlayers) { MenuEntries.Add(availableSession.HostGamertag + &quot; (&quot; + availableSession.CurrentGamerCount.ToString() + &quot;/&quot; + World.MaximumPlayers.ToString() + &quot;)&quot;); } } }
  • 15. Finding and Joining a Session: Code (2) NetworkSession.Join 에 참여를 원하는 availableSession 을 넘겨주면 바로 join 완료 . Session 에 join 한 후에는 NetworkSession 에서 발생하는 이벤트를 적절하게 subscribe 한다 . Session 이 종료될 때는 subscribe 했던 이벤트를 unsubscribe. NetworkSession session; … session = NetworkSession.Join(availableSessions[selectedSessionIndex]); EventHandler<GameStartedEventArgs> gameStartedHandler; EventHandler<GamerJoinedEventArgs> gamerJoinedHandler; EventHandler<NetworkSessionEndedEventArgs> sessionEndedHandler; … public override void LoadContent() { … networkSession.GamerJoined += gamerJoinedHandler; networkSession.GameStarted += gameStartedHandler; networkSession.SessionEnded += sessionEndedHandler; … } … void networkSession_GamerJoined(object sender, GamerJoinedEventArgs e) { … } …
  • 16. Managing Players Joining and Leaving NetworkSession 은 Gamer 들의 list 를 보유 public GamerCollection<NetworkGamer> AllGamers {get;} public GamerCollection<LocalNetworkGamer> LocalGamers {get;} public GamerCollection<NetworkGamer> RemoteGamers {get;} public NetworkGamer Host {get;} Session 의 gamer list 는 machine 간에 서로 같음이 보장 . Local gamer / Remote gamer Host gamer / guest gamer session 에 gamer 가 joined 할 때 session.GamerJoined 이벤트 발생 . session 에 gamer 가 left 할 때 session.GamerLeft 이벤트 발생 . Gamer.Tag object 를 이용해 player 의 상태와 연결하는 데 사용한다 .
  • 17. Managing Players Joining and Leaving: Code NetworkSession.GamerJoined, NetworkSession.GamerLeft 이벤트는 session 생성 당시 subscribe 하기로 등록된 상태 GamerJoined 이벤트에 따라 joined 한 player 에 data 할당 Object type 인 Gamer.Tag 를 이용하여 game 에 사용되는 player class 를 연결 GamerLeft 이벤트에 따라 left 한 player 의 data cleanup void networkSession_GamerJoined(object sender, GamerJoinedEventArgs e) { for (int i = 0; i < networkSession.AllGamers.Count; i++) { if (networkSession.AllGamers[i] == e.Gamer) { PlayerData playerData = new PlayerData(); e.Gamer.Tag = playerData; … } } // Code for broadcasting the new player information … } void networkSession_GamerLeft(object sender, GamerLeftEventArgs e) { PlayerData playerData = e.Gamer.Tag as PlayerData; if ((playerData != null) && (playerData.Ship != null)) { playerData.Ship.Die(null, true); // Remove the player } }
  • 18. Managing Players from Lobby to Gameplay 각 Gamer 는 IsReady 속성을 가지고 있음 . 생성된 NetworkSession 은 IsEveryoneReady 속성을 가지고 있음 . 각 Gamer 의 .IsReady 값을 초기화하기 위한 .ResetReady() 메소드 . NetworkSession 은 NetworkSessionState 를 가진다 . NetworkSessionState.Lobby NetworkSessionState.Playing NetworkSessionState.Ended Lobby 에서 Playing 으로 state 를 transit 하기 위해 Host 가 NetworkSession.StartGame() 호출 .
  • 19. Managing Players from Lobby to Gameplay: Code LocalGamer 가 IsReady 가 아니라면 Ready 하라는 메시지 IsEveryoneReady 가 아니라면 모두 Ready 하기를 기다리라는 메시지 모두 Ready 상태가 되면 Host 가 아닌 경우는 대기 , Host 라면 .StartGame() 와 호출 , 게임 시작 . NetworkSession.GameStarted 이벤트의 EventHandler 에서 world 를 생성 및 초기화 . if (!networkSession.LocalGamers[0].IsReady) { MenuEntries[0] = &quot;Press X to Mark as Ready&quot;; } else if (!networkSession.IsEveryoneReady) { MenuEntries[0] = &quot;Waiting for all players to mark as ready...&quot;; } else if (!networkSession.IsHost) { MenuEntries[0] = &quot;Waiting for the host to start game...&quot;; } else { MenuEntries[0] = &quot;Starting the game...&quot;; networkSession.StartGame(); } void networkSession_GameStarted(object sender, GameStartedEventArgs e) { if ((networkSession != null) && networkSession.IsHost && (world != null)) { world.GenerateWorld(); } }
  • 20. Sending & Receiving Data: Network Topology Server-Client model vs. Peer-to-Peer model NetworkSession 의 host 가 game logic 상 server 역할을 의미하지는 않음 . Host 의 역할은 session 의 description 을 own 하고 , session 의 property 와 state 를 change/update 하고 , player 를 session 에서 제거하는 것에만 국한 . HostMigration 이 허용되는 경우 자동으로 새 host 가 선출됨 (NetworkSession.HostChanged 이벤트 발생 ) Server-Client model 의 경우 server gamer 가 갑자기 disconnect 되는 상황 등 고려
  • 21. Sending & Receiving Data Reliable UDP 에 기반한 packet 전송 LocalNetworkGamer 의 SendData(…) 함수 호출 public void SendData(PacketWriter data, SendDataOptions options); public void SendData(byte[] data, SendDataOptions options); public void SendData(byte[] data, int offset, int count, SendDataOptions options, NetworkGamer recipient); PacketWriter 를 이용하거나 byte 들의 array 를 전달 특정 NetworkGamer 에게 전달하거나 broadcast 상황에 맞는 SendDataOptions .None: Unreliable, out-of-order .InOrder: Unreliable, in-order .Reliable: Reliable, out-of-order .ReliableInOrder: Reliable, in-order LocalNetworkGamer 가 .IsDataAvailable 일 때 ReceiveData(…) 호출 public int ReceiveData(PacketReader data, out NetworkGamer sender); public int ReceiveData(byte[] data, int offset, out NetworkGamer sender);
  • 22. Sending & Receiving Data: Code (1) PacketWriter 혹은 byte[] 이용 . PacketWriter 는 SendData 수행 후 자동으로 clear 되므로 하나의 instance 생성 후 재사용 . Gamer state data 는 SendDataOptions.InOrder 사용 . GamerJoined, GamerLeft 등 중요한 이벤트에 대해서는 .ReliableInOrder 활용 . 꼭 정보가 필요한 사람에게만 전달하여 traffic 을 최소화 . PacketWriter packetWriter = new PacketWriter(); … PlayerData playerData = networkSession.LocalGamers[0].Tag as PlayerData; if ((playerData != null) && (playerData.Ship != null)) { packetWriter.Write((int)World.PacketTypes.ShipData); packetWriter.Write(playerData.Ship.Position); packetWriter.Write(playerData.Ship.Velocity); packetWriter.Write(playerData.Ship.Rotation); packetWriter.Write(playerData.Ship.Life); packetWriter.Write(playerData.Ship.Shield); packetWriter.Write(playerData.Ship.Score); networkSession.LocalGamers[0].SendData(packetWriter, SendDataOptions.InOrder); } void networkSession_GamerJoined(object sender, GamerJoinedEventArgs e) { … if ((networkSession.LocalGamers.Count > 0) && !e.Gamer.IsLocal) { PlayerData playerData=networkSession.LocalGamers[0].Tag as PlayerData; if (playerData != null) { packetWriter.Write((int)World.PacketTypes.PlayerData); … networkSession.LocalGamers[0].SendData(packetWriter, SendDataOptions.ReliableInOrder, e.Gamer); } } }
  • 23. Sending & Receiving Data: Code (2) PacketReader 혹은 byte[] 이용 . .IsDataAvailable 로 받은 packet 이 있는지 확인 .ReceiveData 에 packetReader 와 out sender 를 인자로 전달하여 누가 보냈는지 추적 . Packet 의 구조에 따라 적절하게 PacketRead 함수 사용 . PacketReader packetReader = new PacketReader(); … while (networkSession.LocalGamers[0].IsDataAvailable) { NetworkGamer sender; networkSession.LocalGamers[0].ReceiveData(packetReader, out sender); PacketTypes packetType = (PacketTypes)packetReader.ReadInt32(); switch (packetType) { … case PacketTypes.ShipData: if ((sender != null) && !sender.IsLocal) { UpdateShipData(sender); } break; case PacketTypes.WorldData: if (!networkSession.IsHost && Initialized) { UpdateWorldData(); } break; … } }
  • 24. Latency & Packet Loss Simulation SystemLink 에 비해 전송이 원활하지 않은 상황을 simulation NeetworkSession 인스턴스의 속성 TimeSpan SimulatedLatency Float SimulatedPacketLoss SendDataOptions 들은 simulation 상황에 관계 없이 존중됨 . 일반적인 internet 을 통한 network game play Latency up to 200ms Packet loss up to 0.1 (10%)
  • 25. Ending the Game NetworkSession 은 NetworkSessionState 를 가진다 . NetworkSessionState.Lobby NetworkSessionState.Playing NetworkSessionState.Ended Playing 에서 Lobby 로 state 를 transit 하기 위해 NetworkSession.EndGame() 호출 . Lobby 로 돌아갈 수도 있고 NetworkSession.Dispose() 를 통해 session 을 종료할 수도 있음 . 다른 player 에 의해 session 이 종료된 경우 NetworkSessionState.Ended state 로 이동 . NetworkSession.SessionEnded 이벤트의 argument 로 NetworkSessionEndReason 이 제공 . .ClientSignedOut, .HostEndedSession, .RemovedByHost, .Disconnected
  • 26. Ending the Game: Code 조건에 따라서 Host 인 gamer 가 .EndGame() 호출 . NetworkSession.GameEnded 의 EventHandler 에서 world 의 제거 및 후처리 . EndGame() 후 lobby 로 돌아갈 것인가 session 을 종료할 것인가는 design 하기 나름 . Session 이 종료될 때 subscribe 했던 이벤트를 unsubscribe. void networkSession_GameEnded(object sender, GameEndedEventArgs e) { if ((world != null) && !world.GameWon && !world.GameExited) { world.GameExited = true; } if (!IsExiting && ((world == null) || world.GameExited)) { … } } … if (world.GameExited) { … if (world != null) { world.Dispose(); world = null; } if (networkSession != null) { networkSession.Dispose(); networkSession = null; } … } switch (packetType) { … case PacketTypes.GameWon: … if (networkSession.IsHost && (networkSession.SessionState == NetworkSessionState.Playing)) { networkSession.EndGame(); } break; }
  • 27. DEMO Xbox360 연결하기 Xbox360 용으로 컴파일 및 게임 실행 Cross-platform 매치 : Net Rumble
  • 28. TIP 1: Control & Balance Input 을 xbox360 과 keyboard/mouse 로부터 동시에 받도록 코드 구성 게임의 성격에 따라 컨트롤의 밸런스에 주의 GamePadState gamePad; KeyboardState keyboard; … protected override void Update(GameTime gameTime) { gamePad = GamePad.GetState(PlayerIndex.One); keyboard = Keyboard.GetState(); gamePadUp = gamePad.DPad.Up == ButtonState.Pressed || gamePad.ThumbSticks.Left.Y > 0.5f; gamePadDown = gamePad.DPad.Down == ButtonState.Pressed || gamePad.ThumbSticks.Left.Y < -0.5f; float moveFactorPerSecond = 0.5f * (float)gameTime.ElapsedRealTime.TotalMilliseconds/1000.0f; if (gamePadUp || keyboard.IsKeyDown(Keys.Up)) rightPaddlePosition -= moveFactorPerSecond; if (gamePadDown || keyboard.IsKeyDown(Keys.Down)) rightPaddlePosition += moveFactorPerSecond; … } ?
  • 29. TIP 2: SafeArea 화면의 가장자리에 중요한 UI 정보를 출력하지 않는다 . VGA 케이블로 연결된 PC 모니터 : 100% 혹은 이하 SCART 케이블로 연결된 구형 모니터 : 약 92% 컴포넌트 케이블로 연결된 HDTV 모니터 : 93~95% 일부 구형 모니터 : 80~90% SafeArea
  • 30. TIP 3: No Foreign References XNA Framework 에서 제공하는 dll 외의 dll 들을 함부로 호출하면 Xbox360 에서 정상적으로 컴파일 / 실행되지 않을 수 있음 . mscorlib.~ System.~ Microsoft.Xna.Framework.~ Microsoft.Xna.Framework.dll (XNA Graphic Engine) Microsoft.Xna.Framework.Game.dll (XNA Game Application Model) Microsoft.Xna.Framework.Conponent.Pipeline.dll (XNA Content Pipeline)
  • 31. Q & A Any questions? Refer to Creators Club ( http://creators.xna.com ) & MSDN!! E-mail: [email protected]