키트로 모바일 웹 게임 만들기
web-game 템플릿은 Vite + React + TypeScript로 작성된 완성된 게임(Coin Dash)입니다. 당신의 임무는 게임의 규칙, 뷰, 텍스트 및 아트를 사용자의 게임으로 교체하는 것입니다. 모바일 우선: 390 x 844의 세로 화면, 한 손가락 조작. 데스크톱도 작동해야 합니다.
고정 규칙
- 코드를 작성하기 전에 반드시 먼저 라이브 미리보기를 시작하세요 (빌드 순서 1단계). 그런 다음 코드를 작성합니다: 최대 10줄로 계획을 세우고, 편집합니다. 한 번에 하나의 파일 또는 하나의 기능을 수정한 후
bun run typecheck를 실행합니다. - 키트가 이미 제공하는 기능을 절대 다시 만들지 마세요 (아래 목록 참조). 게임 엔진, UI 라이브러리 또는 @react-three/fiber를 추가하지 마세요.
- 게임 규칙은
src/games/<game>/logic.ts의 순수 함수입니다: React, DOM, 드로잉,Date.now()또는Math.random()을 사용하지 마세요.seeded(seed)를 사용하세요. 동일한 시드는 항상 동일한 게임을 생성해야 합니다: 일일 및 챌린지 라운드는 이에 의존합니다. - 서버나 로그인이 필요하지 않습니다. 진행 상태는
localStorage에 저장됩니다 (키트가 처리합니다). - 텍스트의 모든 주장은 게임이 실제로 수행하는 것과 일치해야 합니다.
- 검증(Verified)이란 실제로 작동하는 것을 확인했음을 의미합니다:
bun run check:play를 통과했고, 폰 크기의 스크린샷을 확인했습니다. 라이브 링크의 HTTP 200 응답은 테스트가 아닙니다.check:play는 헤드리스로 실행되며 데스크톱이나 브라우저 창이 필요하지 않습니다.
키트가 이미 제공하는 기능 (다시 만들지 마세요)
- 고정 스텝 루프, 키보드 및 터치 입력 (화면 아무 곳이나 드래그, 스틱, D패드, 스티어, 액션 버튼, 멀티터치, 두 플레이어, 컴퓨터에서 마우스 드래그), 카메라, 충돌, 탭 숨김 시 일시정지.
src/ui/에 2D 및 3D용 단일 게임 UI: 메뉴, HUD 스트립 (점수 배지, 하트, 타이머, 일시정지), 일시정지, 결과, 잠금 해제, 플레이 방법 및 FAQ, '휴대폰을 돌리세요' 메시지, 토스트, 라우터, 저장된 프로필.src/ui/theme.ts의 테마:softCandy(기본값),glassNeon,cleanMinimal.?theme=glassNeon으로 다른 테마 미리보기.- 최고 점수 및 잠금 해제; 일일 챌린지 (날짜 시드, 출시일부터의 일수, 연속 기록); 챌린지 링크
?c=<seed>&s=<score>&n=<name>(파라미터 정리 및 "이겼습니다 / 졌습니다" 메시지 및 "다시 보내기" 기능 포함);navigator.share또는 클립보드 복사로 공유; 첫 번째 터치 후 Web Audio 사운드 (음소거 설정 유지); 자동으로 실패하는 진동. track(name, data)(이벤트:game_open,game_start,game_over,play_engaged(45초),share,challenge_open,daily_complete). 콘솔에 로그를 남기고, 게시된 페이지에서는 omg analytics로 전송합니다.play.tsx의useRun이 이미 전송하므로 다시 전송하지 마세요.- 100dvh, 안전 영역, 스크롤 또는 확대 금지, 48px 터치 대상,
prefers-reduced-motion지원. src/app/about.ts기반 SEO: 제목, 설명, Open Graph, 공유 이미지, VideoGame 및 FAQPage 스키마. 설치 매니페스트는public/icons/와 함께 omg Vite 플러그인에서 제공합니다.
2D 또는 3D 선택
기본값은 2D입니다 (스크립트 약 100KB gzip). 3D는 게임 아이디어에 깊이가 필요할 때만 사용합니다. three.js (약 137KB gzip)를 추가하며, 메뉴가 표시되는 동안 로드되고 2D 빌드에서는 절대 로드되지 않습니다. src/app/view.ts에서 한 줄만 변경하여 전환한 후, 사용하지 않는 뷰 파일을 삭제하세요.
컨트롤 선택
src/app/about.ts에서 GAME.controls를 한 번만 설정하세요: kind, touchHint (휴대폰 메뉴) 및 keysHint (컴퓨터 메뉴). play.tsx는 GAME.controls.kind를 <TouchControls>에 전달합니다. 두 힌트와 howToPlay는 동일한 컨트롤을 설명해야 합니다. 버튼이 있는 게임에 "드래그"라고 쓰거나, 드래그 게임에 "화살표를 탭하세요"라고 쓰지 마세요. check:ui 및 check:play는 다른 컨트롤을 언급하는 힌트를 실패 처리합니다.
| 게임 | kind | 플레이어 동작 | 규칙이 읽는 값 |
|---|---|---|---|
| 패들, 잡기, 러너, 레인 회피, 새총 | drag | 필드 아무 곳이나 드래그 | axisX/axisY; mode="absolute"일 때 dragTarget으로 패들이 손가락 아래에 위치 |
| 탑뷰, 자유 이동, 트윈스틱 | stick | 왼쪽 아래 조이스틱 조작 | axisX/axisY |
| 그리드 이동: 미로, 뱀, 소코반 | dpad | 네 방향 화살표 탭 | axisX/axisY 또는 wasTapped |
| 레이싱, 두 키로 레인 전환 | steer | 왼쪽 또는 오른쪽 길게 누름 | axisX |
| 한 번 탭: 플래피, 점프, 타이밍 | buttons | 액션 버튼 탭 | wasTapped(input, "p1", "a") |
어떤 종류에도 buttons={[...]}로 액션 버튼을 추가할 수 있습니다. axes="x"는 드래그를 좌우로 제한합니다. 키보드는 항상 작동합니다: 화살표 또는 WASD, 스페이스바.
빌드 순서
- 파일을 편집하기 전에 먼저 미리보기: 프로젝트 디렉토리에서
node_modules가 없으면bun install을 실행합니다. 백그라운드에서bun run dev를 시작합니다 (포트 5174).expoGo없이omg_expose_port를 호출하고 포트 5174를 지정합니다. 사용자에게 알립니다: "미리보기가 아래 카드에 준비되었습니다. 제가 빌드하는 동안 업데이트됩니다." Vite는 이후 모든 저장 시 미리보기를 리로드합니다. 첫 실행 단계에서 이미 이 작업을 수행했거나, 포트 5174가 이 프로젝트의 개발 서버에 의해 이미 사용 중이라면 2단계로 진행합니다. - 계획: 한 줄로 핵심 루프, 컨트롤 종류 (위 표 참조), 승리, 패배, 점수, 라운드 종료 방식 (시간 제한, 목숨, 떨어지는 아이템 등)을 설명합니다.
README.md에 기록합니다. - 규칙 (로직):
coin-dash/logic.ts를src/games/<game>/logic.ts로 복사합니다.createGame(players, seed),stepGame(game, input, dt),finalScore,events(사운드용),UNLOCKS,shareLine을 유지합니다. 입력은axisX/axisY/wasTapped로 읽습니다. - 뷰:
view-2d.ts(Canvas:drawWorld,drawShadow,loadImage) 또는view-3d.ts(three.js:createStage,chaseCamera,billboard,checkerTexture; 공유 지오메트리, Lambert 재질, 블롭 그림자, 섀도우 맵 없음)를 복사합니다. 아트 슬롯 이미지가 설정된 경우 그리지만, 그렇지 않으면 자리 표시자 도형을 그립니다. - 연결 (와이어링):
src/app/play.tsx에서 임포트, HUD 숫자,FEEDBACK(이벤트별 사운드), 버튼 및run.finish({...})라인을 변경합니다.<TouchControls kind={GAME.controls.kind}>,<HudScore icon={ART.scoreIcon}>,run.step및run.finish는 유지합니다. - 단어 (텍스트):
src/app/about.ts를 채웁니다 (이름, 검색어가 포함된 제목, 설명, 태그라인, 컨트롤, 출시일, 화면 방향, 35단계의 플레이 방법, 팁, 46개의 FAQ). - 아트 (필수): 키트에 포함된 Coin Dash 샘플 아트는 사용자의 게임에 절대 도달해서는 안 됩니다.
theme.ts에서 프리셋을 선택하거나, 하나를 확장하여 사용자 색상을 설정합니다.omg_generate_image를 사용하여 하나의 스타일로 이미지를 만들고 (스프라이트 시트, 투명 PNG로 자름, 게임 용량 3MB 미만), 다음 모든 항목을 교체합니다:src/app/art.ts의ART.hero(로고 아래 메뉴 아트) 및ART.scoreIcon(HUD 점수 아이콘).public/art/hero.svg및public/art/score.svg를 삭제합니다.ART.items(잠금 해제당 하나) 및ART.sprites.public/icons/(pwa-192x192.png,pwa-512x512.png,pwa-512x512-maskable.png,apple-touch-icon.png(180px)) 및public/og.png(1200 x 630). 그런 다음 메뉴, 플레이, 결과 스크린샷을 확인합니다: 게임이 코인에 관한 것이 아니라면 빨간 러너, 코인, 코인 배지가 없어야 합니다.
- 확인 (체크):
bun run typecheck,bun test,bun run check:ui,bun run check:play를 순서대로 실행합니다.check:play는 390 x 844에서 터치로 한 라운드를 플레이하며 메뉴, 플레이, 컨트롤, 일시정지, 재개, 결과, 콘솔 오류, 샘플 아트를 확인합니다..omg/ui-check/및.omg/play-check/의 모든 PNG를 엽니다. 각 FAIL 및 WARN을 수정하고 다시 실행합니다.check:play가 통과할 때까지 게시하지 마세요. - 배포 (퍼블리시):
omg_deploy를 실행합니다. 첫 번째 게시에는public/omg-store/1.png~3.png가 필요합니다 (390 x 844의 메뉴, 플레이, 결과 화면). 1분간 기다린 후bun run check:play -- --url <라이브 링크>를 실행하고 스크린샷을 확인합니다. 통과한 항목만 보고합니다.
src/ui/, src/game/, src/render/는 키트 버그로 인해 막힐 때만 편집하세요. 도우미는 게임 폴더에 추가하세요.
모바일 규칙
- 뷰포트 태그,
styles.css,page.ts를 유지하세요. HUD 항목은<Hud>안에 넣으세요. 중요한 컨트롤은 아래쪽 절반에 유지하세요. - 게임 시간에
setInterval,setTimeout또는Date.now()를 사용하지 마세요:dt를 누적하세요. alert,confirm,prompt, 외부 폰트 또는 스크립트를 사용하지 마세요.- 3D: 최대 수백 개의 메시, 지오메트리 및 재질 재사용, 후처리 금지, 큰 텍스처 금지.
- 휴대폰에서 omg 설치 바는 게임 아래에 위치하며, 게임은 그 위에 카드 형태로 표시됩니다. 숨기거나 이동하지 마세요.
최종 보고서
- 라이브 링크. 2. 게임을 한 문장으로 설명. 3. 테스트된 항목과 크기, 라이브 링크에서의
check:play결과. 4. 메뉴, 플레이, 결과 스크린샷. 5. 알려진 문제 또는 다음 아이디어 (최대 5개). 3D가 실제 휴대폰에서 확인되었는지 여부를 명시하세요.
이미 배운 교훈
- 옆으로 스크롤되는 행 끝에 있는 버튼이 화면 밖으로 나가 플레이어가 막혔습니다.
check:ui는 이러한 버튼을 실패 처리합니다; 360px 너비에서 주요 버튼이 화면에 보이도록 유지하세요. - 배포 직후 라이브 사이트가 여전히 이전 빌드를 제공하는 동안 "검증됨"을 주장했습니다. 잠시 기다린 후 다시 확인하세요.
- 게임 복사본이 소스와 달라졌습니다. 하나의 폴더에서 빌드하고, 복사본을 패치하지 마세요.
- Fruit Catcher (10월 22일) 게임은 화살표 버튼 위에 "바구니를 움직이려면 왼쪽 또는 오른쪽으로 드래그하세요"라고 표시했지만 드래그가 작동하지 않았습니다.
GAME.controls를 설정하고check:play가 구동하도록 하세요. - 같은 게임이 키트의 빨간 러너, 코인, 코인 점수 배지 및 코인 앱 아이콘과 함께 배포되었습니다. 7단계에서 모두 교체합니다;
check:play는 샘플 파일이 남아 있으면 실패합니다. - 포트가 노출되지 않아 사용자가 5분 동안 미리보기를 볼 수 없었습니다. 1단계는 모든 편집 전에 수행해야 합니다.
- 에이전트가 "데스크톱 브라우저가 실행 중이 아니었습니다"라고 말하고 HTTP로만 라이브 링크를 확인했습니다.
check:play는 헤드리스입니다; 라이브 링크에서 실행하세요. - 새로운 커스텀 이벤트 (
play_engaged)에 최적화된 광고가 드롭되었습니다. 표준 목표로 광고를 시작하고, 이벤트가 주당 약 50회 발생하면 전환하세요.