← 프로젝트 프로젝트 케이스 스터디

GAWIBAWIBO

자리를 비운 사이에도 승부가 성립하는 비동기 사전입력 × 실시간 판정 가위바위보 등반 게임입니다

계단 1번째 칸에서 도전자와 봇 수비자가 마주 서고 화면 중앙에 보! 챈트, 아래에 가위·바위·보 입력 버튼이 표시된 인게임 화면입니다.
역할
1인 개발 — 기획·시스템디자인·클라이언트/서버 개발 전반
기간
2026년 7월
스택
Node.js(node:http · ws · node:sqlite) · three.js · WebAuthn 패스키 · AES-256-GCM · SHA-256 커밋먼트 · Cloudflare Tunnel/Turnstile

가위바위보로 지상에서 우주까지 100칸 계단을 오르는 온라인 게임입니다. 위로 도전할 때는 “가위 바위 보!” 신호 뒤 1초 안에 입력하는 실시간 승부이고 아래에서 올라오는 도전은 접속해 있지 않아도 미리 남겨 둔 5수 시퀀스가 대신 받아냅니다. 이 비대칭이 프로젝트의 출발점입니다. 소규모 커뮤니티 게임은 ‘지금 접속한 상대’가 없으면 PvP가 성립하지 않지만 수비를 비동기로 두면 계단 위의 모든 칸이 언제나 도전 가능한 상대가 됩니다. 5판 중 3승이면 윗칸 점유자와 자리를 바꾸고 100번째 칸에 오르면 명예의 전당에 영구 기록된 뒤 지상에서 새 등반을 시작합니다.

사전입력 게임의 성패는 시퀀스가 유출되지 않는다는 신뢰에 달려 있습니다. 그래서 비노출을 서버 불변식으로 두었습니다. 상대 손은 라운드 판정이 끝난 뒤에만 공개되고, 미사용 시퀀스의 내용을 반환하는 API 경로 자체가 없고, 저장은 AES-256-GCM 암호문으로만 합니다. 동시에 서버가 조작하지 않는다는 것도 증명해야 하므로 저장 시점에 SHA-256(salt‖throws) 커밋 해시를 즉시 공개하고 매치 종료 후 salt와 원문을 공개해 누구나 검증할 수 있게 했습니다. 경우의 수가 243개뿐이어도 128비트 salt 덕에 커밋만으로는 역산이 불가능합니다. 타이밍도 서버 시계로 판정하되 관측된 최소 RTT의 절반만 유예를 줍니다. 처음에는 클라이언트가 보고하는 RTT를 믿었지만 레드팀 하네스가 pong을 지연시켜 입력 마감을 늘리는 공격을 재현해서 최솟값 기준으로 바꿨습니다. 도전에서 낸 손 5개가 다음 수비 시퀀스로 자동 적립됩니다. 관전자가 라운드별 순서를 기억해도 소용없도록 저장 시 CSPRNG로 순서를 섞습니다.

게임디자인 관점의 과제는 가위바위보라는 순수 운 게임에 실력의 여지를 만드는 것이었습니다. 답은 봇의 성향 시스템입니다. 빈 칸을 채우는 봇마다 바위 선호·고집·순환 같은 손 성향 6종 중 하나가 고정되고 그 힌트가 대결 중 말풍선으로 공개됩니다. 힌트를 읽고 대응하는 플레이어는 완주 하네스 기준 승률 57.5%로 무작위(약 21%)를 크게 앞섭니다. 성향 강도는 고도가 오를수록 약해져 자연스러운 난이도 곡선을 만듭니다. 시퀀스가 소진된 인간 수비자는 워크오버로 자리를 내주므로 방치한 계정이 계단을 막지 못하고, 양쪽이 모두 접속 중이면 서버가 실시간 대결을 먼저 제안해 진검승부로 전환합니다. 25·50·75칸 체크포인트는 첫 도달 시 골드를 주고 추락 후 귀환 지점이 되어 반복 등반의 지루함을 덜어 줍니다.

연출은 three.js 씬 하나로 전부 그리고 내려받는 아트 에셋이 0개입니다. 지형·구름·별·복셀 캐릭터를 모두 코드로 생성합니다. 지상에서는 강과 산이 보이고 오를수록 하늘이 어두워지고 별이 떠오릅니다. 정상 등극은 우주로 날아오르는 비행과 불꽃놀이로 마무리됩니다. 승부가 나면 승자가 패자를 아래칸으로 밀어 떨어뜨리고 놀리는 포즈를 취합니다. 스킨 15종의 승리 포즈가 삿대질부터 로봇 댄스까지 전부 다르고 밀기·추락·좌절 동작도 스킨마다 조합이 유일하도록 테스트가 강제합니다. 골드로 사는 계단 장식 26종과 6슬롯 착용 아이템 28종은 구매 즉시 자기 칸과 캐릭터에 반영되어 계단을 스크롤해 구경하는 것만으로 다른 플레이어의 취향이 보입니다.

배포 전에 유닛 테스트 27건, 헤드리스 브라우저 e2e, 런타임 레드팀 12케이스, 지상에서 100칸까지 실제로 완주하는 등반 하네스를 갖추고 보안 감사에서 나온 16건을 모두 수정했습니다. 그중에는 마지막 라운드 판정 직후 연결이 끊기면 이긴 매치가 몰수패로 뒤집히는 치명적 버그도 있었습니다. 운영은 도커와 Cloudflare Tunnel로 홈랩에서 하고 신규 계정 생성에만 Turnstile 봇 게이트를 둡니다. 계정은 이름 하나로 시작하되 패스키를 등록하면 다른 기기에서도 같은 이름으로 이어집니다.

← 프로젝트로 돌아가기