[나만무] 멀티플레이어 게임 구현하기

개발 공부 일기·2023년 7월 16일
0

colyseus의 createRoom 등을 사용해야한다는 생각은 계속 하고 있었는데, 기존에 있던 내용을 어떻게 활용해야할지 계속 감이 오지 않고 있었다.
그러다가 오늘 문득 들었던 생각이 원래 SkyOffice에서 CustomRoom 을 입장하는 프로세스를 그대로 가져와서 사용하자는 것이었다.

그 과정에서 고민해야했던 사항들

  • Bootstrap 파일은 메인 게임 launch와 preload를 담당한다.

  • 미니게임에 입장했을 때 배경에 원래 맵이 보이도록 하는게 좋을까?

    • 이 방법으로 하면 메인 게임에 입장해있음과 동시에 게임 룸에도 입장해있어야 하고
    • 멀티플레이를 하는 동안 배경에서 다른 캐릭터가 움직일 수도 있다는거고..
    • 네트워크고 이중으로 연결해야하는건데 될지도 모르겠죠
    • 해서 여러모로 좋지 않은 선택이라는 판단이 섰다
  • 미니게임에 입장하면 기존의 Scene 대신 새로운 미니게임 맵이 그려진다

    • 오래전에 크레이지 아케이드를 플레이 하던 시절에 (화면이 거의 기억이 안나서 이 기억이 맞는지 모르겠는데) 게임룸에 입장하면 캐릭터들이 자유롭게 돌아다닐 수 있었고, ready를 하면 그 캐릭터 위에 떴던 것 같다.. 아무튼 전반적으로 넥슨 게임들은 이런 시스템을 갖췄던 것 같아서, 그 느낌으로 해보려고 한다.
    • 그러기 위해서 메인 게임 preload와 launch 기능을 담당하는 Bootstrap scene을 게임 용으로 하나 더 만들어준다 (진행중)
      • Network 인스턴스를 하나 더 생성하게 된다. (하나 더 생성하는게 맞을까?? 좀더 따져봐야할 것 같다.)
    • Network 파일을 게임 룸 전용으로 새로 만들까 했었는데, 같은 connection 안에 있어야 Player 데이터를 더 원활하게 가져올 수 있지 않을까 해서 같은 Network 안에서 다시 작업해보고 있음 (근데 이게 맞는지 모르겠음... 결국 다 만든 후에나 검증이 가능할 것 같다..)
    • Bootstrap 파일과 마찬가지로 Game 파일을 재활용해서 플레이어 대기 화면을 만든다. 이 안에서 채팅이 가능하도록 해도 될 것 같다.
    • Player, OtherPlayer, MyPlayer 의 게임 버전 파일을 새로 만든다 (게임 별로 별도의 파일을 생성해야할 수도 있음)
  • network의 인스턴스를 만들면 constructor에서 현재 port를 지정하고, lobbyroom에 입장하도록 되어있다. connection을 build함과 동시에 lobbyroom을 사용하는 것

    1. roomtype에 따라서 lobby에서 보여주는 room 목록이 달라질 수 있다면.. gamelobby를 굳이 따로 만들지 않고 하나로 통합할 수 있지 않을까?
    2. lobby에서 보여주는 room 목록을 게임 별로 다르게 할 수 없다면 게임 타입 별로 각각의 gamelobby를 만들어줘야 하나..?
  • 근데 같은 port에 대해서 새로운 network 인스턴스를 생성하면 어떻게 되는걸까?
    네, 동일한 도메인과 포트를 사용하여 여러 개의 방에 동시에 접속할 수 있습니다. 각각의 Network 인스턴스는 독립적으로 동작하며, 서로 다른 방에 연결할 수 있습니다. 예를 들어, 하나의 Network 인스턴스를 사용하여 Public Room에 접속한 후, 다른 Network 인스턴스를 생성하여 Lobby Room에서 Custom Room에 접속할 수 있습니다.

Network 클래스의 생성자에서 Colyseus 클라이언트를 초기화하고 Lobby Room에 입장하는 부분이 보입니다. 이후에 joinLobbyRoom() 메서드를 호출하여 Lobby Room에 입장합니다. 그런 다음 joinOrCreatePublic() 또는 joinCustomById() 등의 메서드를 호출하여 다른 방에 접속할 수 있습니다.

Network 인스턴스는 독립적으로 방에 입장하고 메시지를 주고받을 수 있으므로, 여러 방에 동시에 접속하는 것은 문제가 되지 않습니다. 다만, 각 방에 대한 인스턴스를 따로 관리해야하며, 해당 인스턴스에서 발생하는 이벤트나 데이터는 해당 방에만 영향을 미칩니다.

👉🏻 OK 내가 생각했던 대로, 내가 알던 개념 대로, network 인스턴스를 새로 만들면 서로 별개로 작동하는게 맞다
그러니까.. 하나의 client에서 여러개의 network 인스턴스를 생성할 수 있는 상황!

계속해서 이런저런 시도를 하고 있지만 createRoom 이 잘 안 되는 상황이다.
GameRoomStore를 별도로 만들어서 해 봤는데, 하나의 RoomStore에 합치는 방향으로 다시 수정해보려고 한다.
lobby는 결국 network 인스턴스가 생성될 때 마다 참여하고, 실제 게임이 launch되면 방을 퇴장하는 것으로 확인하였으며, 그 뜻은 굳이 따로 game lobby를 만들 필요가 없고, 모든 room을 다 같은 roomSlice로 취급하면 될 것이라는 결론을 얻었다.

앞서 언급했던 lobby 부분이 고민이었는데, chatGPT와 상의해서 도달한 방법은 RoomStore에서 AvailableRoom을 타입 별로 따로 정의 하고(!!) 나머지 필드는 그대로 가져가는 방법이었다. gpt는 RoomInterface에 name과 더불어 type을 추가하는 방향으로 제안을 했으나, 내 판단에 의하면 name만 있어도 될 것 같아서 따로 추가하지는 않았다.
name에 할당되는 RoomType을 PUBLIC과 CUSTOM에 더불어 각각의 game type 을 추가해주었다.

Network class에서도 RoomType 별로 roomCreate 함수를 따로 정의해주었다.
Network와 RoomStore에서의 room 관리에 대한 싱크를 맞추는게 가장 중요할 것 같다.
위에서 언급했듯이 lobby는 하나만 사용할 예정이기 때문에, 새로운 유저가 입장하거나 유저가 게임에 입장하려고 할 때, 모든 room 정보를 불러와야한다는 단점이 있는 것 같다.

  • 이 부분은 추후에 바꿔야 할 것 같다. 처음에는 lobby room이 너무 많아지는 것도 좋지 않은 것 같기도 하고, lobby 종류가 여러개 있는게 network 와의 싱크를 맞추는 부분에서 어려울 것 같아 이 방향으로 진행하고 있었는데, 일반적인 게임에서 로드량을 생각한다면 각 게임 별로 lobby room을 따로 만드는게 당연하지 않을까 싶다. 우선은 지금 버전에서 되게 한 후에 고쳐보자..

0개의 댓글