Communitygithub.com

BennyKok/omg.dev

omg.dev Expo 프로젝트에서 실시간 게임(레이싱, 아케이드, 탑다운, 플랫포머, 퍼즐, 어린이 학습, 단어, 간단한 3D)을 만듭니다. expo-game 템플릿을 기반으로 시작하며, 엔진을 설계하지 않고 게임 키트를 활용합니다.

omg.dev란 무엇인가요?

이 스킬은 Expo와 고정 타임스텝 루프, 입력 처리, 충돌 감지, 카메라, HUD, 메뉴, 일시정지, 결과, 잠금 해제, 저장된 진행 상황 등의 기능을 갖춘 `expo-game` 템플릿을 사용하여 실시간 게임을 신속하게 구축하는 데 중점을 둡니다. 엔진을 처음부터 설계할 필요가 없으며, 대신 템플릿에 포함된 Coin Dash 예제의 콘텐츠를 사용자 지정 게임의 로직, 뷰, 테마로 대체합니다. 이 스킬은 순수 게임 규칙을 포함하는 `logic.ts`, 게임 객체를 렌더링하는 `game-view.tsx`, 네비게이션 및 UI를 업데이트하는 기타 화면과 같이 특정 파일을 편집하는 단계별 프로세스를 안내합니다. 또한 키트 API(예: `createLoop`, `Input`, 충돌 헬퍼, `profileStore`)를 사용하는 방법, 웹 특화 문제(예: `useViewSize` 사용)를 처리하는 방법, 필요한 경우 `@react-three/fiber`를 사용하여 3D 게임을 통합하는 방법을 설명합니다. 마지막으로 타입 검사, UI 검사, Expo Web에서의 수동 테스트를 포함한 검증 단계를 강조하여 게임이 예상대로 작동하고 다양한 플랫폼에서 사용자 친화적인 인터페이스를 유지하도록 합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/BennyKok/omg.dev/tree/HEAD/agents/skills/omg-game-builder

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

키트에서 게임 만들기

expo-game 템플릿에는 이미 엔진(고정 타임스텝 루프, 키보드 및 터치 입력, 카메라, 충돌 헬퍼, HUD, 메뉴, 일시정지, 결과, 잠금 해제, 저장된 진행 상황, 작동하는 샘플 게임(Coin Dash))이 포함되어 있습니다. 당신의 임무는 샘플 콘텐츠를 사용자의 게임으로 대체하는 것입니다. 엔진을 설계하거나 작성하지 마십시오.

이 빌드의 규칙

  1. 첫 번째 턴에 코드를 작성하십시오. 길게 계획하지 마십시오. 최대 10줄의 생각으로 게임 규칙을 결정한 다음 파일을 편집하십시오. 문제는 실행 후에 해결하십시오.
  2. 각 턴을 작게 유지하십시오: 하나의 파일 또는 하나의 기능, 그런 다음 bun run typecheck를 실행하십시오. 코드 없이 긴 추론 과정은 실패입니다.
  3. 키트에 이미 있는 것(루프, 입력, 충돌, 카메라, HUD, 화면, 저장소)을 다시 구현하지 마십시오.
  4. 메뉴, 아트 또는 잠금 해제를 추가하기 전에 게임을 실시간으로 플레이 가능하게 만드십시오. 샘플에는 이미 메뉴가 있습니다.

프로젝트

omg_create_project와 template: "expo-game"을 사용하여 프로젝트를 만드십시오. 첫 번째 미리보기를 위해 omg-app-builder 스킬의 Expo 빠른 경로를 따르십시오. 그런 다음 편집하십시오.

편집할 파일(순서대로)

  1. src/game/theme.ts: 디자인의 색상.
  2. src/games/<your-game>/logic.ts: coin-dash/logic.ts를 복사하십시오. 순수 규칙: createGame(), stepGame(game, input, dt), finalScore(), UNLOCKS. React, 그리기, Date.now()는 사용하지 마십시오. axisX/axisY/wasTapped(input, "p1" | "p2", ...)를 통해서만 입력을 읽으십시오. 무작위성에 seeded()를 사용하십시오.
  3. src/games/<your-game>/game-view.tsx: coin-dash/game-view.tsx를 복사하십시오. World와 Sprite(색상 모양, 이모지 label 또는 react-native-svg)를 사용하여 그리십시오. 월드 단위를 사용하십시오. 카메라가 변환합니다.
  4. src/app/play.tsx: coin-dash에서 게임으로 임포트를 변경하십시오. TouchControls에 kind(dpad, stick, steer)와 buttons({ action: "a", label: "JUMP" })를 설정하십시오. 루프, 키보드, 일시정지 및 완료 연결은 그대로 유지하십시오.
  5. src/app/index.tsx, results.tsx, unlocks.tsx: 제목, 텍스트 및 UNLOCKS 임포트. 사용자가 요청하지 않는 한 자동화된 테스트를 작성하지 마십시오. 대신 자체 점검으로 확인하십시오(마무리 참조).

키트 버그가 막지 않는 한 src/game/loop.ts, input.ts, collision.ts, camera.ts, progress.ts를 편집하지 마십시오. 게임 폴더에 헬퍼를 추가하십시오.

키트 API(이 이름들을 사용하십시오)

  • createLoop({ step }) 및 useGameLoop(update, { paused }): 업데이트는 고정 1/60초 단계로 실행됩니다.
  • createInput(), axisX/axisY, wasTapped, endFrame, setAction, setStick. useKeyboard(input, players, onEscape): P1 = WASD + Space/E; 2인 모드에서 P2 = 방향키 + Enter.
  • TouchControls players={1|2} kind="dpad|stick|steer" buttons={[...]}: 2인 모드는 P1 왼쪽, P2 오른쪽으로 분할합니다. 분할 화면의 경우 두 개의 GameView를 렌더링하고 각각 하나의 카메라를 사용하십시오(play.tsx 참조).
  • circlesOverlap, rectsOverlap, circleRectOverlap, pushCircleOutOfRect, keepCircleInside, angleDiff, seeded, clamp, lerp.
  • createCamera, followCamera(cam, target, dt, { velocity, lookAhead, world, viewW, viewH }).
  • profileStore.finishRun({ gameId, score, stats }, UNLOCKS), useProfile(), profileStore.select(group, id), setSettings.
  • 화면: MenuScreen, PauseOverlay, ResultsScreen, UnlocksScreen, SettingsRow, GameButton. HUD: Hud, HudStat, HudBar, Banner.

웹 함정

  • useViewSize()(onLayout)로 게임 영역을 측정하십시오. useWindowDimensions()는 정적 웹 내보내기에서 크기 조정 전까지 0입니다.
  • 버튼이 있는 Alert.alert는 웹에서 아무 효과가 없습니다. PauseOverlay 또는 화면 내 모달을 사용하십시오.
  • 진행 상황을 컴포넌트 상태가 아닌 profileStore에 유지하십시오: 다시 로드해도 최고 점수와 잠금 해제가 유지되어야 합니다.
  • 게임 시간에 setInterval 또는 Date.now()를 사용하지 마십시오. 루프 dt를 계산하십시오.
  • 프레임별 상태를 React useState에 넣지 마십시오. 게임 객체(ref)에 유지하십시오. 훅은 매 프레임 다시 그립니다.

3D 게임

키트는 2D입니다. 3D 게임(스타일 선택이 아닌 실제 필요)의 경우 루프, 입력, HUD 및 화면을 유지하고 game-view.tsx만 대체하십시오.

bunx expo install three @react-three/fiber expo-gl && bun add -d @types/three

동일한 내보내기를 가진 두 개의 작은 파일을 작성하여 Metro가 올바른 파일을 선택하도록 하십시오:

  • src/components/scene.web.tsx: import { Canvas, useFrame } from "@react-three/fiber"
  • src/components/scene.tsx: from "@react-three/fiber/native"를 사용한 동일한 코드

<Canvas camera={{ position: [0, 0, 4] }}>를 ambientLight, directionalLight 및 게임 객체당 하나의 <mesh>(박스, 구, 평면, 단색)와 함께 배치하십시오. 각 렌더링에서 게임 객체의 위치를 복사하십시오. useGameLoop에서 stepGame을 실행하고 useFrame에서는 실행하지 마십시오. HUD 및 컨트롤은 캔버스 위에 일반 React Native 뷰로 유지하십시오. 캔버스에는 크기가 있는 부모(flex: 1)가 필요합니다.

키트 스파이크에서 확인됨: 3D 장면이 Expo Web에서 렌더링되고 Android JS 번들이 컴파일됩니다. 장치 또는 Expo Go에서 렌더링되는 것은 확인되지 않았습니다. 최종 메시지에서 이를 언급하십시오.

마무리

bun run typecheck 및 bun run build를 실행하십시오. 사용자가 요청하지 않는 한 자동화된 테스트를 작성하지 마십시오. 그런 다음 bun run check:ui를 실행하십시오: 390x844에서 모든 경로를 열고 경로당 하나의 PNG를 .omg/ui-check/에 저장하고 빈 페이지, 오류 경계, 콘솔 오류, 실패한 요청 및 다른 요소로 덮인 버튼을 보고합니다. 각 PNG를 열고 요청 및 디자인 참조와 비교하고 잘못된 것을 수정한 다음 보고서가 깨끗해질 때까지 다시 실행하십시오. 검사는 게임을 플레이하지 않으므로 Expo Web에서도 확인하십시오: 키로 움직이고, 종료되고, 결과 화면을 표시하고, 다시 로드 후 최고 점수를 유지해야 합니다. 테스트한 표면을 말하십시오. 웹 실행은 네이티브 동작의 증거가 아닙니다. 게시 후 라이브 URL을 휴대폰 크기로 여십시오. omg 설치 표시줄은 게임 아래에 위치하며, 게임은 그 위에 카드가 되므로 표시줄이 게임 컨트롤을 덮지 않습니다. 이동하거나 숨기지 마십시오.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

관련 스킬