BeamNG.Earth
A 1:1 scale streamed Earth for BeamNG.drive: real elevation and satellite imagery, floating origin, LOD streaming from a companion server
Napravite kviz, podijelite PIN i igrajte uživo s prijateljima, obitelji ili razredom. Igrači se pridružuju s mobitela, bez računa.
Translation pending
GamesGitHub @syloweb-syncOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Pitalica je multiplayer platforma za kvizove uživo, za društvene večeri, obiteljska okupljanja, razrede i timove. Domaćin složi kviz i pokrene igru, a igrači ulaze s mobitela preko 6-znamenkastog PIN-a ili QR koda, samo s nadimkom i bez računa. Pitanja se svima pojavljuju istovremeno, bodove računa server, a igra završava ljestvicom i postoljem pobjednika.
Sučelje je na hrvatskom jeziku, a kod i komentari na engleskom.
Detaljna arhitektura (stanja igre, realtime događaji, baza): docs/ARHITEKTURA.md.
Domaćin (potreban račun)
Igrač (bez računa)
Vrste pitanja
| Vrsta | Igrač | Bodovanje |
|---|---|---|
| Jedan točan odgovor | dodir na karticu | točno / netočno |
| Više točnih odgovora | označi pa pošalji | cijeli skup ili djelomično |
| Točno / netočno | dva velika gumba | točno / netočno |
| Klizač procjene | klizač, +/– | tolerancija, s bodovima prema blizini |
| Kratki odgovor | upis teksta | točno podudaranje uz normalizaciju, opcionalno ručni pregled |
| Brojčani odgovor | numerička tipkovnica | tolerancija, cijeli ili decimalni broj |
| Pribadača na slici | dodir na sliku | radijus, prema udaljenosti |
| Poredaj redom | povlačenje ili strelice | točan redoslijed ili djelomično |
| Spoji parove | dodir lijevo pa desno | svi parovi ili djelomično |
| Slike kao odgovori | dodir na sliku | točno / netočno |
| Anketa | dodir | bez bodova, rezultati uživo |
| Rangiranje | povlačenje ili strelice | bez bodova, poredak grupe (Borda) |
| Sloj | Tehnologija |
|---|---|
| Okvir | Next.js 16 (App Router, Turbopack), React 19, TypeScript (strict) |
| Stil | Tailwind CSS 4 (dizajnerski tokeni u src/app/globals.css), vlastite komponente na Radix UI primitivima u stilu shadcn/ui |
| Forme i validacija | React Hook Form, Zod 4 (iste sheme na klijentu i serveru) |
| Animacije | Motion (motion/react), canvas-confetti |
| Ikone i fontovi | Lucide, Bricolage Grotesque i Plus Jakarta Sans (lokalno preko @fontsource) |
| Povlačenje | dnd-kit |
| Backend | Supabase: Postgres, Auth, Realtime (Broadcast i Presence), Storage |
| Testovi | Vitest (unit i integracija), Playwright (E2E) |
| Deploy | Vercel (uz dnevni cron za čišćenje) |
Zvukovi se sintetiziraju u pregledniku (Web Audio API), pa nema audio datoteka i nema pitanja licence.
Preduvjeti: Node.js ≥ 20.9 (preporuka 22), Docker (za lokalni Supabase).
npm install # .npmrc postavlja legacy-peer-deps
npx supabase start # lokalni Postgres, Auth, Realtime, Storage, Mailpit
cp .env.example .env.local # zatim upišite vrijednosti koje je ispisao `supabase start`
npm run dev # http://localhost:3000
npx supabase start primjenjuje migracije iz supabase/migrations/. U .env.local upišite ove vrijednosti iz ispisa naredbe:
Ispis supabase start | Varijabla |
|---|---|
API_URL | NEXT_PUBLIC_SUPABASE_URL |
PUBLISHABLE_KEY (ili ANON_KEY) | NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY |
SECRET_KEY (ili SERVICE_ROLE_KEY) | SUPABASE_SECRET_KEY |
Lokalni e-mailovi (potvrde, reset lozinke) stižu u Mailpit na http://127.0.0.1:54324.
Prvi kviz za 30 sekundi: registrirajte se, na nadzornoj ploči kliknite Uvezi JSON i odaberite examples/primjer-kviz.pitalica.json. Zatim pokrenite igru i otvorite /join u drugom pregledniku ili na mobitelu u istoj mreži.
Korisne naredbe:
npm run db:reset # ponovno stvara lokalnu bazu iz migracija
npm run db:types # regenerira src/lib/supabase/database.types.ts
npm run lint && npm run typecheck && npm test
Ako
supabase startne može preuzeti slike spublic.ecr.aws, pokrenite ga saSUPABASE_INTERNAL_IMAGE_REGISTRY=docker.io npx supabase start.
npx supabase login
npx supabase link --project-ref <project-ref>
npx supabase db push
Migracija stvara tablice, indekse, RLS politike, funkcije i Storage bucket quiz-media (javno čitanje, najviše 5 MB, samo PNG, JPEG, WebP i GIF).https://pitalica.vercel.apphttps://pitalica.vercel.app/** (po potrebi i adrese preview deployova)/auth/callback (PKCE). Ako koristite predloške s token_hash, usmjerite ih na /auth/confirm?token_hash={{ .TokenHash }}&type=recovery.game:<uuid>. Poruke sadrže samo „stanje se promijenilo, verzija N”, nikad odgovore ni bodove, a UUID sesije znaju samo sudionici. Ako je javni pristup isključen, igra i dalje radi, ali se osvježava periodično (svakih 2,5 s) umjesto trenutno.publishable ide u NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY, a secret u SUPABASE_SECRET_KEY. Legacy anon i service_role ključevi također rade.| Varijabla | Gdje | Opis |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | klijent i server | URL Supabase projekta |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | klijent i server | publishable (ili legacy anon) ključ; zaštitu podataka osigurava RLS |
SUPABASE_SECRET_KEY | samo server | secret (ili service_role) ključ za autoritativne operacije igre. Nikad s prefiksom NEXT_PUBLIC_. |
NEXT_PUBLIC_SITE_URL | klijent i server | javni URL aplikacije (metapodaci, apsolutne poveznice) |
CRON_SECRET | samo server | štiti /api/cron/cleanup; Vercel Cron ga šalje automatski |
Primjer je u .env.example. Prave tajne se ne commitaju (.env*.local je u .gitignore).
vercel.json postavlja npm ci i cron./api/cron/cleanup pokreće se jednom dnevno (03:17 UTC). On:
Nije potreban zaseban server za igru. Rokovi se provjeravaju „lijeno”: svako čitanje stanja zatvara pitanje kojem je istekao rok, a promjene se zapisuju atomarno (compare-and-swap).
| Naredba | Što pokreće | Preduvjet |
|---|---|---|
npm test | unit testovi (Vitest, ~100): bodovanje svih tipova, djelomično bodovanje, tolerancije, udaljenost pribadače, redoslijed i parovi, javni prikaz bez odgovora, stanja igre, rokovi, izjednačenja, timovi, nadimci, validacija | ništa |
npm run test:integration | integracijski testovi na pravoj bazi: spremanje kviza, RLS, autorizacija domaćina, PIN, ulazak, odgovori, zatvaranje pitanja, poredak, cijela igra sa svih 12 tipova, 20 istovremenih igrača, timovi, vježba, ručni pregled, Storage politike, čišćenje, ograničenje PIN-a | npx supabase start i .env.local |
npm run test:e2e | Playwright: domaćin gradi kviz u uređivaču i igra s dva igrača; svaki tip pitanja kroz sučelje igrača; ponovno spajanje; zabranjene radnje; ručni pregled; timovi; vježba; alati uređivača (upload, dupliciranje, brisanje, presloži, pregled, izvoz i uvoz); pretraga na ploči; odjava i reset lozinke e-mailom | kao gore. Test sam napravi produkcijski build i pokrene ga na portu 3100. |
npm run test:all
E2E_BASE_URL=http://localhost:3000 npm run test:e2e # koristi već pokrenut dev server
QA=1 npx playwright test visual.qa # snimke zaslona za dizajnerski pregled
Playwright je prikvačen na 1.63.0 zbog preglednika instaliranog u razvojnom okruženju. Na drugim računalima pokrenite npx playwright install chromium.
src/
app/ # Next.js rute (stranice + /api route handleri)
(auth)/ # prijava, registracija, reset lozinke
(app)/ # nadzorna ploča, povijest igara, račun
quizzes/[id]/ # uređivač, pregled, postavljanje igre
host/[id]/ # ekran domaćina (projektor)
play/[id]/ join/ practice/[quizId]/
api/ # quizzes, media, games, join, practice, cron
components/
ui/ brand/ site/ home/ app/ auth/
editor/ # uređivač kviza i uređivači po tipu pitanja
game/ # dijeljeno: unos odgovora, rezultati, odbrojavanje, ljestvica, realtime hook
host/ player/
lib/
domain/ # čista logika bez I/O: sheme, bodovanje, javni prikaz, stanja, poredak
server/ # samo server: auth, HTTP, rate limit, kvizovi, games/ (servis igre)
client/ # samo klijent: API, upload, zvuk, sesija igrača, izvoz
supabase/ # klijenti + generirani tipovi baze
game/types.ts # ugovor GameView / GameEvent između servera i klijenta
supabase/migrations/ # SQL shema, RLS, funkcije, Storage
tests/unit | integration | e2e | support
examples/ # primjer kviza za uvoz
docs/ARHITEKTURA.md
host_idanon nema nikakva prava nad tablicama igre, a funkcije igre (submit_answer, finalize_question…) može izvršiti samo service_role.(igrač, pitanje) sprječava dvostruke bodove.state_version (compare-and-swap), pa dvostruki klik ne preskače pitanje.<user-id>/<uuid>.<ext>. Bucket provjerava MIME tip i veličinu, a RLS na storage.objects dopušta pisanje samo u vlastitu mapu.?next=)Sve bodove računa src/lib/domain/scoring.ts na serveru. Svako pitanje daje udio f između 0 i 1:
| Tip | Pravilo |
|---|---|
| Jedan točan, slike, točno/netočno | f = 1 za točan odgovor, inače 0 |
| Više točnih | 1 samo za točan skup; s djelomičnim bodovanjem max(0, (točno označeni − pogrešno označeni) / broj točnih) |
| Klizač | samo točno: 1 ili 0; inače unutar ±tolerancije točno, a s „bodovima prema blizini” 100 % na cilju i 50 % na rubu |
| Brojčani | ` |
| Kratki odgovor | podudaranje nakon odabrane normalizacije (razmaci, velika/mala slova, dijakritici). Bez približnog (fuzzy) podudaranja. Uz ručni pregled nepodudarni odgovori čekaju odluku domaćina. |
| Pribadača | udaljenost u jedinicama širine slike, uz poštivanje omjera stranica (koordinate su normalizirane 0–1); unutar radijusa točno, s ocjenom prema blizini 100 %–50 % |
| Poredaj | 1 za točan redoslijed; djelomično = stavke na točnom mjestu / ukupno |
| Spoji parove | 1 za sve parove; djelomično = točni parovi / ukupno |
| Anketa, rangiranje | nikad ne boduju |
Bodovi = osnovica × množitelj (0/1/2) × f. S bonusom za brzinu polovica je zajamčena, a druga polovica linearno pada s vremenom odgovora (kao u Kahootu). Bodovi nikad nisu negativni.
Izjednačenja: igrači s istim bodovima dijele mjesto (1, 1, 3). Redoslijed prikaza unutar istog mjesta određuje broj točnih odgovora, zatim ukupno vrijeme odgovora, pa vrijeme ulaska.
Timovi: bodovi tima su prosjek bodova članova, pa veći tim nema prednost.
src/lib/media.ts.| Problem | Rješenje |
|---|---|
| „Aplikacija nije konfigurirana” | Nedostaju NEXT_PUBLIC_SUPABASE_* ili SUPABASE_SECRET_KEY. Provjerite .env.local ili varijable na Vercelu. |
| Igrači ne vide promjene odmah | Provjerite je li u Supabase Realtime postavkama uključen javni pristup. Bez njega aplikacija se osvježava svakih 2,5 s. |
| Poveznica za reset lozinke vodi na login s greškom | URL aplikacije mora biti u Redirect URLs, a link se mora otvoriti u istom pregledniku u kojem je zatražen (PKCE). |
| Upload slike ne uspijeva | Datoteka mora biti PNG, JPEG, WebP ili GIF do 5 MB. Bucket quiz-media stvara migracija; provjerite je li supabase db push izvršen. |
| „Previše pokušaja” | Ograničenje po IP-u traje minutu. Kod PIN-a se broje samo promašaji. |
npm install javlja grešku s peer ovisnostima | Repozitorij ima .npmrc s legacy-peer-deps=true; koristite npm ci. |
Lokalni supabase start ne može preuzeti slike | SUPABASE_INTERNAL_IMAGE_REGISTRY=docker.io npx supabase start |
| Playwright ne pronalazi preglednik | npx playwright install chromium |