OhMyGame
OhMyGame은 AI로 게임을 만들 수 있는 오픈소스 스튜디오로, 디자인·구축·플레이테스트·출판을 하나의 앱에서 모델 키와 함께 수행합니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Chain-saver duty tracker for the Torn faction EPIC Mafia [40959].
Members enlist as chain savers ("I can save for 3h"), the app tracks their paid availability time, watches the faction chain via the Torn API every ~15s, automatically detects and credits chain saves (who hit, at how many seconds remaining — holds included), rotates turns between simultaneous savers, sends push notifications ("🚨 YOUR TURN — SAVE NOW"), and generates payout reports for the bankers.
| Piece | Where | Why |
|---|---|---|
| Next.js web app + API | Vercel Hobby | UI, auth, shifts, admin, payouts |
| Postgres | Supabase Free | all data; RLS locked to service-role |
| Chain poller | Supabase Edge Function poller | pg_cron (every 15s) → pg_net → function |
| Live updates | Supabase Realtime broadcast | countdown page without polling |
| Alerts | Web Push (VAPID) | works with the site closed |
Members log in with a Limited Torn API key (never full). Keys are stored
AES-256-GCM encrypted; every API call the app makes carries the comment
ChainWatch, so key owners can audit usage in their own Torn key log.
/v2/faction/chain (with a unique timestamp param each
call — Torn caches identical requests for ~30s and this is the documented
bypass).chain counter value.
From the attack's real ended timestamp it computes the true seconds
remaining — a held attack that registered "after zero" still counts.Detection observes actual API values, so warm-up chains, milestone cooldowns and future timer changes don't break it.
npm install
npm test # 29 unit tests: state machine, rotation, crypto
cp .env.example .env.local # fill in values (see below)
npm run dev
npx supabase login
npx supabase link --project-ref <PROJECT_REF>
npx supabase db push # applies migrations (schema + cron jobs)
openssl rand -base64 32 # → API_KEY_ENC_KEY
openssl rand -base64 32 # → POLLER_SECRET
node scripts/generate-vapid.mjs # prints VAPID_KEYS and NEXT_PUBLIC_VAPID_PUBLIC_KEY
npx supabase secrets set POLLER_SECRET=... API_KEY_ENC_KEY=... VAPID_SUBJECT=mailto:[email protected]
npx supabase secrets set VAPID_KEYS='{"publicKey":{...},"privateKey":{...}}'
npx supabase functions deploy poller --no-verify-jwt
select vault.create_secret('https://<PROJECT_REF>.supabase.co/functions/v1/poller', 'poller_url');
select vault.create_secret('<POLLER_SECRET value>', 'poller_secret');
select jobname, status, start_time
from cron.job_run_details
order by start_time desc limit 10;
Rows should appear ~15s apart with status = succeeded. If sub-minute
scheduling is rejected on your project, fall back to a 1-minute schedule
where the function loops internally:
select cron.unschedule('chainwatch-poller');
-- then re-add with schedule '* * * * *' (and ask the poller to loop —
-- see supabase/migrations/0002_cron.sql comments)
Push this repo to GitHub, then import it at vercel.com/new.
Set environment variables (Project → Settings → Environment Variables):
NEXT_PUBLIC_SUPABASE_URL — from Supabase → Settings → APINEXT_PUBLIC_SUPABASE_ANON_KEY — same pageSUPABASE_SERVICE_ROLE_KEY — same page (keep secret!)API_KEY_ENC_KEY — same value as the Supabase secretSESSION_SECRET — openssl rand -base64 32NEXT_PUBLIC_VAPID_PUBLIC_KEY — from the generate-vapid script(The faction id lives in the database: settings.faction_id, seeded to
40959. To track a different faction, update that row in the SQL editor.)
Deploy. The daily /api/keepalive cron (vercel.json) plus the poller's
own traffic keep the Supabase free project from pausing.
/duty, land ~5 hits, then deliberately wait until
the timer is under 90s and have one enlisted member hit (bonus points for
holding the result screen). Within a minute the save should appear
confirmed with the seconds-remaining, the rotation should advance, and the
turn-holder should have received a push.cron.job_run_details and the function logs.For stretches like the Halloween event, when the faction pays for saves but there's no ranked war to hang a war payout on. Admin → Event mode: name, end time (TCT) and a flat $ per save → Start event now.
While it runs:
/duty redirects to /event (enlist, siren, standings); the home page shows
a popup + banner pointing there; the whole site wears the Halloween themewar_report, so nothing is paid twiceAt the end time (or End event now) the poller closes the event's shifts and
everything returns to normal. On /event an admin then freezes the payout
(hourly pay + saves × $ per save); it's published on /payouts.
Deploy order: apply 0042_chain_events.sql first, then restart the VPS poller,
then deploy the site — the new poller and site read the new table/column.
app/ Next.js pages + API routes
lib/ server glue (db, session, crypto, torn, state)
supabase/functions/
_shared/logic/ PURE chain state machine + rotation (unit-tested)
_shared/lib/ torn client + crypto (runs in Node AND Deno)
poller/ the 15s poll cycle (detection, attribution, alerts)
supabase/migrations/ schema + cron schedules
tests/ Vitest suites for the correctness core
docs/superpowers/specs/ the approved design document