실시간 오목 게임 만들기
파일을 올리고 스키마를 배포한 다음 브라우저 두 개를 열어 보세요. 한쪽에서 만든 방에 친구가 참가하고, 돌을 놓는 순간 다른 화면에도 같은 수가 나타납니다. 승패와 순위는 서버가 알아서 기록합니다.
별도의 프론트엔드 빌드 도구는 필요하지 않습니다. 완성된 샘플로 한 판을 먼저 실행한 뒤 데이터 구조, 실시간 기능과 게임 규칙을 하나씩 바꿔볼 수 있습니다.

1. 먼저 한 판 실행해 보기
처음에는 전체 샘플 ZIP으로 시작하는 편이 가장 빠릅니다. 스키마와 화면 파일을 같은 폴더에 올리고 스키마를 배포하면 바로 대국을 열 수 있습니다.
- 실시간 오목 전체 샘플 ZIP 다운로드: 스키마와
index.html,style.css,app.js, README 포함 - 오목 스키마 파일(.sfn) 다운로드: 백엔드 구조만 살펴보거나 직접 만든 화면과 연결할 때
샘플을 실행하면 다음 장면을 직접 확인할 수 있습니다.
- 방 코드를 이용한 두 사용자 대국
- 마지막 수, 내 돌과 현재 차례 표시
- 한 수마다 다시 시작되는 3분 제한시간
- 진행 상황을 알려 주는 실시간 경기 중계
- 승리·패배 표시와 최근 대국, 플레이어 순위 자동 갱신
스키마에는 19×19 보드와 다섯 돌 승리, 승 3점·무승부 1점·패 0점 규칙이 미리 들어 있습니다. 사용자당 최대 3개의 대기방을 만들 수 있고, 30분 동안 참가자가 없는 대기방은 정리 대상으로 처리됩니다.
게임 안에서 작동하는 기능
오목 한 판에는 WebSpace의 주요 기능이 자연스럽게 들어 있습니다.
| 기능 | 오목에서 하는 일 |
|---|---|
| 스키마 파일 | 대국, 착수 기록과 사용자 전적 구조 정의 |
| 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:// 연결을 사용해야 합니다. 주소를 특정 개발 도메인으로 코드에 고정하지 않고 현재 페이지의 호스트를 기준으로 만드는 것이 좋습니다.
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가 허용됐는지 확인 |
| 수정한 화면이 이전 모습으로 보임 | 미리보기를 다시 열고 정적 파일의 최신 버전이 응답되는지 확인 |
마치며
정적 페이지 하나였던 첫 예제에서 시작해, 데이터베이스, 테이블 간 관계, 역할별 권한, 조직 밖에서 들어오는 파일 제출, 그리고 서버가 직접 판정하는 실시간 게임 상태까지 이어왔습니다. 각 예제는 이전 예제 위에 개념을 하나씩만 더하는 방식으로 구성했습니다. 필요한 기능에 따라 이 중 몇 가지를 조합하면, 대부분의 사내·대고객 도구를 WebSpace만으로 만들 수 있습니다.