- 규칙 모듈 packages/games/src/mafia: 4~12명, 자동/수동 마피아 수, 추가 직업(군인·정치인·영매·연인),
서버 타이머가 phaseTimeout(시스템 전용)으로 페이즈 진행, 인사 낮/토론(±15초, 토론 끝내기)/지목 투표/
최후의 반론/찬반 투표/밤(마피아 공용 대상, 경찰·영매 결과는 밤 마감 시 전달, 의사·군인 순서),
채널(전체/마피아/죽은 사람/연인) 권한을 view에서 필터, 레이트 리밋·고운 말 필터, 자리 비움(2일) 탈락,
나가기 즉시 탈락, 승리 판정·결과(MVP 포함)
- 테스트: 문서 §10 항목 전부, 시드 1,000판 무작위 대국(불변식·누출·onTimeout 합법·결정성),
엔진 randomPlayout, 기록 재생, 실제 Room 통과 테스트(방 채팅 닫힘, 연결별 채팅 필터)
- 화면 apps/web/src/games/mafia: 낮/밤 배너와 큰 남은 시간, 채널 탭 채팅, 꾹 눌러 보는 내 직업,
그리드에서 투표·밤 대상 고르기, 아침 발표·득표 막대, 최종 공개
- 공용 코드(하위 호환): GameDefinition.ownChat, validate의 선택 ctx {now}; Room이 ownChat 게임 진행 중
방 채팅·반응을 거절하고 validate에 서버 시각 전달; 웹 GameUI.ownChat이면 진행 중 방 채팅 패널 숨김
- 등록(GAMES, 카탈로그, 화면 레지스트리, 아이콘)과 E2E 계획(PC 방장 + 휴대폰 3명)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- packages/games/src/halli-galli: 56장 과일 카드, 차례 뒤집기(flipGuard 예약), 언제나 칠 수 있는 종
(tableVersion으로 늦은 종 "늦었어요" 무벌칙, 서버 도착 순서 우선), 오답 벌칙·탈락, official/시간 제한 종료,
하우스 룰(1대1 오답 패배, 3진 아웃, 벌칙 증가, 벌칙 종 밑), latencyComp light 50ms 창,
view는 덱 내용을 본인에게도 숨김(장수만), secretsOf/legalActions 제공
- 테스트: §10 체크리스트 전부, 1,000판 시드 랜덤 플레이아웃(카드 보존·누출·onTimeout 합법·결정성) +
엔진 randomPlayout, 서버 Room 테스트(동시 종 도착 순서, 늦은 종 거절, 자리 비움 자동 뒤집기)
- 화면: 원형 좌석 배치, 큰 종 버튼(스페이스 바), 뒤집기(Enter), SVG 과일 카드, 땡/삐 효과음·진동,
카드 이동 애니메이션, 어린이 모드 합계 막대, 다크 모드·동작 줄이기 대응
- 공용 변경(하위 호환): GameDefinition.timeoutNotBefore 선택 훅 + Room 타이머 반영(자리 비움 시
바쁜 반복 방지), feedback.ts에 ding/buzz 소리 추가
- 등록: GAMES, CATALOG, 웹 레지스트리·아이콘, 출시 예정 목록에서 제거, E2E 계획 추가
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 규칙(packages/games/yut): 29칸 윷판 그래프(모서리·방은 멈췄다 출발할 때만 꺾음, 방에서는 항상 참먹이 쪽),
가락 단위 확률(realistic 0.6 / fair 0.5, 빽도 표시 가락, 낙), 윷·모·잡기 추가 던지기, 모아 둔 결과 자유 순서,
쓸 수 없는 빽도 자동 버림, 빽도는 왔던 길(trail)로, 도 자리 빽도(참먹이/바로 남), pass/reach 날 판정,
업기·잡기(지나가면 안 잡음), 개인전 2~4명(1등 종료/꼴찌까지), 팀전 4·6·8명(청·홍 번갈아, 팀원 순환),
기권(팀은 전원 기권 시 패배), 시간 초과 자동 행동(잡기 > 내기 > 업기 > 뒤처진 말 > 올리기), 3연속 초과 시 자리 비움(5초)
- 테스트: 문서 10절 시나리오 + 확률 10만 회(±0.5%p), 무작위 1,000판(불변식·onTimeout 합법·결정성·리플레이),
자동 진행·무작위 기권 60판, apply p99 < 5ms. 서버 방 테스트 2개(팀전 인원 검사, 연결 끊김 자동 진행·재접속 View)
- 화면(apps/web/games/yut): SVG 윷판·말(편마다 색+모양), 윷가락 던지기 애니메이션, 결과 칩 → 말 → 한 번 더 눌러 확정,
경로 미리보기와 잡기!/날!/업기 배지, 자동 이동, 칸마다 통통 이동 애니메이션, 진행 기록, 옵션·규칙 설명, 키보드 조작
- 엔진/서버(하위 호환): GameDefinition.playerCountError(옵션별 인원 규칙) 추가, 방 시작 시 검사.
방 인원이 게임 최대였으면 옵션 변경으로 범위가 바뀔 때 새 최대를 따라감(팀전 8자리)
- 등록: GAMES, 카탈로그(쉬움·15~25분), 화면 레지스트리, 홈의 "준비 중" 목록에서 윷놀이 제거
- E2E: PC 방장 + 휴대폰 친구, 말 2개로 실제 화면 조작(키보드 2단계 확정)으로 끝까지, 다크 모드 화면 저장
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 섯다(packages/games/seotda): 2장·3장 섯다, 1장씩/한 번에 나눠 주기, 족보(광땡·땡·알리…망통),
땡잡이·암행어사·구사/멍텅구리구사 재경기, 동점 재경기·나눔, 리바이·탈락, 사이드 팟. 규칙 테스트 54개
- 포커(packages/games/poker): 홀덤·오마하·7포커(초이스·보스)·7포커 하이로우(동시 선언)·바둑이(아침·점심·저녁)·
5카드 드로우·인디언 포커(이마 카드, 동점 이월, 다이 벌칙). 한국식/노리밋/팟리밋, 블라인드·앤티,
리바이·레벨 상승·최후 1인. 규칙 테스트 52개 + 족보 판정 24개, 무작위 1,000판(칩 보존·비공개 카드 유출 없음)
- 웹: 섯다·포커 화면(테이블 좌석, 공용 카드, 사이드 팟, 한국식 버튼/레이즈 슬라이더, 초이스·교환·선언,
체크 가능할 때 포기 확인, 리바이 안내), 섯다 결과 화면에서 가져간 칩 표시
- 엔진 betting.buildPots: 라운드 진행 중에는 아직 콜할 수 있는 플레이어도 각 팟 자격자로 표시
- 서버 테스트: 크래시 흉내 후 소켓 종료로 다시 걸린 타이머가 닫힌 DB를 건드리던 누수 수정
- E2E: 3인(PC + 휴대폰 2) 섯다·7포커 한 판, 6개 게임 모두 통과
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 2,000 연결 / 500 방 / 초당 248 행동: p95 20ms, p99 37ms, CPU 0.2코어, 메모리 141MB, 오류 0
- 부하 중 SIGKILL→재시작: 2,000 연결 자동 복구, 수 유실 0
- 복구된 방 마감을 30초 + 0~30초 무작위로 분산(몰림으로 p99 336ms → 40ms)
- 보고서: docs/reports/load-20261004.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- scripts/loadtest.ts: 방 N개 × (선수 2 + 관전자) 연결, 방마다 2초에 한 수, 상대 수신까지 지연 p50/p95/p99,
서버 CPU·메모리, --chaos 시 서버 SIGKILL → 재시작 → 재연결·수 유실 검사
- LOADTEST_NO_HTTP_LIMITS=1(https 주소에서는 무시)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 공통 상단 메뉴(사이트 이름·홈·게임 목록·관리자·어디서나 코드 입력·내 정보)
- 홈: 방 만들기 + 코드 입력 카드, 게임 격자, 지금 열린 공개 방 목록(/api/public-rooms)
- 대기실: 두 칸(초대·설정 바로 수정·규칙 요약 / 자리·시작 버튼·채팅 항상 보임)
- 게임 화면: 판(화면 높이에 맞춤, 좌표 표시) + 오른쪽 패널(상태·선수·시계·버튼·기보·채팅)
- 오목: 마우스 올리면 미리 보기 돌, PC는 한 번 클릭으로 착수(두 번 눌러 확정은 터치 기기 기본값,
기기별 설정), GameUI에 Side 패널 추가
- 채팅: PC는 패널로 항상 표시(Enter로 바로 입력), 휴대폰은 시트
- 관리자: 왼쪽 사이드바, 사용자 표, 규칙 입력 두 칸 격자, 저장 바 고정
- 좁은 화면은 같은 화면을 한 칸으로 접어서 지원(방 상단 줄 줄바꿈 수정)
- E2E: PC 1440×900 기준(방장 PC, 친구 휴대폰), 관리자 E2E도 PC
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 권한: 디스코드 ID로 요청마다 계산. 슈퍼어드민 293719842274541579(SUPERADMIN_DISCORD_IDS),
어드민은 슈퍼어드민이 디스코드 ID로 추가(로그인 전 미리 등록 가능), 고정 슈퍼어드민은 삭제 불가
- 게임 설정: 사용 여부, 표시 이름·설명·안내문, 원작 범위 안 인원, 모든 규칙 옵션 기본값,
옵션별 방장 변경 금지(잠금), 초기화. 입력 화면은 옵션 스키마(zod→JSON Schema)로 자동 생성
- 오목 옵션 전체에 한국어 제목·선택지 메타, 엔진 고정값(자동 착수 허용 횟수, 무승부 재제안 간격,
한 수 제한 초)을 옵션으로 꺼냄
- 사이트 설정: 이름, 공지, 점검 모드, 금지어, 방 수 제한, 연결 유예, 채팅 기본값
- 방 관리(목록·닫기), 사용자 관리(검색·닉네임 변경·이용 제한·강제 로그아웃·삭제, 슈퍼어드민 전용),
관리자 작업 기록(전/후 값)
- 이용 제한: 세션 삭제 + 접속 종료 + 디스코드 재로그인 거부
- 테스트: 관리자 API 7개(권한·설정 반영·잠금·점검·금지어·방 닫기·이용 제한·기록), 오목 옵션 2개,
e2e/admin.e2e.ts(슈퍼어드민 로그인→규칙 변경·잠금→어드민 추가→게스트 새 방 반영)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 웹(React+Vite): 홈(큰 버튼 2개·하던 게임 돌아가기), 6자리 코드 입력(붙여넣기 감지·자동 입장),
링크 입장(닉네임 한 칸), 대기실(코드/링크 복사·공유·QR·자리·준비·방장 메뉴·설정),
오목(SVG 판·두 번 눌러 확정·금수/위험 표시·시계·무르기·무승부·기권·키보드 조작·스크린리더 안내),
결과(한 판 더 투표·방 전적·공정성 확인), 채팅·반응, 계정(닉네임 변경·글자 크기·테마·소리·진동)
- WS 클라이언트: 지수 백오프+지터 재연결, 화면 복귀/온라인 즉시 재연결, seq 순서 처리,
ping/pong 지연·시계 보정, 서버 재시작 안내, 다른 창 접속 처리
- @bg/shared/lite: 브라우저용 진입점(zod 제외) → 첫 화면 JS 약 90KB gzip
- e2e/omok.e2e.ts: 브라우저 두 개(모바일·PC)로 방 만들기→링크 입장→대국→새로고침 복구→승리→한 판 더
- deploy: Dockerfile(운영 의존성만, 267MB), docker-compose(app+Caddy), Caddyfile(보안 헤더·CSP), .env.example
- 프록시 뒤에서만 X-Forwarded-For 신뢰(TRUST_PROXY=1)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 실제 서버 + WS 클라이언트로 테스트 문서 3절 시나리오 검증(방 만들기·링크 입장·재접속·
서버 강제 종료 후 복구·차례 위반·중복 cs·탭 교체·방장 이전·도배 제한·잘못된 메시지·
Origin 검사·디스코드 콜백 state 검증·게스트 합치기)
- 시계를 조작하는 방 단위 테스트: 시간 초과 자동 착수, 연결 끊김 유예, 재시작 후 마감 30초 유예,
게임 오류 격리(3회 → 일시 정지), 한 판 더 흑백 교대, 게임 중 나가기
- Bun server.stop()이 서버 쪽 WS 종료 뒤 끝나지 않는 문제: 대기 시간 1초로 제한
- 게임 중 나간 사람의 자리가 게임 종료 후 비워지지 않던 버그 수정
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>