프로젝트 회고-GitHub Pages와 Firebase로 첫 실시간 멀티플레이 도전
“GitHub Pages에 멀티플레이 게임을 올릴 수 있을까?”
모든 것은 이 단순한 질문에서 시작됐습니다. 정적(Static)인 페이지만을 호스팅할 수 있는 GitHub Pages에 어떻게 두 명의 플레이어가 실시간으로 상호작용하는 게임을 만들 수 있을까? 처음에는 막연하게 느껴졌지만, 이내 아주 흥미로운 해법을 찾게 되었습니다. 바로 ‘서버 없는 서버’, Firebase Realtime Database를 활용하는 것이었죠.
이번 프로젝트는 단순한 가위바위보 게임을 넘어, 현대적인 웹 기술을 활용해 어떻게 제한된 환경에서 영리하게 동적인 경험을 만들어낼 수 있는지 배울 수 있었던 값진 여정이었습니다.
핵심 아이디어: ‘서버 없는’ 서버, Firebase
가장 큰 허들은 ‘상태 관리’였습니다. 플레이어 1이 ‘가위’를 냈다는 것을 어떻게 플레이어 2가 알 수 있을까요? 전통적인 방식이라면 Node.js나 Python으로 직접 서버를 구축하고, WebSocket 같은 기술로 실시간 통신을 구현해야 했을 겁니다.
하지만 Firebase는 이 패러다임을 완전히 바꿨습니다. Firebase의 Realtime Database는 클라우드에 존재하는 거대한 JSON 객체라고 생각할 수 있습니다. 우리 프로젝트에서는 이 데이터베이스를 ‘게임의 현재 상태’를 저장하는 중앙 허브로 사용했습니다.
- 플레이어 접속: P1이 접속하면, 데이터베이스에 { “player1”: { “online”: true, “score”: 0 } } 와 같은 데이터를 씁니다.
- 선택: P1이 ‘바위’를 내면, { “player1”: { “choice”: “rock” } } 로 데이터를 업데이트합니다.
- 상태 감지: 모든 플레이어의 클라이언트(브라우저)는 이 데이터베이스의 변화를 실시간으로 감지(onValue)합니다. P2의 화면은 P1의 데이터가 업데이트되는 순간, 그 사실을 즉시 알아채고 화면을 갱신할 수 있습니다.
서버 코드를 한 줄도 작성하지 않고, 복잡한 실시간 통신 문제를 아주 우아하게 해결한 것입니다.
구현 과정: 조각 맞추기
-
기본 구조 (HTML/CSS): 먼저 index.html에 로그인 화면, 게임 화면, 점수판, 선택 버튼 등 모든 시각적 요소를 배치했습니다. 처음에는 플레이어 코드를 입력받는 방식이었지만, 사용성을 개선하기 위해 ‘P1 접속’, ‘P2 접속’ 버튼 방식으로 변경하는 등 작은 개선을 거쳤습니다.
-
Firebase 연동 (
app.js
): app.js에서는 Firebase SDK를 가져와 우리가 만든 Firebase 프로젝트와 연결했습니다. 이 과정에서 firebaseConfig 객체에 databaseURL을 명시적으로 추가해야 한다는 중요한 사실을 배웠습니다. -
핵심 로직 구현:
- 로그인: 플레이어가 버튼을 누르면, 해당 플레이어의 상태(온라인 여부, 점수)를 Firebase에 기록하고 게임 화면으로 전환합니다.
- 게임 플레이: 가위/바위/보 버튼을 누르면, 자신의 선택(choice)을 Firebase에 기록합니다.
- 결과 판정: onValue 리스너는 항상 데이터베이스를 감시하다가, 두 플레이어의 choice가 모두 기록되면 승패를 판정하고 점수를 업데이트합니다.
- 동기화: 한쪽에서 게임을 초기화하면, Firebase의 게임 데이터 전체(game 객체)를 null로 만들어 버립니다. 그러면 다른 쪽 클라이언트가 데이터가 사라진 것을 감지하고, “게임이 초기화되었습니다” 라는 메시지와 함께 자동으로 페이지를 새로고침하여 로그인 화면으로 돌아가게 만들었습니다. 이는 모든 사용자의 경험을 일관성 있게 유지하는 아주 중요한 부분이었습니다.
좌충우돌: 문제 해결의 순간들
개발 과정이 순탄하기만 한 것은 아니었습니다. 몇 가지 중요한 배움의 순간이 있었죠.
- “왜 내 컴퓨터에선 안 되지?”: 처음 파일을 만들고 브라우저에서 열었을 때, 버튼이 아무 반응도 하지 않았습니다. import 같은 모듈 시스템과 외부 서비스 연동은 보안 정책상 file:// 프로토콜에서는 작동하지 않는다는 사실을 깨달았습니다. python -m http.server 명령어로 간단한 로컬 웹 서버를 띄우자마자 모든 것이 마법처럼 작동하기 시작했습니다.
- “버튼이 안 눌려요!”: 로그인 방식을 버튼으로 바꾼 직후, 또다시 버튼이 먹통이 되는 현상을 겪었습니다. 원인은 자바스크립트에서 이벤트를 연결하는 방식의 작은 실수였습니다. 복잡한 함수 호출 구조 대신, 각 버튼에 직접 이벤트 리스너를 할당하는 더 단순하고 명확한 방식으로 코드를 리팩토링하여 문제를 해결할 수 있었습니다.
마치며
이번 프로젝트는 기술적인 성취만큼이나 ‘아이디어를 어떻게 현실로 만드는가’에 대한 깊은 통찰을 주었습니다. 거창한 서버 인프라 없이도, Firebase와 같은 훌륭한 BaaS(Backend-as-a-Service)를 활용하면 아이디어를 빠르고 효율적으로 프로토타이핑하고 실제 작동하는 서비스로 만들 수 있다는 자신감을 얻었습니다.