OhMyGame
OhMyGame은 AI로 게임을 만들 수 있는 오픈소스 스튜디오로, 디자인·구축·플레이테스트·출판을 하나의 앱에서 모델 키와 함께 수행합니다
인원·컨디션·시간·예산 선택하면 오늘 플레이할 스팀 게임 5개를 추천, 전체 목록도 직접 탐색 가능
Pick your group size (solo or with friends), today's mood, how much time you have, and your budget — get 5 Steam game picks for right now. You can also browse and filter the whole list yourself.
게임TypeScript · JavaScriptGitHub @goncharo55온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗友達の人数・今日の気分・使える時間・予算を選ぶだけで、今日みんなで遊べるSteamゲームを5本だけ提案するサイト。 自分で条件を絞って探したい人向けに、チェックボックス式のブラウズ画面も用意している。
/ トップページ/quiz 4問の診断フロー(人数[1人(ソロ)〜6人以上]→気分→時間→予算)→ /result で当日固定のおすすめ5本を表示/browse 自分で人数・気分・時間・予算をチェックボックスで組み合わせて絞り込む一覧(ゲーム名検索・ページネーション付き)/games/[appid] ゲーム個別ページ(SEO・将来の広告枠用)data/games.json に964本のゲームデータ(手動選定36本 + 自動発見928本)/ja/...)・英語(/en/...)のロケール別ルーティング。接続元の国情報(Vercelデプロイ時)またはブラウザ言語から自動判定し、ヘッダーの言語切り替えセレクタで手動変更も可能next-intlを使ったロケール別ルーティング(src/app/[locale]/...)。
src/messages/ja.json / src/messages/en.json に完全翻訳済み。新しい言語を追加する場合は「routing.tsのlocalesに追加」+「対応するmessages/*.jsonを書く」だけでよいx-vercel-ip-countryヘッダー。Vercelにデプロイした場合のみ有効) → ③ブラウザのAccept-Language → ④既定値(日本語)
src/middleware.ts(Next.js 16ではproxy.ts)のCOUNTRY_TO_LOCALE。今は日本→jaのみ登録、それ以外は英語にフォールバックする設定。ここに追記するだけで対応国を増やせるl=japaneseで1回だけ取得しており、UI文言はSteamと無関係に管理している。ゲームのshortDescription(説明文)は取得した言語のまま(Steamが日本語ローカライズしていないタイトルは英語のまま)表示される。これを各言語に翻訳してキャッシュする仕組み(DeepL等)は次のステップとして保留中(下記「データの既知の限界」参照)「みんなで」だけでなく一人プレイしたい人にも対応するため、人数の選択肢に「1人」を追加した。
scripts/add-singleplayer-flag.mjs: 各ゲームがSteamの「シングルプレイヤー」カテゴリ(id=2)を持っているかを追加取得するマイグレーション(既存964件に対して一度実行済み。964件中882件がソロ対応と判定)discover-and-build.mjs / fetch-curated-games.mjsの実行では、この情報を最初から取得するようになっている(マイグレーションは初回だけでよい)coop.singlePlayer === trueのゲームのみ表示する(matchesFilters, src/lib/games.ts)2段階のパイプラインになっている。
verified: true)scripts/curated-seed.mjs : 人手で選んだ「みんなで遊べる有名タイトル」のリスト(appid・気分タグ・目安プレイ時間・実際の対応人数)scripts/fetch-curated-games.mjs : 上記リストを元にSteam公式 appdetails API から画像・価格・説明・カテゴリを取得
npm run data:curated
verified: false)scripts/discover-and-build.mjs : 手動リストだけでは「知ってるゲームばかり」になってしまうため、以下の手順で知名度は高くないが質は担保されているゲームを大規模に自動発見する
npm run data:discover # 候補6000件を評価(既定値)
node scripts/discover-and-build.mjs 3200 12 # 候補上限・カテゴリごとのページ数を指定
store.steampowered.com/search/results(公式検索フロントエンド)を使用appreviews API でチェックし、レビュー300件以上 かつ 高評価率75%以上のものだけ採用(品質ゲート。無名だが質の低いゲームを弾く)appdetails で type=game かつ協力/マルチカテゴリ持ちのものだけ最終採用mood-classifier.mjs(ジャンル+説明文のキーワードマッチ、EN/JP対応)で気分タグを推定data/games.json(手動選定+これまでの自動発見分)は保持したまま、新規に見つかった分だけ追加。差分実行なので同じappidを何度も評価し直さないdata/games.jsonへ途中経過を保存するため、数十分〜1時間規模のバッチが中断しても採用済み分は残る品質の閾値(レビュー300件・高評価率75%)はscripts/discover-and-build.mjs内のQUALITY_MIN_REVIEWS/QUALITY_MIN_POSITIVE_RATIOで調整可能。閾値を上げるほど有名タイトル寄りに、下げるほど無名タイトルも混ざりやすくなる。
scripts/fetch-steam-data.mjs : 上記2つを作る前の試作版(参考用、実運用では使っていない)SteamSpyは使っていない: Cloudflareのボット判定(403)でブロックされており、突破する行為は避けたため、Steam公式のストアフロントAPI(search/results / appreviews / appdetails)のみで完結する設計にしている。
レート制限について: Steamの検索APIは短時間に集中アクセスすると429(Too Many Requests)を返すことがある。discover-and-build.mjsは429を検知すると5秒→10秒→…と待機して自動リトライする。1000本規模のバッチは数十分〜1時間程度かかる想定。
estimatedSessionMinutes(プレイ時間の目安)とminPlayers/maxPlayers(対応人数)はSteam APIに存在しない項目のため暫定値(2〜4人)。将来的にはHowLongToBeat等の外部データに置き換えたいmoodTags(気分)はmood-classifier.mjsによるジャンル+説明文のキーワードマッチ(自動発見タイア)または人手判断(手動選定タイア)。1000本規模になるとキーワード分類の精度には限界があるため、質の担保はあくまでレビュー数/高評価率のフィルタが主。より精度を上げるならshortDescriptionをLLM(Claude Haiku等)に分類させる案が安価(1本あたり数銭程度)で精度も出やすいが、API課金が発生するため導入は要判断shortDescription)はSteamが日本語ローカライズしていないタイトルの場合、英語のまま表示される(UIのロケールを英語に切り替えても、この文章自体はSteamから取得した言語のまま変わらない)。DeepL等での翻訳キャッシュ導入は保留中で、導入すればこの制限は解消できるcc=パラメータを変えてSteamから再取得する必要があり、翻訳と同様「言語ごとに再取得」のコストがかかるため、現時点ではスコープ外としている)現状は手元でnpm run data:updateを手動実行する想定。差分実行に対応しているので、定期的に回せば新しく人気が出たゲームや新作が自動で追加されていく。完全に無人で回すには:
schedule(cron)でnpm run data:updateを週1回実行data/games.jsonに差分があれば自動コミット → Vercel/Cloudflare Pagesが自動で再デプロイ実装にはGitHubリポジトリ化が前提。
構成案(低コスト優先):
| 項目 | 推奨 | 理由 |
|---|---|---|
| フレームワーク | Next.js (App Router) | SSG/SSRでSEOに強く、generateMetadata・sitemap.ts・robots.tsが標準搭載 |
| ホスティング | Vercel無料枠 or Cloudflare Pages | 個人トラフィック規模なら無料枠で十分。静的+一部動的(/result,/browse)构成でも問題なく動く |
| データ更新 | GitHub Actions cron → 再デプロイ | サーバー常時稼働が不要。実行時のみ課金/無料枠消化 |
| 画像 | Steam CDN直リンク(next/imageのunoptimized) | 自前で画像を持たないので配信コストがかからない |
| 広告 | 現時点では未実装 | Google AdSenseはサイト審査・アカウント発行が必要で、ユーザー本人の作業が必要なため。ある程度コンテンツ(ゲーム数・PV)が育ってから申請するのが通りやすい |
SEO観点で今回やったこと:
generateMetadata(タイトル・description・OGP)/result?players=...&mood=... のようなクエリ付きURLで「3人・怖い・1時間・無料のおすすめ」的なロングテール検索に対応できる形にした/games/[appid])をgenerateStaticParamsで静的生成し、個別ゲーム名での検索流入も狙える形にしたsitemap.ts / robots.ts で自動生成まだやっていない(次のステップ):
npm install
npm run dev # http://localhost:3000
npm run build