실시간 오목 게임 만들기
오목 샘플을 워크스페이스에 올리고 스키마를 배포해 두 사용자가 실시간으로 대국하는 게임을 실행합니다. 한 사용자가 돌을 놓으면 상대 화면에도 같은 수가 표시되고, 승패와 순위는 서버가 기록합니다.
별도의 프론트엔드 빌드 도구는 필요하지 않습니다. 완성된 샘플을 실행한 뒤 데이터 구조, 실시간 기능과 게임 규칙을 바꿔 볼 수 있습니다.

1. 샘플 내려받기
처음에는 전체 샘플 ZIP으로 시작합니다. 스키마와 화면 파일을 같은 폴더에 올리고 스키마를 배포하면 바로 대국을 열 수 있습니다.
- 실시간 오목 전체 샘플 ZIP 다운로드: 스키마와
index.html,style.css,app.js, README 포함 - 오목 스키마 파일(.sfn) 다운로드: 백엔드 구조만 살펴보거나 직접 만든 화면과 연결할 때
샘플에서는 다음 기능을 확인할 수 있습니다.
- 방 코드를 이용한 두 사용자 대국
- 마지막 수, 내 돌과 현재 차례 표시
- 한 수마다 다시 시작되는 3분 제한시간
- 진행 상황을 알려 주는 실시간 경기 중계
- 승리·패배 표시와 최근 대국, 플레이어 순위 자동 갱신
스키마에는 19×19 보드와 다섯 돌 승리, 승 3점·무승부 1점·패 0점 규칙이 미리 들어 있습니다. 사용자당 최대 3개의 대기방을 만들 수 있고, 30분 동안 참가자가 없는 대기방은 정리 대상으로 처리됩니다.
게임 안에서 작동하는 기능
오목 샘플은 웹스페이스의 다음 기능을 사용합니다.
| 기능 | 오목에서 하는 일 |
|---|---|
| 스키마 파일 | 대국, 착수 기록과 사용자 전적 구조 정의 |
| REST API | 최근 대국과 플레이어 순위 조회 |
| WebSocket | 방 생성·참가와 착수 결과를 실시간 전달 |
| 이벤트 처리기 | 차례, 좌표, 승리 조건과 제한시간을 서버에서 판정 |
| 회원 권한 | 로그인한 사용자만 대국에 참여 |
| 협업 기능 | 같은 화면에서 참가자와 대화 |
승패와 점수는 브라우저가 아니라 서버가 결정합니다. 서버는 현재 판과 차례를 확인해 정상적인 착수만 저장하고, 두 사용자에게 같은 결과를 보냅니다.
2. 워크스페이스에 올리기
스키마 파일만 내려받았다면 팀 또는 개인 워크스페이스의 프로젝트 폴더에 업로드합니다. 전체 샘플 ZIP을 내려받았다면 폴더 업로드나 압축 파일 업로드로 다섯 파일을 같은 폴더에 둡니다.
오목대국장/
├── gomoku-realtime.sfn
├── index.html
├── style.css
├── app.js
└── README.md
스키마 파일을 열고 DB구조에서 세 개의 테이블을 확인합니다.
| 테이블 | 저장 내용 |
|---|---|
gomoku_games | 방 코드, 참가자, 현재 차례, 제한시간과 최종 결과 |
gomoku_moves | 몇 번째 수인지, 돌 색상, 좌표와 사용자 |
gomoku_players | 사용자별 승·패·무, 누적 점수와 최근 경기 |
대국과 전적을 나눠 저장하기 때문에 화면을 새로 열어도 최근 기록과 순위를 다시 불러올 수 있습니다.
3. API와 실시간 기능 확인하기
API빌드 탭을 열고 다음 항목을 확인합니다.
- 데이터베이스 이름이
gomoku인지 확인합니다. 실시간 소켓이사용함인지 확인합니다.서버 제공 기능이턴 기반 보드게임(turn-based-board)인지 확인합니다.보내기와받기권한이회원만인지 확인합니다.- 세 테이블의 등록과 수정 API가 비활성화되어 있는지 확인합니다.
등록과 수정 API를 끄면 참가자가 REST API로 승리 횟수나 착수 기록을 직접 바꿀 수 없고, 모든 게임 상태 변경이 서버의 이벤트 처리기를 거칩니다.
4. SQLite3로 배포하기
처음 실행할 때는 스토리지에서 SQLite3를 선택합니다. 별도의 데이터베이스 주소나 계정이 필요하지 않습니다.
배포하기를 선택하기 전에 화면에 표시되는 변경 내용과 권한 요약을 확인합니다. 이미 같은 이름의 데이터베이스에 기록이 있다면 서버의 덮어쓰기 정책에 따라 관리자 또는 배포 담당자의 승인이 필요할 수 있습니다.
배포가 끝나면 다음 주소 형식의 REST API와 WebSocket이 준비됩니다.
GET /api/web/gomoku/gomoku_games/list
GET /api/web/gomoku/gomoku_players/list
WS /api/web/gomoku/realtime-ws
운영 서버가 HTTPS라면 같은 도메인의 wss://로 연결합니다. WebSocket 주소는 특정 개발 도메인으로 고정하지 말고 현재 페이지의 호스트를 기준으로 만듭니다.
5. 오목 화면 열기
스키마 파일은 게임의 데이터베이스와 백엔드를, index.html, style.css, app.js는 바둑판 화면을 담당합니다. 두 부분이 나뉘어 있어 대국 기록을 유지한 채 화면만 바꿀 수 있습니다.
전체 샘플을 올렸다면 index.html을 선택하고 미리보기를 엽니다. 스키마 파일만 사용한다면 직접 만든 HTML에서 위의 REST API와 WebSocket을 연결합니다.
클라이언트는 board-game.create, board-game.join, board-game.move 같은 동작을 WebSocket으로 보냅니다. 돌과 점수는 서버에서 돌아온 확정 이벤트를 기준으로 표시합니다.
6. 두 명이 대국하기
- 서로 다른 회원 계정으로 같은
index.html을 엽니다. - 첫 번째 계정에서
새 대국 만들기를 선택합니다. - 만들어진 방 코드를 두 번째 계정에 전달합니다.
- 두 번째 계정에서 코드를 입력하고
참가하기를 선택합니다. - 번갈아 돌을 놓고 두 화면에 같은 수가 표시되는지 확인합니다.
- 다섯 돌이 이어진 뒤 승리 표시, 최근 대국과 순위가 갱신되는지 확인합니다.
한 컴퓨터에서 테스트하려면 일반 창과 시크릿 창처럼 로그인 세션이 분리된 브라우저를 사용합니다.

대국 결과 확인하기
가로, 세로 또는 대각선으로 다섯 돌이 이어지면 서버가 대국을 끝내고 승자와 점수를 저장합니다. 한 수의 제한시간이 지나도 서버 시각을 기준으로 시간패가 결정됩니다.

최근 대국과 순위가 바로 바뀌지 않으면 버튼을 다시 누르기보다, WebSocket의 종료 이벤트를 받은 뒤 목록을 다시 조회하는 흐름인지 확인합니다. 화면의 개발 정보를 펼치면 송수신 JSON과 서버 처리시간도 확인할 수 있습니다.
다른 게임으로 바꾸기
turn-based-board는 오목 전용 처리기가 아닙니다. 스키마 파일의 처리기 설정에서 다음 값을 바꿔 다른 턴 기반 게임에 사용할 수 있습니다.
| 설정 | 현재 값 | 의미 |
|---|---|---|
boardSize | 19 | 보드 한 변의 칸 수 |
winLength | 5 | 승리에 필요한 연속 돌 수 |
turnTimeSeconds | 180 | 한 수의 제한시간 |
winScore | 3 | 승리 점수 |
drawScore | 1 | 무승부 점수 |
lossScore | 0 | 패배 점수 |
예를 들어 보드 크기를 줄여 빠른 게임으로 바꾸거나, 점수 규칙을 행사에 맞게 조정할 수 있습니다.
문제가 생겼을 때
| 증상 | 확인할 항목 |
|---|---|
| 실시간 이벤트 처리기를 사용할 수 없음 | 서버가 현재 스키마의 turn-based-board 처리기를 지원하는 버전인지 확인 |
| 새 대국이나 참가 버튼이 동작하지 않음 | DB 배포 상태, 실시간 기능, 로그인과 송수신 권한 확인 |
401 Unauthorized | 로그인 세션이 유효한지 확인하고 URL 쿼리에 토큰을 직접 넣지 않았는지 확인 |
| 운영 서버에서 WebSocket이 차단됨 | HTTPS 페이지가 wss://를 사용하고 CSP의 connect-src가 허용됐는지 확인 |
| 수정한 화면이 이전 모습으로 보임 | 미리보기를 다시 열고 정적 파일의 최신 버전이 응답되는지 확인 |