SYDESYDE
SYDESYDE
  • 피드
  • 쇼케이스
  • 블로그
  • 모임
SYDESYDE© 2026 SYDE. All rights reserved.
SYDE 소개문의하기
Kakao
SYDE 오픈채팅
Instagram
Instagram
Threads
Threads
커뮤니티 가이드라인협업문의이용약관개인정보처리방침
커뮤니티 가이드라인협업문의이용약관개인정보처리방침

© 2026 SYDE. All rights reserved.

방 코드를 만들었는데, 연결이 되지 않았다 — SAME DECK #4

방 코드를 만들었는데, 연결이 되지 않았다 — SAME DECK #4

mmustardoo· 8일 전· 해프닝·회고
목차
  • 친구에게 코드만 보내면 될 줄 알았다
  • 통신 테스트는 끝났는데, 종료할 때 충돌했다
  • 보냈다고 나오는데, 상대는 아무것도 받지 못했다
  • 한 번 연결하는 것보다 다시 연결하는 게 더 어려웠다
  • 이제 친구와 한 판을 시작할 수 있다
  • 돌아보며

목차

  • 친구에게 코드만 보내면 될 줄 알았다
  • 통신 테스트는 끝났는데, 종료할 때 충돌했다
  • 보냈다고 나오는데, 상대는 아무것도 받지 못했다
  • 한 번 연결하는 것보다 다시 연결하는 게 더 어려웠다
  • 이제 친구와 한 판을 시작할 수 있다
  • 돌아보며

지난 글에서는 SAME DECK의 첫 멀티플레이를 구현한 이야기를 했다.

서로 다른 컴퓨터에서 같은 전투를 진행할 수 있도록 만들었고, 실제 LAN 연결에도 성공했다.

하지만 친구와 게임을 하려면 여전히 IP 주소와 포트를 알아야 했다.

실제 두 컴퓨터로 연결을 시험했을 때는 게임이 잘못된 네트워크 주소를 선택하는 문제도 있었다.

정상적인 Wi-Fi 주소로 바꾸자 연결에 성공했지만, 접속에 실패했을 때는 아직 경기가 시작되지도 않았는데 MATCH ENDED라는 메시지가 표시되고 있었다.

이후 주소 선택 방식과 오류 메시지를 수정했다.

다만 이런 문제를 고치더라도 IP 주소를 직접 입력해야 한다는 불편함은 그대로였다.

그래서 친구에게 방 코드 하나만 보내면 함께 플레이할 수 있도록 멀티플레이 방식을 바꿔보기로 했다.

그런데 이 작업에서 예상보다 훨씬 많은 문제를 만나게 됐다.


친구에게 코드만 보내면 될 줄 알았다

온라인 연결을 위해 선택한 것은 Epic Online Services(EOS)였다.

게임에서 방을 생성하고, 코드를 공유하면 친구가 그 방을 찾아 참가할 수 있도록 구현했다.

이전처럼 상대방의 IP 주소나 포트를 직접 알아낼 필요가 없다는 점이 마음에 들었다.

플레이어에게 보여주고 싶었던 과정은 단순했다.

방 생성
   ↓
초대코드 공유
   ↓
친구가 코드로 참가
   ↓
양쪽 준비 완료
   ↓
전투 시작

기존에 구현한 LAN 멀티플레이의 전투 판정과 동기화 구조는 최대한 유지했다.

이미 만든 전투 시스템을 다시 구현하기보다는, 상대방과 연결되는 부분을 EOS 기반으로 바꾸는 데 집중했다.

그런데 개발을 진행하면서 알게 된 것은 방을 찾는 것과 실제로 게임 데이터를 주고받는 것은 다른 문제라는 점이었다.

방 검색과 참가 요청이 성공했다고 해서 두 컴퓨터가 곧바로 연결되는 것은 아니었다.

실제 네트워크 연결을 성립시키고, 상대방이 올바른 방에 참가했는지 확인하고, 양쪽에서 게임에 필요한 데이터를 주고받을 수 있어야 했다.

처음에는 연결 기능만 구현하면 될 것 같았지만, 실제로는 그 이후에도 확인해야 할 단계가 많았다.


통신 테스트는 끝났는데, 종료할 때 충돌했다

EOS 연동을 검증하던 중에는 조금 특이한 오류도 발견했다.

별도로 만든 Windows 네트워크 검증 프로그램에서 두 컴퓨터의 연결과 데이터 송수신까지 확인했는데, 프로그램을 종료하는 과정에서 충돌이 발생한 것이다.

화면에서는 작업이 끝난 것처럼 보였고 결과 기록도 남았다.

그런데 실제 프로그램은 정상 종료되지 않았다.

Windows에서 확인된 오류 코드는 0xC0000005였다. 잘못된 메모리 접근으로 발생할 수 있는 예외다.

처음에는 네트워크 연결이나 EOS 자원을 정리하는 과정에서 문제가 발생한 것인지 의심할 만한 상황이었다.

하지만 종료 시점의 호출 기록을 조사하면서 다른 가능성이 드러났다.

Godot과 연결한 네이티브 DLL에서 시간을 조회하기 위해 사용하던 코드가 문제였다.

당시 Godot의 C++ 바인딩을 통해 Time::get_singleton()을 호출하고 있었다.

그런데 프로그램 종료 과정에서 관련 DLL이 먼저 해제된 뒤에도, 엔진의 객체가 이미 해제된 DLL의 바인딩 콜백을 참조할 수 있는 상황이 있었다.

처음에는 이 설명만으로 실제 원인이라고 확신할 수 없었다.

그래서 EOS 연결이나 패킷 전송을 모두 제외하고, 문제가 의심되는 시간 조회 코드만 사용하는 작은 테스트를 만들었다.

그 결과 네트워크 연결을 전혀 하지 않았는데도 같은 종료 충돌이 반복해서 재현됐다.

이후 시간 정보를 조회하는 방식을 변경하고 동일한 조건에서 다시 테스트했다.

수정 전에는 반복해서 충돌하던 테스트가 수정 후에는 정상적으로 종료됐다.

네트워크 SDK 자체의 문제로 생각하기 쉬운 상황이었지만, 실제 원인은 Godot과 네이티브 코드 사이의 객체 수명에 있었던 것이다.

무엇보다 인상적이었던 것은 오류가 발생한 시점이었다.

게임이 실행되는 동안 아무 문제도 없어 보이더라도, 프로그램을 종료하는 마지막 순간에 문제가 발생할 수 있었다.

정상적으로 플레이하는 것과 정상적으로 종료하는 것은 별개의 문제였다.


보냈다고 나오는데, 상대는 아무것도 받지 못했다

종료 충돌을 수정하고 게임에 EOS를 통합한 뒤에는 실제 두 컴퓨터에서 온라인 대전을 시험했다.

정상적으로 경기를 진행한 기록도 생겼다.

그런데 이후 다른 연결 시도에서는 이해하기 어려운 문제가 발생했다.

방을 만들고 참가하는 과정은 진행됐지만, 정작 두 컴퓨터 사이의 실제 연결이 성립되지 않는 경우가 있었다.

로그를 확인해보니 Host에서는 연결에 필요한 메시지의 전송 요청이 여러 번 수락된 것으로 기록되어 있었다.

그런데 상대 컴퓨터에서는 해당 메시지를 수신한 기록이 없었다.

보냈다는 기록은 있는데, 받은 기록은 없었던 것이다.

처음에는 SDK가 전송 요청을 성공적으로 처리했다고 하니 상대에게도 도착했을 것이라고 생각하기 쉽다.

하지만 EOS SDK에서 반환하는 전송 성공은 데이터가 상대에게 무사히 도착했다는 뜻이 아니었다.

로컬 SDK가 전송 요청을 정상적으로 받아들여 큐에 넣었다는 의미였고, 실제 네트워크를 거쳐 상대에게 전달됐는지는 별도로 확인해야 했다.

단순하게 정리하면 이렇다.

Host
  │
  └─ 전송 요청
        ↓
     EOS SDK
        │
        └─ 요청 수락: 성공
                 │
                 └─ 실제 원격 전달: 미확인

Guest
  └─ 수신 기록: 없음

문제는 그사이에 정확히 무슨 일이 발생했는지 알 수 없다는 점이었다.

그래서 단순히 연결 실패라고만 기록하는 대신, 연결 과정을 여러 단계로 구분해서 확인하기 시작했다.

방을 찾았는지, 연결 요청이 수락됐는지, 실제 P2P 연결이 성립됐는지, 상대가 패킷을 수신했는지, 게임 입장까지 완료됐는지를 따로 기록했다.

이전에는 하나로 뭉뚱그려 보던 연결 과정이 실제로는 여러 단계로 나뉘어 있다는 것을 알게 됐다.

다만 기록을 세분화한다고 바로 원인을 찾을 수 있었던 것은 아니다.

일부 상황은 별도의 테스트로 재현할 수 있었지만, 당시 최초 연결 실패가 EOS 내부의 연결 협상이나 네트워크 경로 중 정확히 어디에서 발생했는지까지 확정하지는 못했다.

더 흥미로운 점은 이후 같은 게임 실행파일로 실제 연결에 성공했다는 사실이었다.

한쪽은 집 인터넷, 다른 한쪽은 모바일 네트워크를 사용하는 환경에서 EOS의 Relay 경로로 양쪽 연결과 입장을 확인했다.

하지만 성공했다고 해서 이전 실패의 원인을 해결했다고 말할 수는 없었다.

진단 도구를 수정한 뒤 연결에 성공한 기록이 있다고 해서, 그 수정 때문에 연결이 성공했다고 단정할 근거는 없었기 때문이다.

이 과정에서 문제를 조사하는 방식도 조금 달라졌다.

처음에는 오류가 발생하면 무엇을 고쳐야 할지부터 고민했지만, 이후에는 실제로 확인한 사실과 아직 가설에 불과한 것을 구분하는 데 더 신경 쓰게 됐다.


한 번 연결하는 것보다 다시 연결하는 게 더 어려웠다

온라인 멀티플레이에서는 한 번 연결하는 것만 생각해서는 안 됐다.

경기가 끝나면 다시 대전할 수도 있고, 방에서 나갔다가 다른 방에 들어갈 수도 있다.

그런데 초기 테스트에서는 첫 접속에 성공한 뒤 같은 프로그램에서 다시 방에 참가하려다 실패하는 상황도 있었다.

문제를 조사하면서 이전 방에서 사용하던 자원을 어떻게 정리할지 고민해야 했다.

실제로는 인증 갱신 작업을 아직 끝나지 않은 방 정리 작업처럼 계산해 새로운 방 요청을 막는 별도의 결함도 발견했다.

이 문제는 작은 테스트에서 재현한 뒤 수정했다.

다만 이 결함이 앞서 발생했던 모든 재입장 실패의 원인이라는 뜻은 아니었다. 실제로 확인한 문제와 아직 원인이 불분명한 연결 실패는 구분해서 다뤘다.

또 하나 어려웠던 것은 방에서 나갔다고 해서 관련 작업이 모두 즉시 끝나는 것은 아니라는 점이었다.

이미 보낸 방 생성이나 참가 요청의 응답이 뒤늦게 도착할 수 있었고, 이전 방의 작업이 새로 만든 방에 영향을 주지 않도록 처리해야 했다.

처음에는 방을 만들고 연결하는 기능에 집중했지만, 개발을 진행할수록 안전하게 나가고 다시 들어오는 과정도 중요해졌다.

친구와 게임을 하다가 한 명이 나갔다고 해서 프로그램을 반드시 다시 실행해야 한다면, 사용자 입장에서는 꽤 번거로울 것이다.

결국 멀티플레이는 연결을 만드는 기능뿐 아니라, 그 연결이 끝났을 때 다음 플레이를 정상적으로 준비하는 기능까지 필요했다.


이제 친구와 한 판을 시작할 수 있다

이런 문제들을 확인하고 수정하는 동안 게임을 시작하는 과정도 조금씩 바꿨다.

처음에는 양쪽이 준비를 마친 뒤 별도의 시작 과정과 고정된 대기시간이 있었다.

이후에는 두 컴퓨터의 전투 화면이 실제로 준비됐는지 확인하고, 준비가 끝나면 자동으로 게임을 시작하도록 수정했다.

단순히 일정 시간 기다리는 대신, 실제 게임의 준비 상태를 기준으로 다음 단계로 넘어가게 만든 것이다.

불필요하게 기다리는 시간을 줄이고, 한쪽 화면이 아직 준비되지 않았는데 게임이 시작되는 상황도 방지하고 싶었다.

그리고 여러 차례의 테스트를 거쳐 실제 두 컴퓨터에서 방을 만들고, 코드를 입력해 참가하고, 전투를 진행할 수 있게 됐다.

실제 경기를 끝까지 플레이하고, 양쪽에서 재대전을 선택해 다음 경기에 들어가거나 메뉴로 돌아와 종료하는 과정도 확인했다.

최근 전투 규칙을 변경한 빌드에서도 기본적인 두 PC 플레이가 정상적으로 이루어지는 것을 확인했다.

이제는 방 생성부터 참가, 전투, 재대전, 종료까지 멀티플레이의 기본적인 플레이 흐름을 실제로 진행할 수 있게 된 것이다.

물론 이것이 모든 네트워크 환경에서 문제없이 동작한다는 의미는 아니다.

여전히 원인이 확정되지 않은 과거 연결 실패가 있고, 장시간 플레이나 다양한 네트워크 환경에서의 안정성은 추가로 확인할 부분이 남아 있다.

일반 사용자를 대상으로 한 공개 배포 역시 별도의 준비가 필요하다.

하지만 처음 만들려고 했던 친구 대전의 기본적인 모습은 갖추게 됐다.


돌아보며

처음에는 방 코드를 만들고 기존 전투 시스템에 연결하면 될 것 같았다.

그런데 실제로는 연결 과정뿐 아니라 프로그램 종료, 방 정리, 재입장, 두 컴퓨터의 준비 상태처럼 생각하지 못했던 부분에 훨씬 많은 시간을 사용했다.

어떤 문제는 정확한 원인을 찾아 수정할 수 있었고, 어떤 문제는 실제 증상이 사라지거나 연결에 성공했어도 원인까지 확정하지는 못했다.

그래도 이런 과정들을 거치면서 조금씩 실제 플레이할 수 있는 게임에 가까워졌다고 생각한다.

친구 입장에서는 방 코드를 입력하고 게임을 시작하는 단순한 과정이다.

하지만 그 과정이 자연스럽게 동작하도록 만들기 위해서는 꽤 많은 부분을 신경 써야 했다.

멀티플레이에서 어려웠던 것은 단순히 두 컴퓨터를 연결하는 것보다, 플레이어가 연결 과정을 크게 의식하지 않고 게임을 시작하고 끝낼 수 있게 만드는 일이었다.

아직 베타 개발 중이고 다듬어야 할 부분도 남아 있지만, 이제는 친구에게 SAME DECK을 보내고 방 코드를 공유해 함께 한 판을 플레이할 수 있게 됐다.

처음 생각했던 WITH FRIEND 모드가 실제로 동작하는 모습을 확인했다는 점에서 의미 있는 작업이었다.

  • #1인개발
  • #게임개발
14
m
mustardoo

mustardoo님의 다른 글

  • 멀티플레이를 만들었다 — SAME DECK #38일 전
  • 같은 덱을 쓴다고 전략이 생기는가? — SAME DECK #212일 전
  • 하나의 덱을 공유하는 턴제 게임 — SAME DECK #119일 전

댓글 0

My avatar