Files
tetrig/README.md
tkrmagid cbb8dea2eb Switch to Flutter (Android + iOS) for iPhone support; port engine to Dart
아이폰 지원 요구로 Android 전용 Kotlin 스택을 크로스플랫폼 Flutter로 교체.
- app/: Flutter 프로젝트(android+ios). 코어 로직은 순수 Dart 모듈 app/lib/engine.dart
  로 이식(SRS+180 킥·7-bag·홀드·고스트·락딜레이·T-spin/mini·콤보/B2B). 웹/Kotlin 판과 동일 알고리즘.
- app/test/engine_test.dart: Dart 테스트 24개 전부 통과, flutter analyze 0 issue.
- 이전 android/(Kotlin) 모듈 제거(Flutter로 대체). README에 Flutter 전환 + iOS 빌드 제약(맥 필요) 명시.
- 게임 UI(목업 ② + §11 터치)와 설치용 빌드는 다음 단계.
2026-08-22 14:40:03 +09:00

8.1 KiB
Raw Blame History

TETRIG (테트리그)

쌓아라, 부숴라, 올라가라.

TETR.IO 스타일의 모바일 실시간 대전 블록 스태커 웹 게임. 솔로 3모드 + 인원 무제한 커스텀 룸(FFA) + Glicko-2 랭크 리그전을 하나의 단일 HTML 클라이언트와 Cloudflare Workers 서버로 구현한다.

이 문서는 앱 제작을 위한 최종 빌드 진입점(entry point) 이다. 모든 설계 결정·수치·에셋의 정본(source of truth)은 TETRIG-최종명세서.md 이며, 구현 시 반드시 명세서와 UX 목업을 함께 열어 작업한다.

클라이언트 변경 (2026-08-22 사용자 결정): 플레이스토어 + 앱스토어(아이폰) 동시 출시를 위해 클라이언트를 크로스플랫폼 Flutter (Dart, Android + iOS) 로 제작한다. 소스는 app/. 코어 게임 로직은 UI와 분리된 순수 Dart 모듈 app/lib/engine.dart 에 있고 flutter test 로 검증한다(SRS 킥테이블·7-bag·T-spin 판정·점수·좌표 등 §4·§13 데이터는 그대로 이식됨). 서버 계획(Cloudflare Workers + D1 + WebSocket)은 변경 없이 유지된다. 초기 웹(HTML) 프로토타입(src/, index.html)은 검증된 동작 레퍼런스로 남겨둔다.

iOS 빌드 제약: Android(APK/AAB)는 리눅스에서 빌드 가능하나, iOS(.ipa)·앱스토어 제출은 macOS + Xcode 가 필수다. 맥 한 대 또는 클라우드 맥 CI(Codemagic 등) + Apple Developer Program($99/년) 이 필요하다. 이 저장소는 iOS 코드베이스와 CI 설정까지 포함하되 실제 iOS 바이너리는 맥 환경에서 빌드한다.


무엇을 만드는가

산출물은 딱 2개다.

  1. 클라이언트 — 단일 HTML 파일 (HTML + CSS + JS, Canvas 2D). 외부 에셋 0개, 사운드는 100% Web Audio 신스 생성.
  2. 서버 — Cloudflare Workers 프로젝트 (wrangler 표준 구조: Durable Objects 2종 + D1 + Cron).

게임 구성:

  • 솔로 3모드: SPRINT(40줄 최속) · TIME ATTACK(2분 점수) · ENDLESS(무한)
  • 커스텀 룸: 6자리 초대 코드, 인원 무제한 FFA, 호스트 규칙 설정
  • 리그전: Glicko-2 레이팅 + 18단계 랭크 + 배치 10경기 + 시즌제

아키텍처

[모바일 브라우저]                      [Cloudflare]
클라이언트 (단일 HTML, Canvas)  ⇄ WSS ⇄  Workers
 ├ 게임 엔진 (SRS+, 판정, 렌더)          ├ MatchmakerDO (리그 매칭 큐, 싱글턴)
 ├ 솔로 모드 3종                        ├ GameRoomDO (경기방 — 리그 & 커스텀 공용)
 └ 멀티/커스텀/프로필/리더보드 UI        ├ D1 (계정·레이팅·전적·리더보드)
                                        └ Cron (RD 감쇠, 시즌 처리)
  • 클라이언트: Cloudflare Pages(또는 Workers 정적 자산)로 호스팅, 시작 주소는 tetrig.pages.dev.
  • 서버: 무료 티어로 운영 가능 (DO SQLite 백엔드 + WebSocket Hibernation).
  • 로컬 개발: wrangler dev + 브라우저 탭 여러 개로 다인전 테스트.

저장소 파일

파일 용도
TETRIG-최종명세서.md 정본 명세서 — 모든 규칙·수치·좌표·스키마·프로토콜
tetrig-ux-mockup.png 9화면 UX 목업 (1390×2944) — UI 구현의 시각 기준
tetrig-logo.svg / tetrig-logo.png 가로형 워드마크 로고 (실사용 에셋 / 렌더 미리보기)
tetrig-icon.svg / tetrig-icon.png 앱 아이콘 512×512 (실사용 에셋 / 렌더 미리보기)

명세서의 화면 번호 ①⑨는 목업 시트의 화면과 1:1 대응한다. 시각 판단은 목업 이미지를 따르고, 명세서 §11§13의 좌표·팔레트 수치로 정확도를 보정한다.

핵심 규칙 요약 (상세는 명세서 §4~§8)

  • 보드: 10열 × 40행(내부), 하단 20행 표시. 랜덤 7-bag, 넥스트 5, 홀드 1회/피스, 고스트 피스.
  • 회전: SRS + 180° 킥테이블 (명세서 §4.1). 락 딜레이 500ms / 최대 15회 리셋.
  • 판정: T-spin / T-spin mini, B2B, 콤보, All Clear. 4줄 클리어는 "QUAD" (Tetris/테트리스 단어 금지).
  • 대전: 가비지 전송 테이블 + 상쇄(counter) + 8줄/회 상한 + 장기전 방지 배율.
  • 리그: Glicko-2 (R=1500, RD=350, σ=0.06, τ=0.5) → 표시용 TR(0~25,000) → 18단계 랭크. 배치 10경기, RD<100일 때만 랭크 표시.
  • 매치메이킹: MatchmakerDO 싱글턴 큐, R ± 2×RD 구간이 겹치면 성사. 형식은 높은 랭크 기준 A+ 이하 FT3 / S- 이상 FT5.

디자인 시스템 (NEOBRUTAL — 상세는 명세서 §13)

  • 테마 이원화: 메뉴/로비/결과는 BONE(#EDE7DA) 라이트, 인게임은 INK(#17161B) 다크.
  • 컴포넌트: 2px 잉크 보더 + 블러 0 하드 오프셋 섀도 + 우하단 챔퍼컷 + 고대비 플랫 컬러.
  • 시그니처: 45° 해저드 스트라이프(가비지·공격·광고·난투에만 절제 사용).
  • 금지: 다크 네이비 배경 · 네온 글로우 · 그라디언트 · 블러 섀도 · 과도한 라운딩.
  • 피스 7색(v2 확정): I #3EC1B6 / O #F5C531 / T #A76BF2 / S #7FCC4C / Z #F25C4C / J #4C7DF2 / L #F2913D / 가비지 #46464F.

개발 로드맵 (이 순서로 진행)

각 Phase 완료 시 실행 가능한 파일 + 코어 로직 단위 테스트 통과를 완료 기준으로 삼고, 사용자 확인 후 다음으로 넘어간다.

단계 내용 완료 기준
Phase 1 코어 엔진: 보드·피스·SRS+180 킥·7-bag·홀드·고스트·락딜레이·클리어 키보드 플레이 + 킥/판정 단위 테스트 통과
Phase 2 판정·점수 + 솔로 3모드 + 솔로 결과 화면 3모드 정상 플레이·기록 저장
Phase 3 가상 버튼 + 스와이프 + 핸들링 설정 + 메뉴 화면들 모바일 브라우저 실기 조작 확인
Phase 4 서버 뼈대: 게스트/계정·기록 이전·GameRoomDO·WS·가비지 원장 + 커스텀 1:1 탭 2개로 코드 방 1:1 대전 성사
Phase 5 커스텀 FFA: 다인 타겟팅·미니뷰 그리드·KO 관전·도중 입장·리매치 투표 탭 4개+ FFA 라운드 정상 진행
Phase 6 MatchmakerDO + Glicko-2 + TR/랭크 + 리더보드·프로필·전적 + 리그 결과 매칭→경기→TR 반영 전체 사이클
Phase 7 연출·사운드·시즌·광고 슬롯 연결·재접속/부하 점검·폴리시 v1 배포 (wrangler deploy + Pages)

개발 환경

# 서버 (Cloudflare Workers)
npm create cloudflare@latest      # wrangler 프로젝트 초기화
wrangler dev                      # 로컬 개발 서버 + WS
wrangler deploy                   # 배포

# 클라이언트
# 단일 HTML 파일 — 브라우저로 직접 열거나 Pages/Workers 정적 자산으로 서빙

준비물(필요 시점에 사용자에게 확인 — 명세서 §17):

  • Google OAuth 클라이언트 ID (Phase 4)
  • 애드센스 계정 ID (Phase 7)

구현 가드레일 (반드시 지킬 것)

  • IP 금지: 사용자 노출 텍스트에 "Tetris/테트리스" 금지, 테트리스 음악(Korobeiniki 등) 금지, 표준 가이드라인 색상 1:1 복제 금지, TETR.IO 에셋·명칭 복제 금지.
  • BRAND 상수화: 앱 이름·로고 문구는 코드 1곳(const BRAND = "TETRIG" / BRAND_KO = "테트리그")에서 관리해 1분 내 리브랜딩 가능하게.
  • 튜닝 수치 상수화: 중력·TR 커브·콤보 테이블 등 조정 대상은 코드 상단 상수로 분리.
  • 언어: 사용자 노출 텍스트는 한국어 (게임 용어 SPRINT/HOLD 등 영문 허용).
  • 테스트 필수: 킥테이블·T-spin 판정은 반드시 jsdom/node 단위 테스트로 검증.
  • 명세 준수: 명세서에 값이 명시된 것은 그대로 구현하고, 없는 것만 질문한다.

라이선스 / 상표

앱 이름 "테트리그(TETRIG)"는 상표 유사성 리스크를 인지한 뒤 스토어 출시·수익화(광고 게시)까지 최종 확정한 이름이다(2026-08-21). 이름 재검토 트리거는 없다. BRAND 상수화는 리브랜딩 대비가 아니라 표기 일관성·유지보수를 위한 단일 소스로서 유지한다 (명세서 §2).