BeamNG.Earth
BeamNG.drive용 1:1 비율 실시간 지구, 실제 고도·위성 이미지·부동 원점·보조 서버에서 LOD 스트리밍
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A portrait, mobile-first fantasy-football draft-order game for the Fort Wayne Finest
Fantasy Football League. You run up an infinite field with one control: tap anywhere to
switch lanes. Your score is the exact number of yards you survive, and it is hidden until
the run ends.
Status: Phase 4 complete. Manager sign-in, practice persistence, the official run
window, one-attempt enforcement, and draft-position selection all work against Postgres.
The commissioner dashboard and final reveal (Phase 5) are not built yet.
Requires Node 20 or newer and Docker (for the local database).README 전문 보기 ↗A portrait, mobile-first fantasy-football draft-order game for the Fort Wayne Finest Fantasy Football League. You run up an infinite field with one control: tap anywhere to switch lanes. Your score is the exact number of yards you survive, and it is hidden until the run ends.
Status: Phase 4 complete. Manager sign-in, practice persistence, the official run window, one-attempt enforcement, and draft-position selection all work against Postgres. The commissioner dashboard and final reveal (Phase 5) are not built yet.
Requires Node 20 or newer and Docker (for the local database).
npm install
cp .env.example .env.local
docker run -d --name fwf-pg -e POSTGRES_PASSWORD=draftdash -e POSTGRES_DB=draftdash -p 55432:5432 postgres:17-alpine
npm run db:migrate
npm run db:seed
npm run dev
Open http://localhost:3000 on a phone-sized viewport (or a real phone on the same network
via the network URL that next dev prints). The seed prints the manager names and PINs;
sign in as any of them, or as Commissioner for an admin account.
Set SESSION_SECRET in .env.local to any long random string:
node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"
| Command | What it does |
|---|---|
npm run dev | Dev server |
npm run build | Production build |
npm run start | Serve the production build |
npm run lint | ESLint |
npm run typecheck | tsc --noEmit |
npm run simulate | Headless course verification (see below) |
npm run db:migrate | Apply pending SQL migrations |
npm run db:seed | Insert league settings and members (safe to re-run) |
npm run test:api | Backend integration tests (dev server must be running) |
npm run test:draft | Draft selection tests (dev server must be running) |
npm test | Both suites |
app/ Next.js App Router pages and global styles
layout.tsx Root layout, viewport/safe-area config, orientation guard
page.tsx Screen state machine: menu -> playing -> result
components/
GameCanvas.tsx Mounts Phaser for one run (client-only)
OrientationGuard.tsx Landscape rotate-back overlay
ScoreReveal.tsx Count-up animation for the final yardage
MuteButton.tsx Sound on/off, persisted per device
game/
config.ts All gameplay tuning constants
rng.ts Seeded deterministic PRNG (mulberry32)
course.ts The entire simulation, with no Phaser dependency
sprites.ts Pixel-art grids, baked into textures at boot
audio.ts Web Audio arcade sounds, synthesised (no audio files)
milestones.ts Milestone thresholds and banner text
scenes/RunScene.ts Phaser scene: renders a Course and forwards taps
lib/
db.ts Postgres pool and transaction helper
auth.ts scrypt PIN hashing
session.ts Signed, httpOnly session cookie
phase.ts Server-authoritative phase and countdown logic
members.ts Member reads and the guarded score writes
api.ts Route-handler helpers and score validation
client.ts Browser-side API calls and types
db/migrations/ SQL migrations, applied in name order
scripts/
simulate.ts Headless verification of course invariants
migrate.ts Migration runner
seed.ts League settings and members
test-api.ts Integration tests for the rules that must hold
game/course.ts holds every gameplay rule — scrolling, spawning, difficulty, collision,
yardage — and imports nothing from Phaser. RunScene only draws it and forwards taps.
That split matters for the official run: given a seed and a sequence of inputs the course is fully deterministic, so every league member faces an identical defender sequence, spawn timing, speed progression, and starting lane. It also means the course can be verified (and later replayed server-side) without a browser.
npm run simulate runs a perfect-dodging bot against it and asserts that:
OPPOSITE_LANE_SEPARATION apart, which is the reaction
window. Changing SPAWN_GAP_MIN below that separation will break fairness; npm run simulate catches it.Every sprite is a character grid in game/sprites.ts, baked into a texture at boot.
Every sound is synthesised from oscillators and noise buffers in game/audio.ts. The turf,
crowd, and stars are drawn with Graphics. Nothing but the Press Start 2P webfont is
fetched, which keeps the payload small and means there is no art to source.
Audio is never required: if the AudioContext cannot start, every call is a no-op. The
sound toggle persists per device.
Anything a player could gain by lying about lives on the server:
now() compared against league_settings, never the
browser clock. Times are stored as timestamptz written with the IANA zone
America/Indiana/Indianapolis, so the DST offset is resolved by Postgres rather than
hardcoded. September resolves to UTC-4 and January to UTC-5, which is the point.POST /api/official/start locks the member row and sets
official_started_at in one transaction. The attempt is spent before a frame is drawn,
so refreshing, force-quitting, or opening a second device buys nothing.POST /api/official/complete writes once. A second submission returns the
locked score instead of overwriting it.GET /api/session returns only the caller's own row. No ranks, no other
managers, no counts.npm run test:api covers all of the above, including two simultaneous starts racing for
one attempt. The suite has been mutation-tested: removing the restart guard, the overwrite
guard, or the window check each makes it fail.
Yardage is tracked internally and never rendered during a run. There are no yard markers, and the turf bands are deliberately not yard-aligned so they cannot be counted.
Vercel, with a hosted Postgres. Any Postgres works — Neon, Vercel Postgres, or Supabase —
because the app talks plain SQL over pg rather than a vendor SDK.
DATABASE_URL and SESSION_SECRET as environment variables.npm run db:migrate and npm run db:seed with DATABASE_URL pointed at it.The game is then linked from nicksmith.app alongside the other games.
Draft-position selection and its turn gating (Phase 4), the commissioner dashboard and final reveal (Phase 5), and PWA support (Phase 6).
Two things are deliberately deferred rather than forgotten:
game/course.ts is Phaser-free and deterministic
precisely so a submitted input trace could be replayed server-side to verify it, if the
league wants that.