-
Notifications
You must be signed in to change notification settings - Fork 0
프로젝트 기획서
양해울 edited this page May 31, 2026
·
3 revisions
재미있는 프론트엔드 프로젝트를 찾던 중, 인터넷 공개 데이터를 활용한 게임 서비스를 구상.
게임 형식 + 한국 문화 기반 + 공개 데이터 활용 방향으로 기획을 발전시켜, 나무위키의 특수성(한국 문화 감성, 방대한 내부 링크)을 활용한 스피드런 게임으로 확정.
"나무위키 스피드런(나무런)" = 위키피디아의 스피드런(The Wiki Game)의 나무위키 버전
- 시작 문서와 도착 문서가 주어짐
- 플레이어는 나무위키 내부 링크만 클릭하여 이동
- 도착 문서에 도달하면 종료
- 경쟁 요소: 클릭 수, 소요 시간으로 점수 측정 및 랭킹
| 기능 | 설명 |
|---|---|
| 📅 일일 문제 | 매일 고정된 시작·도착 문서 쌍 (daily_prompts 테이블) |
| 🎲 랜덤 스피드런 |
byte_size 상위 문서 중 무작위 2개 선택 |
| 📄 나무마크 렌더링 |
namumark-clone-core로 실제 나무위키 유사 표시 |
| 🏆 결과 & 리더보드 | 클릭 수·경로·소요 시간 기록 및 동일 문제 순위 표시 |
| 영역 | 기술 | 선택 이유 |
|---|---|---|
| 프론트엔드 | React + TypeScript | 컴포넌트 기반 UI 구조, 타입 안정성 |
| 빌드 도구 | Vite | 빠른 HMR, ESM 기반 번들링 |
| 스타일링 | Tailwind CSS v4 | 빠른 프로토타이핑, 유틸리티 우선. v4는 CSS-first 방식으로 별도 config 불필요 |
| 호스팅 | Vercel | 프론트엔드 무료 배포, GitHub 자동 연동 |
| DB (메타데이터) | Supabase (PostgreSQL) | 무료 티어, REST API 내장, 리더보드 저장 |
| 객체 스토리지 | Cloudflare R2 | Egress 무료, CDN 캐싱, 문서 JSON 서빙 |
| 마크업 파서 | namumark-clone-core | TypeScript 구현체, 나무마크 렌더링 |
| 데이터 | 나무위키 덤프 (CC BY-NC-SA 2.0 KR) | heegyu/namuwiki (HuggingFace, 867K 문서, 비상업적 이용 허용) |
- 위키피디아보다 한국 문화·연예인·게임·사건 등에 특화
- 나무위키 특유의 감성과 문체가 재미 요소
- 인기 문서끼리는 6단계 내 연결 가능 (Six Degrees 효과)
위키피디아는 공식 API가 있어 구현이 쉬움.
나무위키는 공식 API 없음 → 덤프 데이터 전처리 및 자체 백엔드 구축 필요.
-
HuggingFace
heegyu/namuwiki(2022년 3월 기준 덤프) - 867,024개 문서 포함,
.parquet포맷 - 라이선스: CC BY-NC-SA 2.0 KR (비상업적 이용 허용, 출처 표기 필수)
.parquet 다운로드 (867,024개 문서, 약 2.8GB)
→ 리다이렉트 문서 분리 (약 295,649개, 전체의 34%) → Supabase redirects 테이블 저장
→ 일반 문서 전체 (~571,375개) 처리
- 내부 링크 추출: [[문서명]] / [[실제명|표시텍스트]] 패턴
- byte_size 계산 (실제 바이트 수)
→ 본문 JSON → Cloudflare R2 병렬 업로드 (boto3, max_workers=50)
→ 메타데이터 → Supabase bulk INSERT (1,000개 배치)
토막글 필터링은 파이프라인에서 하지 않음. 모든 일반 문서를 적재하고, 랜덤 시작/도착점 후보 선택 시
byte_size와 링크 수 조건을 쿼리로 적용. (약 487,984개가 후보)
이유: 토막글도 게임 중 경유지로 이동 가능해야 dead link가 발생하지 않음.
| 데이터 | 저장 위치 | 내용 |
|---|---|---|
| 본문 원문 | Cloudflare R2 | articles/문서명.json |
| 메타데이터 | Supabase articles
|
title, links[], byte_size |
| 리다이렉트 | Supabase redirects
|
title → target 매핑 |
| 일일 문제 | Supabase daily_prompts
|
날짜별 시작·도착 문서 |
| 게임 기록 | Supabase game_records
|
닉네임, 경로, 클릭 수, 시간 |
[메인 화면]
├─ 오늘의 문제 (daily_prompts에서 조회)
└─ 랜덤 스피드런 시작 버튼
↓
[게임 화면]
├─ 상단 헤더: 목표 문서 | 경과 시간 타이머 | 클릭 수 카운터
├─ 문서 표시 영역 (R2 fetch → namumark-clone-core 렌더링)
├─ 링크 클릭 → 유효 내부 링크 검증 → 다음 문서 이동
├─ 외부 링크 클릭: 무시 또는 비활성화
└─ 막힌 경우: "문서 건너뛰기" 버튼
↓ (목표 문서 도달)
[결과 화면]
├─ 소요 시간, 총 클릭 수, 거쳐온 경로 (노드 형태)
├─ 닉네임 입력 후 Supabase game_records에 기록
└─ 다시 하기 / 오늘의 문제 도전
↓
[리더보드]
└─ 동일 문제(시작-도착)의 최단 시간 / 최소 클릭 수 순위
-- 문서 메타데이터
CREATE TABLE articles (
title TEXT PRIMARY KEY,
links TEXT[],
byte_size INTEGER,
created_at TIMESTAMP DEFAULT NOW()
);
-- 게임 기록
CREATE TABLE game_records (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_name TEXT,
start_article TEXT,
end_article TEXT,
click_count INTEGER,
elapsed_seconds INTEGER,
path TEXT[],
created_at TIMESTAMP DEFAULT NOW()
);
-- 리다이렉트 매핑
CREATE TABLE redirects (
title TEXT PRIMARY KEY,
target TEXT
);
-- 일일 문제
CREATE TABLE daily_prompts (
date DATE PRIMARY KEY,
start_article TEXT,
end_article TEXT
);| Phase | 내용 |
|---|---|
| Phase 1 | 데이터 파이프라인 (로컬 1회 실행, R2·Supabase 적재) |
| Phase 2 | 핵심 렌더링 테스트 (R2 fetch, namumark-clone-core 렌더링) |
| Phase 3 | 플레이 사이클 완성 (타이머, 클릭 카운트, 도착 판정, 결과 저장) |
| Phase 4 | 폴리싱 및 배포 (UI/UX 고도화, 에러 처리, Vercel 배포) |
나무위키 덤프는 CC BY-NC-SA 2.0 KR 적용.
- 서비스 Footer 및 README에 출처 명시: "본 서비스는 나무위키 데이터를 기반으로 합니다 (CC BY-NC-SA 2.0 KR)"
- 비상업적 이용 유지 (광고 수익화 금지)
- 동일 라이선스 적용