BeamNG.Earth
BeamNG.drive용 1:1 비율 실시간 지구, 실제 고도·위성 이미지·부동 원점·보조 서버에서 LOD 스트리밍
링크만으로 위키피디아 페이지를 이동해 목표 달성, 무료·즉시·공유 가능, 일일 챌린지 플레이
Get from one Wikipedia page to another using only links. Free, instant, and built to share. Play the Daily Challenge.
게임TypeScript · CSSGitHub @BillGStanford온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗The internet disagrees with you. Duelio is a small web experiment. Visitors see a low-stakes everyday dilemma with two sides, pick one, see where everyone landed, read or join the discussion, and share the question.
It tests one hypothesis: people will share a specific everyday disagreement, invite others to weigh in, and take part in a public discussion about it. See EXPERIMENT.md for how to judge that.
/d/<slug>: a straightforward prompt and voting panel, followed by the group-room tally when applicable, discussion, and report. After voting, the image card preview is open on the page rather than hidden in a dropdown./admin./submit: public dilemma submissions. Valid submissions are published immediately, appear in the searchable homepage feed, and get a shareable dilemma page./admin: editor desk (create, edit, publish, unpublish, remove, set closing date, review submissions, resolve reports, 7-day metrics)./guidelines: community rules.https://duelio.ink by default; set NEXT_PUBLIC_SITE_URL when attaching a different custom domain./admin/matchups.WikiRush (/wikirush) is "GeoGuessr for Wikipedia": you see a start page and a destination, then race there using only the links in the article.
/wikirush?c=SEED&t=90&r=5&s=SCORE&n=NAME) that replay a friend's exact rounds and show you how you compare.src/lib/wikirush/ and is unit tested; the same formula runs server-side in supabase/wikirush-v2.sql.🟩🟨🟧🟥), native share or copy, and a "Challenge a friend" link.submit_wikirush_game (run supabase/wikirush-v2.sql, see supabase/WIKIRUSH_SETUP.md); without it, scores and stats stay on the device.python3 scripts/make-wikirush-art.py regenerates public/wikirush/ (watermark mark, social card).Vote card. After you vote, you get a card with your pick ("I picked Split evenly. Do you agree?") and the live percentage. Pick a size, then share. On phones it opens the native share sheet with the image attached. On a computer it saves the PNG.
| Size | Pixels | Good for |
|---|---|---|
| Story 9:16 | 1080 x 1920 | Instagram, TikTok, Reels, WhatsApp status |
| Feed post 4:5 | 1080 x 1350 | Instagram and Facebook feed |
| Square 1:1 | 1080 x 1080 | iMessage, WhatsApp, any post |
| Link card 1.91:1 | 1200 x 630 | X, Facebook, LinkedIn (also the link preview image) |
Vote cards show the closing time when one is set. Every card (vote, group chat, take, and each dilemma's preview) uses the same look: a soft paper background with faint blue and pink glows, a hairline frame, a bold serif headline centered on the card, and small labels. Text is measured against the real font and sized to fit, so long questions shrink and wrap evenly instead of overflowing, and very long text ends in an ellipsis. Image URL pattern: /card/<slug>/a?fmt=story|portrait|square|wide (use b for side B, room?g=<code> for the group card).
Settle it in your group chat. One button creates a group link (/d/<slug>?g=<code>) and opens the share sheet, or copies it. Everyone who votes through that link is counted in the group. The link preview in iMessage, WhatsApp, Slack, and similar apps reads "Group chat verdict pending" with the question and how many votes are in. The page shows the group's own split live (it refreshes every 8 seconds). The split is shown only to people who voted in that group. Everyone else sees just how many have voted. Chat apps cache previews, so the vote count on a preview can lag.
Your take. After you vote on enough debates, you see how often you sided with the majority and can share it as a card. A debate counts once 3 people have voted and one side leads. You need 3 counted debates. No account is needed: it uses the same anonymous cookie as voting, so clearing cookies resets it.
Group codes are random labels, not secrets. Anyone with a link can vote in that group, and anyone can invent a code. A public voter nickname is optional; when supplied, it is displayed next to that person's side. It is not a verified identity, and voters can choose a different nickname on another dilemma.
Choices made on purpose: results are never locked behind sharing, and there are no email or push notifications, because both would pull in personal data and consent handling this experiment doesn't need. Group chats get a live tally instead.
The homepage illustration is a local SVG asset, so it does not depend on an external image-generation or image-hosting service. On Windows, postinstall also applies a narrow URL-resolution compatibility fix to Next.js's bundled @vercel/og renderer; without it, generated share cards fail to render because Node's Windows path joining corrupts the renderer's bundled font and WASM URLs.
Upgrading an existing Supabase project: run the full supabase/schema.sql again. Its create table if not exists and alter table ... add column if not exists statements add the daily schedule, public nickname and crowd-prediction fields, plus defense and endorsement tables, without removing existing data. The app requires those schema updates before deployment.
Next.js 14 (App Router) + TypeScript, Tailwind CSS, Supabase Postgres for production data, Threadline embed for discussion, Vercel for hosting. No web fonts and no animation libraries.
Requires Node 18.18 or newer.
npm install
npm run dev # http://localhost:3000
This zip already contains a .env.local with the Threadline values and a generated admin password. With no Supabase variables set, Duelio stores data in .data/duelio.json. That is for development and single-server hosting only.
Admin: open /admin, sign in with ADMIN_PASSWORD from .env.local. Admin is switched off if that variable is empty.
Copy .env.example to .env.local and fill it in.
| Variable | Needed | Purpose |
|---|---|---|
NEXT_PUBLIC_THREADLINE_SITE_ID | yes | Threadline site id. Public by design (it appears in the page HTML). |
NEXT_PUBLIC_THREADLINE_API_URL | yes | Threadline comments API URL. The redirecting threadline.ink/api alias is normalized to its direct API host. |
NEXT_PUBLIC_THREADLINE_EMBED_SRC | yes | Threadline embed script URL. |
NEXT_PUBLIC_SITE_URL | in production | Public URL without trailing slash, used for canonical and social URLs. |
ADMIN_PASSWORD | for /admin | Editor password. Choose a long one. |
ADMIN_SESSION_SECRET | optional | Signs the admin cookie. Defaults to ADMIN_PASSWORD. |
VOTE_SALT | recommended | Salt for hashing anonymous voter ids. Use a long random string. |
NEXT_PUBLIC_SUPABASE_URL | production | Supabase project URL. |
SUPABASE_SERVICE_ROLE_KEY | production | Server only. Never expose it to the browser. |
NEXT_PUBLIC_ANALYTICS_ID | optional | Reserved for connecting an analytics provider (see Analytics). |
NEXT_PUBLIC_* values are baked into the browser bundle at build time, so changing one means rebuilding.
src/components/ThreadlineComments.tsx loads the Threadline embed with next/script, reading the three NEXT_PUBLIC_THREADLINE_* variables. The API URL is normalized to avoid redirecting CORS preflights. If a variable is missing or the script fails to load, the page shows "The discussion is unavailable right now. Your vote still counts." and keeps working.
Threadline provides the discussion only (comments, replies, reactions, comment moderation). Voting, submissions, reports, and analytics are Duelio's own.
Two things the embed snippet does not document, so check them on your deployed site before you rely on them:
The "Be the first person to make the case" line is shown above the embed on every dilemma. Duelio cannot tell whether a thread has comments, so it does not hide that line.
Before enabling matchup voting in production, run supabase/matchups.sql in the Supabase SQL Editor. This adds the matchup, round, and vote tables plus server-only functions for atomic voting and round rollover. It does not delete or rewrite existing polls or votes. The feature uses the existing NEXT_PUBLIC_SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, VOTE_SALT, and Threadline environment variables; no new secrets are required. After the migration, deploy the branch and test creating the same pair in both orders, voting twice in one round, closing a round from /admin/matchups, and confirming that the share URL preview includes the chosen competitor.
supabase/schema.sql.npx vercel).NEXT_PUBLIC_SITE_URL.dilemmas table./admin on the live site, sign in, and check the storage line says "Supabase".Do not deploy to Vercel without Supabase. The JSON file store would live in temporary storage and lose votes.
Row level security is enabled on every table with no public policies, so the Supabase anon key can read nothing. The app only talks to Supabase from the server, using the service role key.
/admin; legacy submissions waiting for review can still be approved or rejected there.pending (hidden), published, rejected, removed (page shows a removal notice)./admin under "Open reports". Press Mark resolved when handled.Duelio records these events into your own database and shows 7-day counts in /admin: page views, dilemma views, vote started and completed, share clicked and completed, group chats created and joined, vote cards and takes shared, submission started and completed, report submitted, and discussion script loaded. Share completion is only measured for the native share sheet and for copying the link, because the browser cannot see where a link is pasted.
src/lib/analytics.ts is the adapter. To connect a provider, add its snippet so it creates window.dataLayer, and every event is mirrored there. Comment and reply activity inside Threadline is not visible to Duelio, so read it in Threadline's own dashboard.
npm test # 35 unit tests: results math, validation, store, rooms, crowd take, card text fitting
npm run typecheck
npm run build && npm run start
npm run smoke # 88 end-to-end checks, including every card size against a running server (set ADMIN_PASSWORD)
npm run smoke expects a fresh data store (delete .data/ first) because it casts votes.
src/assets/bg-<tone>-<size>.jpg. Edit the colours or glows in scripts/make-backgrounds.py and run python3 scripts/make-backgrounds.py (needs pip install pillow numpy).src/assets (see FONT-LICENSE.txt): Pagella Bold for headlines, Poppins Bold for small labels. The Pagella copy has its optional ligature table removed because the image renderer cannot read it.SPEC in src/lib/cards.tsx. Text fitting lives in src/lib/textFit.ts.The editorial dilemmas live in src/lib/seed.ts. They are inserted only into an empty database. Afterward, manage dilemmas in /admin.
src/app/ pages and API routes (/, /d/[slug], /submit, /guidelines, /admin, /api/*)
src/components/ VoteBox, ShareBar, ReportBox, SubmitForm, ThreadlineComments, DuelStrip
src/lib/ validation, results math, auth, rate limit, analytics, seed, card images and text fitting
src/lib/store/ Store interface, JSON file store, Supabase store
supabase/schema.sql database schema
scripts/ background image generator
tests/ unit tests and the end-to-end smoke script
/ and /wikirush (?play=1 starts a game, ?daily=1 starts the Daily, ?stream=1 turns on streamer mode).articleCache.ts), the API slims and caches Wikipedia HTML, and the first round warms up from the lobby.starters.ts)./wikirush/og, challenge links get their own social preview, plus /wikirush/how-to-play and /wikirush/streamers.gx-* classes in src/app/globals.css): top bar with your avatar, level and points; a bottom tab bar on phones.src/components/game/*): PLAY, Daily, mode cards for Quick, Hard, Wild, Duel and Dilemma, player card and top explorers./login is a full-screen sign-in / sign-up with avatar picker. Profile, Settings and Leaderboard use the same look.python3 scripts/make-game-art.py into public/game/.supabase/wikirush-v2.sql (avatar column) so avatars show on the public leaderboard./records shows the fastest finds on any page pair, per-pair record holders (with a "Beat it" button that loads that exact pair in the lobby via ?beat=<id>), best games, fastest clean sweeps and every Day N Challenge board./api/wikirush/records, which re-validates the route (starts and ends on the right pages, one hop per click, human pace) before writing to wikirush_records. Run the last block of supabase/wikirush-v2.sql to create the table.?pick=.