Sari la conținut
megapromoting
Hai să discutăm

Expertiză · Jocuri și simulări

Jocuri, simulări și experiențe interactive care se deschid dintr-un link, construite pe Three.js peste WebGL.

Construim experiențe interactive în browser: reguli care se aplică, o stare care se schimbă și un motiv pentru care omul mai face un pas. Cinci proiecte construite pe aceeași stivă, patru dintre ele deschise public chiar acum.

Construit dejaCinci implementări proprii pe aceeași stivă, dintre care patru se pot deschide de oricine fără să ne întrebe pe noi: humanoid-sim.megapromoting.com, vision.megapromoting.com, www.megapromoting.com/satelit/ și relieva.vercel.app — toate 200 la verificarea din 06.09.2026. Three.js apare în 17 fișiere sursă scrise de noi, în cinci depozite. Rezerva care schimbă jumătate din pagină: Unity și Unreal NU apar nicăieri în codul nostru — nici într-un fișier, nici într-un proiect, nici măcar ca aplicație instalată. Partea aceea rămâne ofertă cu condiții și e scrisă ca atare, nu ca realizare.

Construim jocuri, simulări și experiențe interactive care se deschid dintr-un link. Fără instalare, fără magazin, fără plugin: motorul e Three.js peste WebGL, iar publicul intră apăsând pe o adresă. Asta e stiva pe care o putem arăta — cinci proiecte construite, patru dintre ele publice, toate deschise de oricine vrea să le verifice.

Un joc nu e o pagină frumoasă. Sunt reguli care se aplică, o stare care se schimbă și un motiv pentru care omul mai face un pas. În jocul nostru de investigație, motivul e un ceas de 72 de ore: o replică te costă 10 minute, o deplasare prin oraș 30, iar la ora de închidere dosarul se închide cu sau fără tine. În simularea de roboți, motivul e curiozitatea: același robot, aceeași săritură, altă gravitație.

Partea pe care o luăm mai în serios decât se obișnuiește e proveniența. Într-o simulare, cea mai ușoară minciună e să lași o animație frumoasă să treacă drept fizică demonstrată. În simularea de roboți, toate cele 15 acțiuni din interfață sunt marcate în cod ca `cinematic`, panoul de dovezi al aplicației declară `actionValidation: "none"`, iar poarta de lansare a proiectului răspunde astăzi „Release qualification: blocked”. Preferăm să publicăm poarta care refuză decât o afirmație pe care n-o putem susține.

Despre Unity și Unreal spunem lucrurile pe față: le luăm la comandă, dar nu avem niciun proiect livrat pe ele. Ce urmează după această frază — condițiile, riscurile și cum pornim — e scris mai jos, nu ascuns într-o notă de subsol.

Ce cuprinde

Lucrarea, pe componente

Întâi regula, apoi grafica

Un prototip fără nicio textură, dar cu regula corectă, spune mai mult decât o scenă frumoasă fără miză. În jocul de investigație regula înseamnă cinci personaje, opt indicii din care trei sunt probă tare, patru motive, patru finaluri și un ceas de 72 de ore în care fiecare replică taie 10 minute, iar o deplasare 30. Orele 00:00–07:00 se sar automat, ca ceasul să nu se consume în somn.

Scena în browser, pe Three.js

Aceeași bibliotecă în cinci depozite: Three.js 0.184–0.185, uneori prin `@react-three/fiber` și `@react-three/drei`, alteori scrisă direct. Două proiecte folosesc varianta React; alte două scriu Three.js pur, până la nivelul la care gestionăm manual atributele de buffer. Cel mai mare motor propriu are 1.824 de linii și desenează toți sateliții ca un singur obiect `THREE.Points`, cu atribute de poziție, culoare, mărime și transparență actualizate în loc, cadru cu cadru.

Randare care coboară singură pe dispozitive slabe

Shaderul de pe acest site are trei trepte: `low` cu 24 de iterații de raymarching și raport de pixeli 0,5, `medium` cu 40 și 0,65, `high` cu 80, precizie `highp` și raport plafonat la 2. Alegerea e automată: pe mobil coboară la `low`, iar orice dispozitiv cu 4 nuclee sau mai puține îl retrogradează pe `high` la `medium`. Dacă WebGL lipsește, componenta se stinge curat în loc să arunce eroare. Aceeași disciplină în celelalte proiecte: plafon 1,6 în scena de oraș și 1,75 în cea de teren, 1,5 pe mobil în demonstratorul de lume, cu bucla de randare oprită când canvasul iese din ecran.

Scene mari care rămân un singur desen

Un oraș cu 9.506 clădiri nu înseamnă 9.506 obiecte. Fiecare amprentă din OpenStreetMap devine o `ExtrudeGeometry` fără teșitură și cu `curveSegments: 1`, primește culoarea scrisă direct în vârfuri, i se șterge atributul `uv` — și apoi toate se contopesc într-o singură geometrie prin `mergeGeometries`. Inelele geometrice degenerate din datele publice sunt sărite cu `try`/`catch`, nu lăsate să dărâme pagina.

Personaje care mint, își amintesc și cedează în condiții

Adevărul cazului nu stă în pagină. Dosarele celor cinci personaje — biografie, secret, condiția în care se rupe — stau într-un fișier care începe cu `import "server-only"` și nu poate fi importat din client. Personajul semnalează un indiciu deblocat printr-un tag pe care jucătorul nu-l vede, iar serverul îl acceptă doar dacă acel personaj are dreptul să dea acel indiciu. Un model care inventează un indiciu care nu-i aparține e ignorat, nu crezut.

Limba ca mecanică, nu ca traducere

Un personaj răspunde scurt și defensiv în română, dar în rusă devine vorbăreț și periculos de sincer — regula e scrisă în dosarul lui, iar prima replică în rusă îi crește încrederea. Microfonul urmează aceeași limbă (`ru-RU` sau `ro-RO`). Unde localizarea e clasică, mergem departe: simularea de roboți are opt limbi, cu araba marcată explicit ca scriere de la dreapta la stânga.

Simulare cu formule, nu cu impresii

Înălțimea săriturii scalează cu raportul gravitațiilor, perioada de mers cu 2π√(L/g), numărul Froude cu v²/(g·L), iar rezistența aerului cu densitatea atmosferei planetei. Autonomia bateriei trece printr-o funcție de scădere pe temperatură cu patru praguri: peste 20 °C nemodificată, peste 0 °C `0,85 + 0,0075·T`, peste −20 °C `0,55 + 0,015·T`, peste −40 °C `0,12 + 0,02·T`, iar sub asta 5 %. Mersul e cinematică inversă cu două segmente, rezolvată prin legea cosinusului, cu factor de sprijin 0,6 pe ciclu.

Sunet și voce construite, nu descărcate

Atmosfera jocului de investigație nu are niciun fișier audio: ploaia e zgomot roz filtrat trece-jos la 1.400 Hz și trece-sus la 300 Hz, buclat; pârâitul de vinil sunt impulsuri scurte generate la fiecare 180 ms; tunetul e o explozie de zgomot cu descreștere exponențială, programată la 18–48 de secunde. Ploaia vizuală e canvas 2D separat, până la 180 de picături înclinate. Vocea merge în ambele sensuri: dictare prin interfața de recunoaștere a browserului și replici sintetizate per personaj prin ElevenLabs `eleven_multilingual_v2`, MP3 44,1 kHz / 128 kbps.

Format de model 3D pentru care nu există încărcător gata făcut

Roboții Unitree G1 și Go2 vin în MJCF, formatul MuJoCo, care nu are un încărcător standard pentru Three.js. L-am scris: 170 de linii care citesc XML-ul, reconstruiesc ierarhia de corpuri, extrag fiecare articulație cu axa și intervalul ei, și încarcă geometria prin `STLLoader` și `OBJLoader`. În scenă intră 67 de fișiere de mesh, 62 MB — 29 de articulații acționate la humanoid, 12 la patruped, numărate în blocul `<actuator>` al fiecărui model.

Cum arată

Traseul, pas cu pas.

01

Regula pe hârtie, înainte de orice pixel

Scriem ce câștigă jucătorul, ce pierde, ce îl costă o acțiune și când se termină. Livrăm documentul de reguli și lista de stări — nu un moodboard. Dacă regula nu ține la citit, nu ține nici desenată.

02

Prototip jucabil fără chei și fără costuri

Jocul de investigație se parcurge integral și fără nicio cheie de API: ruta cade pe un set de replici scriptate de 237 de linii, iar vocile devin cele ale browserului. Așa se poate vedea jocul cap-coadă înainte de a plăti pentru primul token. Aceeași logică o punem în orice proiect: modul demonstrativ e o cerință de livrare, nu o consolare.

03

Bugetul de randare, stabilit înainte de conținut

Stabilim de la început ținta: ce dispozitiv trebuie să meargă acceptabil, care e plafonul de raport de pixeli, câte trepte de calitate există și când se oprește bucla. Apoi conținutul se așază în bugetul ăsta. E ordinea inversă față de cum se face de obicei, și e motivul pentru care scenele noastre nu se prăbușesc pe telefon.

04

Ce e demonstrat se etichetează, ce nu — la fel

Fiecare valoare afișată primește un statut: măsurată, dedusă din surse, sau simulată. Terenul din simularea de roboți poartă în scenă marcajul `visual_only`, ca nimeni să nu-l confunde cu o suprafață de coliziune. Livrăm eticheta odată cu valoarea; e muncă în plus la construcție și singurul lucru care ține pagina onestă după ce plecăm noi.

05

Predare cu tot cu ce lipsește

La final predăm codul, activele cu licențele lor și lista scrisă a ce nu e gata. Simularea de roboți e publicată ca build static servit de Nginx și nu are pipeline automat de publicare — scrie în README-ul propriu, nu într-o notă internă. Preferăm ca lista de lipsuri să vină de la noi.

1Regula scrisă pehârtie2scena în browser peThree.js3treapta de randarecare coboară singurăpe dispozitiv slabAceeași ordine în toate cele cinci proiecte.
Traseul, în 3 pași

Datele

Ce atingem, unde stau și cât rămân

Întrebările pe care le pune oricine are un responsabil cu protecția datelor — puse aici înainte să le pună el.

Ce iese din browser și ce nu
În jocul de investigație, salvarea stă în `localStorage` sub cheia `dosarul14-save-v1` și nu pleacă nicăieri. Către server pleacă doar conversația, tăiată la ultimele 20 de mesaje, cu maximum 600 de caractere pe mesaj. Cheile de model și de voce stau exclusiv pe server, în rutele de API; pagina publică nu le vede niciodată. În demonstratorul de lume, comanda vocală e recunoscută de browser — audio nu se trimite nicăieri.
De unde vin datele și modelele
Roboții G1 și Go2 sunt derivați din Google DeepMind MuJoCo Menagerie și păstrează licența BSD-3-Clause, cu notificarea inclusă lângă model. Orașul din scena urbană e OpenStreetMap peste Copernicus DEM GLO-30, cu data instantaneului scrisă în fișierul de date (2026-07-02). Fotografiile de la nivelul străzii poartă fiecare autorul, licența și pagina sursă. Mașina din demonstratorul de lume și tot decorul din simularea de roboți sunt generate din primitive — nu sunt active cumpărate.
Proveniența afișată, nu doar respectată
Scena urbană are un mod care recolorează orașul ca să arate care clădiri au înălțimea declarată în OpenStreetMap și care sunt deduse din numărul de etaje — 1.128 declarate față de 8.378 estimate, adică 11,9 %. Exagerarea verticală ×3 e scrisă în legendă, lângă intervalul real de teren, 37,7–155,9 m. Demonstratorul de lume etichetează fiecare schimbare din scenă cu una din patru surse, iar stratul creativ se afișează literal ca „simulat”.
Ce înseamnă „validat” la noi
În simularea de roboți, o acțiune devine validată doar după un scenariu versionat, o rulare de fizică autoritară, validare independentă, toleranțe declarate și un artefact reproductibil. Astăzi niciuna nu îndeplinește toate cinci, deci toate cele 15 sunt marcate `cinematic` și interfața o spune. Rapoartele MuJoCo există și sunt versionate: căderea pasivă a humanoidului pe Pământ e rulată cu MuJoCo 3.10.0 și pas de timp de 1 ms, pe un model cu 31 de corpuri, 72 de geometrii, 30 de articulații și masă totală 33,341142 kg, cu amprenta `sha256` a fișierului. Verificarea accelerației în cădere liberă trece la −9,806650 m/s² cu toleranță 0,049033.
Poarta care spune „nu”
Rulat pe 06.09.2026, verificatorul de dovezi al proiectului răspunde: determinism — trecut; fizică — trecut; opritor de articulație calibrat — fals; calificare pentru lansare — blocată. Motivul e scris: răspunsul de 5 ms al opritorului nu e calibrat pe hardware real. Poarta rămâne roșie până când e.

Un caz

O simulare de instruire care refuză să mintă

Situația

O echipă vrea să arate în prezentări cum se comportă un robot pe Lună față de Pământ, fără ca publicul tehnic din sală să poată spune „asta e doar o animație”.

Ce am construit

Modelul robotului se încarcă din formatul lui real — MJCF, prin încărcătorul scris de noi, cu fiecare articulație și intervalul ei; la humanoid intră 29 de articulații acționate. Mersul e cinematică inversă cu două segmente, cu factor de sprijin 0,6. Gravitația schimbă valorile din formule, nu viteza unei animații: înălțimea săriturii scalează cu raportul gravitațiilor, perioada pasului cu 2π√(L/g), autonomia bateriei trece prin scăderea pe temperatură cu patru praguri. Terenul e generat determinist din sămânța planetei — 80 m latură, amplitudine 0,18 m pe Pământ și 0,58 m pe Lună — și poartă în scenă marcajul `visual_only`, ca nimeni să nu-l ia drept suprafață de coliziune. Separat de browser rulează o validare numerică în MuJoCo, cu pas de 1 ms, care își scrie rezultatul într-un raport JSON versionat, cu amprenta modelului.

Ce a ieșit

Scena se deschide dintr-un link, în opt limbi, inclusiv cu scriere de la dreapta la stânga. Fiecare acțiune din interfață e etichetată onest — astăzi, toate ca previzualizare cinematică — iar un panou desfășurabil arată exact ce a fost verificat numeric și ce nu. Când cineva din sală întreabă „e demonstrat?”, răspunsul e pe ecran, nu în discurs.

Ce nu spune cazul

Presupune un model al robotului într-un format deschis, cu licența lui verificată; o listă scrisă a valorilor care trebuie afișate; și acordul că valorile nevalidate rămân marcate ca atare, inclusiv în prezentările de vânzări. Fără al treilea punct, proiectul nu e acesta.

Întrebări

Ce ne întreabă oamenii înainte să sune

Pe ce motor construiți și de ce anume pe el?

Three.js peste WebGL, în browser. Motivul e practic: livrabilul e un link. Nu ai instalare, nu ai magazin, nu ai proces de recenzie, iar o corectură ajunge la toată lumea în momentul publicării. Îl folosim în cinci depozite — versiunile 0.184 și 0.185 — uneori prin `@react-three/fiber` și `@react-three/drei`, alteori scris direct, până la nivelul la care gestionăm manual atributele de buffer. Patru dintre proiecte sunt deschise public chiar acum, deci afirmația se poate verifica fără să ne întrebi pe noi.

Puteți face în Unity sau Unreal?

Le luăm la comandă, dar răspunsul cinstit începe altfel: nu avem niciun proiect livrat pe Unity sau Unreal. Am căutat în tot codul de pe mașina de lucru — nicio referință la `UnityEngine`, niciun fișier `.uproject`, niciun `.csproj`, nicio macrocomandă de Unreal. Motoarele nu sunt nici măcar instalate. Ce se schimbă practic dacă alegi unul dintre ele: livrabilul nu mai e o adresă web, ci un build per platformă; distribuția trece prin magazin sau instalator; iar termenii de licențiere sunt cei publicați de Unity, respectiv Epic, la data proiectului, și îi verificăm atunci, nu îi presupunem. Cum procedăm: pornim cu un prototip plătit și, dacă proiectul cere experiență de motor pe care nu o avem în casă, o spunem înainte de contract.

Merge pe telefon?

Da, și e o decizie luată la construcție, nu o speranță. Shaderul de pe acest site are trei trepte de calitate — 24, 40 și 80 de iterații — și coboară singur: pe mobil pornește pe cea mai ușoară, iar pe orice dispozitiv cu 4 nuclee sau mai puține treapta maximă devine cea de mijloc. Raportul de pixeli e plafonat peste tot: 0,5 pe treapta joasă aici, 1,5 pe mobil în demonstratorul de lume, 1,6 și 1,75 în cele două scene ale hărții urbane. Când canvasul iese din ecran, bucla se oprește. Ce nu-ți pot da: o cifră de cadre pe secundă pe un telefon anume — nu avem o astfel de măsurătoare publicabilă, deci nu inventăm una.

Jocul se deschide în browser sau se instalează?

Tot ce am construit până acum se deschide în browser. Trei dintre proiecte sunt build-uri statice servite de Nginx de pe serverul nostru; unul stă pe Vercel. Un joc instalabil — desktop, telefon sau consolă — e o discuție diferită: presupune cont de dezvoltator, proces de recenzie, clasificare de vârstă și, cel mai probabil, alt motor. Niciunul dintre proiectele noastre nu e distribuit printr-un magazin, deci ăla ar fi un drum nou, cu pașii lui.

Cine deține codul și activele la final?

Codul scris pentru proiectul tău îți aparține, iar termenii se scriu în contract înainte să înceapă lucrul. Pentru active, distincția contează: cele generate din primitive sau din date publice vin fără constrângeri suplimentare — mașina din demonstratorul de lume e construită din cutii, capsule și cilindri, orașul din scena urbană e OpenStreetMap peste Copernicus DEM. Cele importate păstrează licența lor: roboții Unitree sunt BSD-3-Clause de la MuJoCo Menagerie, cu notificarea lângă model. Într-un proiect cu grafică creată pe comandă, sursa și proprietatea fiecărui activ se stabilesc pe listă, activ cu activ.

Ce se întâmplă cu multiplayerul?

E cea mai onestă rezervă pe care o avem. Niciunul dintre cele cinci proiecte nu are stare partajată între jucători: jocul de investigație ține tot în `localStorage`, simularea de roboți ține starea în memoria paginii. Un joc cu mai mulți oameni simultan cere un server autoritar de stare, sincronizare și tratarea decalajului de rețea — piese noi, nu o setare care se bifează. Se poate construi, dar intră în proiect ca subsistem separat, cu munca lui, nu ca opțiune.

Cât durează până văd ceva jucabil?

Nu-ți dau un număr pe care nu-l pot susține. Îți dau ordinea: prima livrare e un prototip jucabil cu regula corectă și grafica minimă, iar el trebuie să meargă fără nicio cheie de API — așa cum jocul nostru de investigație se parcurge integral pe replici scriptate. Abia după ce regula ține, se adaugă grafica, vocea și modelul. Dacă un furnizor îți promite termenul înainte să vadă regula, promite ceva ce nu a măsurat.

Cât consumă să ții personajele „vii”, adică pe model?

Consumul îl controlezi prin limitele scrise în cod, nu prin speranță. În jocul de investigație: istoricul trimis către model e tăiat la ultimele 20 de mesaje, mesajul jucătorului la 600 de caractere, răspunsul la 400 de tokeni, iar timpul maxim de așteptare e 45 de secunde. Sinteza vocală taie textul la 900 de caractere. Fiecare din aceste praguri e o linie pe care o putem muta împreună, cu efect direct pe factură. Și rămâne modul fără chei, în care jocul funcționează pe replici scriptate și nu consumă nimic.

Ce nu faceți?

Nu susținem că o animație e fizică demonstrată. În simularea de roboți, toate cele 15 acțiuni sunt marcate în cod ca `cinematic`, panoul de dovezi declară `actionValidation: "none"`, iar verificatorul de lansare răspunde astăzi „Release qualification: blocked”, pentru că răspunsul de 5 ms al opritorului de articulație nu e calibrat pe hardware real. Nu livrăm multiplayer ca opțiune ascunsă. Nu ne prezentăm ca studio de Unity sau Unreal. Și nu punem un demo în ofertă fără să spunem dacă e public — jocul nostru de investigație, de exemplu, rulează doar local și nu are adresă.

Pe ce se sprijină afirmațiile de mai sus (25 surse)
  1. Cele patru demonstratoare publice răspund 200: humanoid-sim.megapromoting.com (974 B), vision.megapromoting.com (619 B), www.megapromoting.com/satelit/ (1.160 B), relieva.vercel.app (680.122 B)https://humanoid-sim.megapromoting.com/ · https://vision.megapromoting.com/ · https://www.megapromoting.com/satelit/ · https://relieva.vercel.app/ · 2026-09-06

24 dintre ele sunt cod și fișiere din depozitele noastre. Nu le publicăm numele și nici linia: împreună, pe o singură pagină, ar descrie prea exact cum sunt construite sisteme care nu sunt doar ale noastre. Le parcurgem cu tine, în depozit, la cerere — verificarea rămâne posibilă, doar că se face într-o discuție.

Ce ai vrea să funcționeze mai bine?

Povestește-ne despre procesul tău. Împreună stabilim ce merită construit, ce putem conecta și cum verificăm rezultatul.

Hai să discutăm