BeamNG.Earth
BeamNG.drive용 1:1 비율 실시간 지구, 실제 고도·위성 이미지·부동 원점·보조 서버에서 LOD 스트리밍
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Human, Animal, Plant, Object - Discord Activity word game
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Human, Animal, Plant, Object — Discord Activity إنسان، حيوان، نبات، جماد. A multiplayer word game that runs inside a Discord voice channel as an Activity. Built with Next.js (App Router) on Vercel, Supabase (Postgres + Realtime), and the Discord Embedded App SDK. The UI comes in English and Arabic, with full right-to-left layout for Arabic.README 전문 보기 ↗
إنسان، حيوان، نبات، جماد. A multiplayer word game that runs inside a Discord voice channel as an Activity. Built with Next.js (App Router) on Vercel, Supabase (Postgres + Realtime), and the Discord Embedded App SDK. The UI comes in English and Arabic, with full right-to-left layout for Arabic.
src/lib/scoring.ts)| Answer | Points |
|---|---|
| Valid, and nobody else wrote the same word in that category | 10 |
| Valid, but another player wrote the same word | 5 |
| Invalid, blank, or wrong starting letter | 0 |
The server decides whether an answer is valid, in this order:
Matching ignores case, accents, and Arabic diacritics. It treats أ/إ/آ/ا as the same letter, and likewise ى/ي and ة/ه. A leading "ال" or "the " is also allowed. So "الأسد" counts for أ, and "The Rock" counts for R.
Discord client ──iframe──▶ https://<client_id>.discordsays.com (Discord proxy)
│ / → your Vercel app
│ /supabase → <ref>.supabase.co (Realtime websocket)
│ /discord-cdn → cdn.discordapp.com (avatars)
▼
Next.js on Vercel
/api/auth/discord trades the OAuth code for a token, checks the user with Discord, returns a signed session (JWT)
/api/game/[action] join · state · settings · ready · start · answers · endRound · vote · verdict · tally · next · lobby
│ service-role key
▼
Supabase Postgres ── Realtime (postgres_changes on `games`) ──▶ every client refetches state
/api/game/*, which checks the Discord session before touching the database. Picking letters, round deadlines, closing rounds, and scoring all happen on the server. Race-prone steps run as atomic SQL functions (start_round, end_round, apply_round_scores).games.version. Clients subscribe to that row through Supabase Realtime and refetch a view of the game tailored to them. Clients also poll state every 5 seconds. That poll doubles as a heartbeat (who's online, host handover) and as a fallback if the websocket drops.rounds.ends_at is set in Postgres. Clients measure how far their clock is from the server's on each response and count down to the server's deadline. The server accepts answers up to 2 seconds after the deadline to catch the last auto-save, then closes the round itself.games row, and no table accepts writes from the client.supabase/migrations/…_init.sql tables, RLS, triggers, RPCs, realtime publication
src/app/api/auth/discord OAuth2 code exchange → session token
src/app/api/auth/guest local test mode (ALLOW_GUEST_MODE=true only)
src/app/api/game/[action] game action router
src/server/game.ts all game rules and state projection
src/server/session.ts session JWT (jose)
src/lib/letters.ts alphabets, normalization, letter check
src/lib/scoring.ts validity + points (shared by server and live preview)
src/lib/discord.ts Embedded App SDK boot + URL mapping patches
src/hooks/useGame.ts realtime subscription, polling, clock sync
src/components/ Lobby, RoundPlay, Voting, RoundResults, FinalLeaderboard
src/i18n/en.json, ar.json every UI string (CLDR plural forms for Arabic)
tests/ node:test unit tests (scoring, letters, i18n key parity)
supabase link --project-ref <ref> and then supabase db push, orsupabase/migrations/20260915000000_init.sql into the SQL editor.sb_publishable_… key)sb_secret_… key)pg_cron and schedule the cleanup:
select cron.schedule('cleanup-games', '0 * * * *', 'select public.cleanup_stale_games()');
Go to discord.com/developers/applications and click New Application.
On the OAuth2 page:
https://127.0.0.1. Discord requires one, but Activities never actually use it.On Activities → Getting Started, enable Activities for the app.
On Activities → URL Mappings, add these mappings. Targets have no https:// and no trailing slash.
| Prefix | Target |
|---|---|
/ | your-app.vercel.app |
/supabase | <project-ref>.supabase.co |
/discord-cdn | cdn.discordapp.com |
The app calls patchUrlMappings() on startup. That rewrites Supabase and avatar URLs to go through these prefixes, because Discord's content security policy (CSP) blocks every host that isn't mapped.
On Installation, enable Guild Install and User Install.
On Activities → Settings, choose the supported platforms: Web, iOS, and Android. The layout is responsive and works on phones.
OAuth scopes requested at runtime: identify and guilds.
To launch it, join a voice channel, open the 🚀 Activities menu, and pick your app. While the app is unverified, only you, your team members, and users you add under App Testers can launch it.
Import the repo into Vercel. The framework preset is detected automatically.
Add these environment variables (see .env.example):
| Variable | Where it's used |
|---|---|
NEXT_PUBLIC_DISCORD_CLIENT_ID | client + server |
DISCORD_CLIENT_SECRET | server only |
NEXT_PUBLIC_SUPABASE_URL | client + server |
NEXT_PUBLIC_SUPABASE_ANON_KEY | client (Realtime only) |
SUPABASE_SERVICE_ROLE_KEY | server only |
SESSION_SECRET | server only. Generate with openssl rand -base64 32 |
ALLOW_GUEST_MODE | set false in production |
Turn off Deployment Protection for the environment Discord points at (Project → Settings → Deployment Protection). Otherwise Discord's proxy gets a Vercel login page instead of the game.
Framing headers: next.config.ts sends Content-Security-Policy: frame-ancestors with Discord's domains (discord.com, *.discord.com, *.discordsays.com). It doesn't send X-Frame-Options, so the page can be embedded. No vercel.json is needed.
Point the / URL mapping at your production domain.
cp .env.example .env.local # fill in the values
npm install
npm run dev
Without Discord (quickest). With ALLOW_GUEST_MODE=true, open http://localhost:3000, pick a name and a room code, then open more tabs with the same ?room= to play against yourself. Each tab gets its own guest identity. Guest rooms are kept separate from real Discord instances.
Inside Discord. Expose your dev server over HTTPS and point the / URL mapping at it:
npx cloudflared tunnel --url http://localhost:3000
If hot reload complains about the tunnel host, add it to allowedDevOrigins in next.config.ts.
| Command | What it does |
|---|---|
npm run dev | Next.js dev server |
npm run build | production build |
npm run lint | TypeScript type-check |
npm test | unit tests for scoring, letter normalization, and that en/ar have matching keys and all used keys exist |
{ id, emoji } to src/lib/categories.ts.categories.<id> to both en.json and ar.json.npm test. It fails if a label is missing in either language.t("section.key", { vars }). For counts, pass count. Arabic plural forms (_zero, _one, _two, _few, _many, _other) are picked automatically.join. Call GET /applications/{id}/activity-instances/{instance_id} with a bot token. Today the instance id is treated as a secret you can only get by being in the call./api/game/*, for example with Vercel Firewall rules.