Communitygithub.com

BennyKok/omg.dev

omg.devのExpoプロジェクトでリアルタイムゲーム(レース、アーケード、トップダウン、プラットフォーマー、パズル、子供向け学習、ワード、シンプル3D)を構築します。ゲームキットから始め、エンジンは設計しません。

omg.dev とは?

このスキルは、`expo-game`テンプレートを基にしたomg.devプロジェクトで、リアルタイムゲームを迅速に開発するためのものです。テンプレートには固定タイムステップループ、キーボード/タッチ入力、カメラ、衝突判定、HUD、メニュー、一時停止、結果表示、アンロック、セーブ機能など、ゲームエンジンに必要なコンポーネントがすべて含まれています。開発者はサンプルゲーム(Coin Dash)の内容を、ユーザーが望むゲームに置き換えるだけでよく、エンジンを一から設計する必要はありません。各ターンで1つのファイルまたは機能に集中し、`bun run typecheck`でエラーを確認しながら段階的に編集を進めます。3Dゲームが必要な場合は、Three.jsとreact-three-fiberを使用した2つのファイル(Web用とネイティブ用)を作成し、キャンバス上に3Dオブジェクトをレンダリングします。最後に`bun run typecheck`、`bun run build`、そして`bun run check:ui`で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. 各ターンは小さく保ちます:1つのファイルまたは1つの機能、その後 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 }):updateは固定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が右に分割されます。分割画面では、2つの GameView をレンダリングし、それぞれに1つのカメラを設定します(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。

Webの落とし穴

  • ゲーム領域は useViewSize()(onLayout)で計測します。useWindowDimensions() は静的Webエクスポートではリサイズまで0になります。
  • ボタン付きの Alert.alert はWebでは何もしません。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

同じエクスポートを持つ2つの小さなファイルを記述して、Metroが正しい方を選択するようにします:

  • src/components/scene.web.tsx:import { Canvas, useFrame } from "@react-three/fiber"
  • src/components/scene.tsx:from "@react-three/fiber/native" を使用した同じコード

ゲームオブジェクトごとに1つの <mesh>(ボックス、球体、平面、フラットカラー)を持つ <Canvas camera={{ position: [0, 0, 4] }}> を ambientLight、directionalLight とともに配置します。各レンダリングでゲームオブジェクトから位置をコピーします。stepGame は useGameLoop で実行し、useFrame では実行しません。HUDとコントロールは、キャンバスの上にある通常のReact Nativeビューとして維持します。キャンバスにはサイズを持つ親(flex: 1)が必要です。

キットのスパイクで確認済み:3DシーンはExpo WebとAndroid JSバンドルでレンダリングされます。デバイス上またはExpo Goでのレンダリングは未確認です。最終メッセージでその旨を伝えてください。

仕上げ

bun run typecheck と bun run build を実行します。ユーザーから依頼がない限り、自動テストは記述しないでください。次に bun run check:ui を実行します:すべてのルートを390x844で開き、ルートごとに1つのPNGを .omg/ui-check/ に保存し、空白ページ、エラーバウンダリ、コンソールエラー、失敗したリクエスト、および別の要素で覆われたボタンを報告します。各PNGを開き、リクエストとデザインリファレンスと比較し、問題を修正して、レポートがクリーンになるまで再度実行します。このチェックはゲームをプレイしないため、Expo Webでも確認してください:キーで動き、終了し、結果画面を表示し、リロード後もベストスコアが保持される必要があります。テストした画面を伝えてください。Web実行はネイティブ動作の証拠にはなりません。公開後、ライブURLを電話サイズで開いてください。omgインストールバーはゲームの下に配置され、ゲームはその上のカードになるため、バーがゲームコントロールを覆うことはありません。移動したり非表示にしたりしないでください。

Individual skills in this repo

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

関連スキル