Przejdź do treści
megapromotingPorozmawiajmy

Ekspertyza · Gry i symulacje

Gry, symulacje i interaktywne doświadczenia otwierane z linku, zbudowane na Three.js nad WebGL.

Budujemy interaktywne doświadczenia w przeglądarce: reguły, które się stosują, stan, który się zmienia, i powód, dla którego osoba robi kolejny krok. Pięć projektów zbudowanych na tym samym stacku, cztery z nich publicznie otwarte już teraz.

Już zbudowanePięć własnych wdrożeń na tym samym stacku, z których cztery może otworzyć każda osoba bez pytania nas o zgodę: humanoid-sim.megapromoting.com, vision.megapromoting.com, www.megapromoting.com/satelit/ i relieva.vercel.app — wszystkie 200 przy weryfikacji z 06.09.2026. Three.js pojawia się w 17 plikach źródłowych napisanych przez nas, w pięciu repozytoriach. Zastrzeżenie, które zmienia połowę strony: Unity i Unreal NIE pojawiają się nigdzie w naszym kodzie — ani w pliku, ani w projekcie, ani nawet jako zainstalowana aplikacja. Ta część pozostaje ofertą z warunkami i jest tak zapisana, a nie jako realizacja.

Budujemy gry, symulacje i interaktywne doświadczenia otwierane z linku. Bez instalacji, bez sklepu, bez wtyczki: silnik to Three.js nad WebGL, a publiczność wchodzi, klikając adres. To jest stos, który możemy pokazać — pięć zbudowanych projektów, cztery z nich publiczne, wszystkie otwierane przez każdą osobę, która chce je sprawdzić.

Gra to nie jest ładna strona. To reguły, które się stosują, stan, który się zmienia, i powód, dla którego osoba robi kolejny krok. W naszej grze śledczej tym powodem jest zegar 72-godzinny: jedna riposta kosztuje 10 minut, przejazd przez miasto 30, a o godzinie zamknięcia akta zamykają się z Tobą albo bez Ciebie. W symulacji robotów powodem jest ciekawość: ten sam robot, ten sam skok, inna grawitacja.

Część, którą traktujemy poważniej niż zwykle, to pochodzenie. W symulacji najłatwiejszym kłamstwem jest pozwolić, by ładna animacja uchodziła za wykazaną fizykę. W symulacji robotów wszystkie 15 działań w interfejsie są oznaczone w kodzie jako `cinematic`, panel dowodów aplikacji deklaruje `actionValidation: "none"`, a brama uruchomienia projektu odpowiada dziś „Release qualification: blocked”. Wolimy opublikować bramę, która odmawia, niż stwierdzenie, którego nie możemy obronić.

O Unity i Unreal mówimy wprost: przyjmujemy je na zamówienie, ale nie mamy żadnego zrealizowanego projektu na nich. To, co następuje po tym zdaniu — warunki, ryzyka i jak zaczynamy — jest napisane niżej, nie ukryte w przypisie.

Co obejmuje

Praca, komponent po komponencie

Najpierw reguła, potem grafika

Prototyp bez żadnej tekstury, ale z poprawną regułą, mówi więcej niż ładna scena bez stawki. W grze detektywistycznej reguła oznacza pięć postaci, osiem wskazówek, z których trzy są twardym dowodem, cztery motywy, cztery zakończenia i zegar 72-godzinny, w którym każda kwestia skraca czas o 10 minut, a przemieszczenie o 30. Godziny 00:00–07:00 są pomijane automatycznie, żeby zegar nie zużywał się we śnie.

Scena w przeglądarce, w Three.js

Ta sama biblioteka w pięciu repozytoriach: Three.js 0.184–0.185, czasem przez `@react-three/fiber` i `@react-three/drei`, czasem pisana bezpośrednio. Dwa projekty używają wariantu React; dwa inne piszą czysty Three.js, aż do poziomu, na którym ręcznie zarządzamy atrybutami bufora. Największy własny silnik ma 1.824 linie i rysuje wszystkie satelity jako jeden obiekt `THREE.Points`, z atrybutami pozycji, koloru, rozmiaru i przezroczystości aktualizowanymi na miejscu, klatka po klatce.

Renderowanie, które samo obniża jakość na słabszych urządzeniach

Shader na tej stronie ma trzy poziomy: `low` z 24 iteracjami raymarchingu i współczynnikiem pikseli 0,5, `medium` z 40 i 0,65, `high` z 80, precyzją `highp` i współczynnikiem ograniczonym do 2. Wybór jest automatyczny: na telefonie spada do `low`, a każde urządzenie z 4 rdzeniami lub mniej jest degradowane z `high` do `medium`. Jeśli brakuje WebGL, komponent wygasza się poprawnie zamiast rzucać błędem. Ta sama dyscyplina w innych projektach: limit 1,6 w scenie miasta i 1,75 w scenie terenu, 1,5 na telefonie w demonstratorze świata, z pętlą renderowania zatrzymaną, gdy canvas znika z ekranu.

Duże sceny, które pozostają jednym rysunkiem

Miasto z 9.506 budynkami nie oznacza 9.506 obiektów. Każdy ślad z OpenStreetMap staje się `ExtrudeGeometry` bez fazowania i z `curveSegments: 1`, dostaje kolor zapisany bezpośrednio w wierzchołkach, ma usuwany atrybut `uv` — a potem wszystko scala się w jedną geometrię przez `mergeGeometries`. Zdegenerowane pierścienie geometryczne z danych publicznych są pomijane przez `try`/`catch`, a nie zostawiane, by przewróciły stronę.

Postacie, które kłamią, pamiętają i ulegają warunkom

Prawda sprawy nie leży na stronie. Akta pięciu postaci — biografia, sekret, warunek, przy którym pęka — znajdują się w pliku, który zaczyna się od `import "server-only"` i nie może zostać zaimportowany z klienta. Postać sygnalizuje odblokowaną wskazówkę przez tag, którego gracz nie widzi, a serwer akceptuje to tylko wtedy, gdy ta postać ma prawo przekazać tę wskazówkę. Model, który wymyśla wskazówkę nie należącą do niego, jest ignorowany, a nie uznawany.

Język jako mechanika, a nie tłumaczenie

Postać odpowiada krótko i defensywnie po rumuńsku, ale po rosyjsku staje się gadatliwa i niebezpiecznie szczera — reguła jest zapisana w jej aktach, a pierwsza wypowiedź po rosyjsku zwiększa jej pewność siebie. Mikrofon podąża za tym samym językiem (`ru-RU` lub `ro-RO`). Tam, gdzie lokalizacja jest klasyczna, idziemy dalej: symulacja robotów ma osiem języków, z arabskim wyraźnie oznaczonym jako zapis od prawej do lewej.

Symulacja z formułami, a nie z wrażeniami

Wysokość skoku skaluje się stosunkiem grawitacji, okres chodu z 2π√(L/g), liczba Froude’a z v²/(g·L), a opór powietrza z gęstością atmosfery planety. Autonomia baterii przechodzi przez funkcję spadku zależną od temperatury z czterema progami: powyżej 20 °C bez zmian, powyżej 0 °C `0,85 + 0,0075·T`, powyżej −20 °C `0,55 + 0,015·T`, powyżej −40 °C `0,12 + 0,02·T`, a poniżej tego 5 %. Chód to kinematyka odwrotna z dwoma segmentami, rozwiązana przez twierdzenie cosinusów, ze współczynnikiem podparcia 0,6 na cykl.

Dźwięk i głos zbudowane, a nie pobrane

Atmosfera gry detektywistycznej nie ma żadnego pliku audio: deszcz to różowy szum filtrowany dolnoprzepustowo do 1.400 Hz i górnoprzepustowo do 300 Hz, zapętlony; trzaski winylu to krótkie impulsy generowane co 180 ms; grzmot to wybuch szumu z wykładniczym zanikiem, zaprogramowany na 18–48 sekund. Deszcz wizualny to osobny canvas 2D, do 180 pochylonych kropli. Głos działa w obie strony: dyktowanie przez interfejs rozpoznawania mowy przeglądarki i repliki syntetyzowane per postać przez ElevenLabs `eleven_multilingual_v2`, MP3 44,1 kHz / 128 kbps.

Format modelu 3D, dla którego nie ma jeszcze gotowego loadera

Roboty Unitree G1 i Go2 przychodzą w MJCF, formacie MuJoCo, który nie ma standardowego loadera dla Three.js. Napisałem go: 170 linii, które czytają XML, odbudowują hierarchię ciał, wyodrębniają każdy przegub z osią i zakresem oraz ładują geometrię przez `STLLoader` i `OBJLoader`. Do sceny trafia 67 plików mesh, 62 MB — 29 napędzanych przegubów w humanoidzie, 12 w czworonożnym, policzonych w bloku `<actuator>` każdego modelu.

Jak to wygląda

Trasa, krok po kroku.

01

Reguła na papierze, przed jakimkolwiek pikselem

Pisemy, co zyskuje gracz, co traci, ile kosztuje działanie i kiedy się kończy. Dostarczamy dokument zasad i listę stanów — nie moodboard. Jeśli reguła nie trzyma się w czytaniu, nie trzyma się też narysowana.

02

Działający prototyp bez kluczy i bez kosztów

Gra śledcza przechodzi w całości i bez żadnego klucza API: trasa opiera się na zestawie 237 wierszy skryptowanych dialogów, a głosy stają się głosami przeglądarki. Tak można zobaczyć grę od początku do końca przed zapłatą za pierwszy token. Tę samą logikę stosujemy w każdym projekcie: tryb demonstracyjny to wymóg dostawy, nie pocieszenie.

03

Budżet renderowania, ustalony przed treścią

Od początku ustalamy cel: na jakim urządzeniu ma działać akceptowalnie, jaki jest limit stosunku pikseli, ile poziomów jakości istnieje i kiedy zatrzymuje się pętla. Potem treść układa się w ten budżet. To odwrócona kolejność względem zwykle stosowanej i dlatego nasze sceny nie rozpadają się na telefonie.

04

To, co jest pokazane, jest oznaczone; to, co nie jest, też

Każda wyświetlana wartość otrzymuje status: zmierzona, wywnioskowana ze źródeł albo symulowana. Teren w symulacji robotów ma w scenie oznaczenie `visual_only`, aby nikt nie pomylił go z powierzchnią kolizji. Dostarczamy etykietę razem z wartością; to dodatkowa praca przy budowie i jedyna rzecz, która utrzymuje stronę uczciwą po naszym odejściu.

05

Przekazanie wraz z tym, czego brakuje

Na końcu przekazujemy kod, zasoby wraz z ich licencjami oraz pisemną listę tego, co nie jest gotowe. Symulacja robotów jest opublikowana jako statyczny build serwowany przez Nginx i nie ma automatycznego pipeline’u publikacji — jest to zapisane we własnym README, nie w wewnętrznej nocie. Wolimy, aby lista braków pochodziła od nas.

1Zasada zapisana wpapier2scena w przeglądarce naThree.js3treapta de randarektóry sam się opuszczape dispozitiv slabTaka sama kolejność we wszystkich pięciu projektach.
Trasa, w 3 krokach

Dane

Czego dotykamy, gdzie to leży i jak długo zostaje

Pytania, które zadaje każdy, kto ma inspektora ochrony danych — postawione tutaj, zanim on je zada.

Co wychodzi z przeglądarki, a co nie
W grze śledczej zapis znajduje się w `localStorage` pod kluczem `dosarul14-save-v1` i nigdzie nie wychodzi. Na serwer trafia tylko rozmowa, przycięta do ostatnich 20 wiadomości, po maksymalnie 600 znaków na wiadomość. Klucze modelu i głosu znajdują się wyłącznie na serwerze, w trasach API; strona publiczna nigdy ich nie widzi. W demonstratorze świata polecenie głosowe jest rozpoznawane przez przeglądarkę — audio nie jest nigdzie wysyłane.
Skąd pochodzą dane i modele
Roboty G1 i Go2 są pochodnymi Google DeepMind MuJoCo Menagerie i zachowują licencję BSD-3-Clause, z dołączonym powiadomieniem obok modelu. Miasto w scenie miejskiej to OpenStreetMap na Copernicus DEM GLO-30, z datą zrzutu zapisaną w pliku danych (2026-07-02). Zdjęcia z poziomu ulicy mają każde podanego autora, licencję i stronę źródłową. Samochód w demonstratorze świata i cała scenografia w symulacji robotów są generowane z prymitywów — nie są to kupione zasoby.
Pochodzenie pokazane, nie tylko przestrzegane
Scena miejska ma tryb, który zmienia kolory miasta, aby pokazać, które budynki mają wysokość zadeklarowaną w OpenStreetMap, a które są wywnioskowane z liczby kondygnacji — 1 128 zadeklarowanych wobec 8 378 oszacowanych, czyli 11,9 %. Przewyższenie pionowe ×3 jest zapisane w legendzie, obok rzeczywistego zakresu terenu, 37,7–155,9 m. Demonstrator świata oznacza każdą zmianę w scenie jedną z czterech źródeł, a warstwa kreatywna wyświetla się dosłownie jako „symulowane”.
Co u nas oznacza „zwalidowane”
W symulacji robotów działanie staje się zwalidowane dopiero po wersjonowanym scenariuszu, autorytatywnym uruchomieniu fizyki, niezależnej walidacji, zadeklarowanych tolerancjach i reprodukowalnym artefakcie. Dziś żadna nie spełnia wszystkich pięciu, więc wszystkie 15 są oznaczone `cinematic`, a interfejs to mówi. Raporty MuJoCo istnieją i są wersjonowane: pasywne upadanie humanoida na Ziemi jest uruchamiane z MuJoCo 3.10.0 i krokiem czasu 1 ms, na modelu z 31 ciałami, 72 geometriami, 30 stawami i masą całkowitą 33,341142 kg, z odciskiem `sha256` pliku. Sprawdzenie przyspieszenia w swobodnym spadku przechodzi przy −9,806650 m/s² z tolerancją 0,049033.
Brama, która mówi „nie”
Uruchomiony 06.09.2026, weryfikator dowodów projektu odpowiada: determinizm — zaliczony; fizyka — zaliczona; skalibrowany ogranicznik przegubu — fałsz; kwalifikacja do uruchomienia — zablokowana. Powód jest zapisany: odpowiedź ogranicznika 5 ms nie jest skalibrowana na realnym sprzęcie. Brama pozostaje czerwona, dopóki tak się nie stanie.

Przykład

Symulacja szkoleniowa, która odmawia kłamania

Sytuacja

Zespół chce pokazać w prezentacjach, jak zachowuje się robot na Księżycu w porównaniu z Ziemią, bez tego, by techniczna publiczność na sali mogła powiedzieć „to tylko animacja”.

Co zbudowaliśmy

Model robota wczytuje się z jego rzeczywistego formatu — MJCF, przez napisany przez nas loader, z każdym stawem i jego zakresem; w humanoidzie wchodzi 29 stawów napędzanych. Chód to odwrotna kinematyka z dwoma segmentami, z współczynnikiem podparcia 0,6. Grawitacja zmienia wartości we wzorach, nie prędkość animacji: wysokość skoku skaluje się względem stosunku grawitacji, okres kroku z 2π√(L/g), autonomia baterii przechodzi przez spadek zależny od temperatury z czterema progami. Teren jest generowany deterministycznie z ziarna planety — 80 m boku, amplituda 0,18 m na Ziemi i 0,58 m na Księżycu — i ma w scenie oznaczenie `visual_only`, aby nikt nie wziął go za powierzchnię kolizji. Oddzielnie od przeglądarki działa walidacja numeryczna w MuJoCo, z krokiem 1 ms, która zapisuje wynik do wersjonowanego raportu JSON z odciskiem modelu.

Co z tego wyszło

Scena otwiera się z linku, w ośmiu językach, w tym z pismem od prawej do lewej. Każde działanie w interfejsie jest uczciwie oznaczone — dziś wszystkie jako podgląd kinematyczny — a panel rozwijany pokazuje dokładnie, co zostało sprawdzone numerycznie, a co nie. Gdy ktoś na sali pyta „czy to zostało udowodnione?”, odpowiedź jest na ekranie, nie w opowieści.

Czego nie mówi ten przypadek

Zakłada model robota w otwartym formacie, z jego sprawdzoną licencją; pisaną listę wartości, które mają być wyświetlane; oraz zgodę, że wartości nieweryfikowane pozostają tak oznaczone, także w prezentacjach sprzedażowych. Bez trzeciego punktu projekt nie jest tym.

Pytania

O co pytają ludzie, zanim zadzwonią

Na jakim silniku budujecie i dlaczego właśnie na nim?

Three.js nad WebGL, w przeglądarce. Powód jest praktyczny: dostarczany element to link. Nie ma instalacji, nie ma sklepu, nie ma procesu recenzji, a poprawka trafia do wszystkich w momencie publikacji. Używamy go w pięciu repozytoriach — wersje 0.184 i 0.185 — czasem przez `@react-three/fiber` i `@react-three/drei`, czasem pisane bezpośrednio, aż do poziomu, na którym ręcznie obsługujemy atrybuty bufora. Cztery z projektów są teraz publicznie otwarte, więc stwierdzenie da się sprawdzić bez pytania nas.

Czy można to zrobić w Unity albo Unreal?

Bierzemy to na zamówienie, ale uczciwa odpowiedź zaczyna się inaczej: nie mamy żadnego projektu dostarczonego w Unity ani Unreal. Przeszukaliśmy cały kod na stacji roboczej — brak odniesień do `UnityEngine`, brak pliku `.uproject`, brak `.csproj`, brak makr Unreal. Silniki nie są nawet zainstalowane. Co zmienia się praktycznie, jeśli wybierzesz jeden z nich: dostarczany element nie jest już adresem internetowym, lecz buildem na platformę; dystrybucja przechodzi przez sklep albo instalator; a warunki licencyjne są tymi opublikowanymi przez Unity, odpowiednio Epic, na datę projektu, i sprawdzamy je wtedy, a nie zakładamy. Jak działamy: zaczynamy od płatnego prototypu i, jeśli projekt wymaga doświadczenia z silnikiem, którego nie mamy wewnątrz, mówimy to przed umową.

Działa na telefonie?

Tak, i to decyzja podjęta przy budowie, a nie nadzieja. Shader na tej stronie ma trzy poziomy jakości — 24, 40 i 80 iteracji — i sam się skaluje w dół: na urządzeniach mobilnych startuje na najlżejszym, a na każdym urządzeniu z 4 rdzeniami lub mniej maksymalny poziom staje się środkowym. Współczynnik pikseli jest ograniczony wszędzie: 0,5 na niskim poziomie tutaj, 1,5 na mobile w demonstratorze świata, 1,6 i 1,75 w dwóch scenach miejskiej mapy. Gdy canvas wychodzi poza ekran, pętla się zatrzymuje. Czego nie mogę dać: liczby klatek na sekundę dla konkretnego telefonu — nie mamy takiego publicznego pomiaru, więc nie wymyślamy go.

Gra otwiera się w przeglądarce czy instaluje?

Wszystko, co dotąd zbudowaliśmy, otwiera się w przeglądarce. Trzy z projektów to statyczne buildy serwowane przez Nginx z naszego serwera; jeden jest na Vercel. Gra instalowana — desktop, telefon albo konsola — to inna rozmowa: wymaga konta deweloperskiego, procesu recenzji, klasyfikacji wiekowej i najpewniej innego silnika. Żaden z naszych projektów nie jest dystrybuowany przez sklep, więc to byłaby nowa droga, z własnymi krokami.

Kto na końcu posiada kod i zasoby?

Kod napisany dla projektu należy do Ciebie, a warunki zapisuje się w umowie przed rozpoczęciem pracy. W przypadku zasobów liczy się rozróżnienie: te wygenerowane z prymitywów albo z danych publicznych przychodzą bez dodatkowych ograniczeń — pojazd w demonstratorze świata jest zbudowany z pudeł, kapsuł i cylindrów, miasto w scenie miejskiej to OpenStreetMap na Copernicus DEM. Zaimportowane zachowują swoją licencję: roboty Unitree są BSD-3-Clause z MuJoCo Menagerie, z informacją obok modelu. W projekcie z grafiką tworzoną na zamówienie źródło i własność każdego zasobu ustala się na liście, zasób po zasobie.

Co dzieje się z multiplayerem?

To najuczciwsze zastrzeżenie, jakie mamy. Żaden z pięciu projektów nie ma współdzielonego stanu między graczami: gra śledcza trzyma wszystko w `localStorage`, symulacja robotów trzyma stan w pamięci strony. Gra dla wielu osób jednocześnie wymaga autorytatywnego serwera stanu, synchronizacji i obsługi opóźnień sieci — nowych elementów, a nie opcji do zaznaczenia. Da się to zbudować, ale wchodzi do projektu jako osobny podsystem, z własną pracą, a nie jako opcja.

Ile trwa, zanim zobaczę coś grywalnego?

Nie podam liczby, której nie mogę obronić. Podaję kolejność: pierwsza dostawa to grywalny prototyp z poprawną regułą i minimalną grafiką, a on musi działać bez żadnego klucza API — tak jak nasza gra śledcza przechodzi w całości na skryptowanych dialogach. Dopiero po utrzymaniu reguły dodaje się grafikę, głos i model. Jeśli dostawca obiecuje termin, zanim zobaczy regułę, obiecuje coś, czego nie zmierzył.

Ile kosztuje utrzymanie postaci „przy życiu”, czyli na modelu?

Zużycie kontrolujesz przez limity zapisane w kodzie, nie przez nadzieję. W grze śledczej: historia wysyłana do modelu jest ucinana do ostatnich 20 wiadomości, wiadomość gracza do 600 znaków, odpowiedź do 400 tokenów, a maksymalny czas oczekiwania to 45 sekund. Synteza mowy ucina tekst do 900 znaków. Każdy z tych progów to linia, którą możemy przesunąć razem, z bezpośrednim skutkiem na fakturę. I pozostaje tryb bez kluczy, w którym gra działa na skryptowanych dialogach i nic nie zużywa.

Czego nie robicie?

Nie twierdzimy, że animacja jest udowodniona fizycznie. W symulacji robotów wszystkie 15 akcji są oznaczone w kodzie jako `cinematic`, panel dowodów deklaruje `actionValidation: "none"`, a weryfikator uruchomienia odpowiada dziś „Release qualification: blocked”, ponieważ odpowiedź 5 ms ogranicznika stawu nie jest skalibrowana na rzeczywistym sprzęcie. Nie dostarczamy multiplayera jako ukrytej opcji. Nie przedstawiamy się jako studio Unity ani Unreal. I nie umieszczamy dema w ofercie bez powiedzenia, czy jest publiczne — nasza gra śledcza na przykład działa tylko lokalnie i nie ma adresu.

Na czym opierają się powyższe stwierdzenia (25 źródeł)
  1. Cztery publiczne demonstratory odpowiadają 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 z nich to kod i pliki z naszych repozytoriów. Nie publikujemy ich nazw ani numerów linii: razem, na jednej stronie, opisałoby to zbyt dokładnie, jak zbudowane są systemy, które nie należą tylko do nas. Przechodzimy je razem z Tobą, w repozytorium, na życzenie — weryfikacja pozostaje możliwa, tylko odbywa się w rozmowie.

Co chcesz, żeby działało lepiej?

Opowiedz nam o swoim procesie. Wspólnie ustalimy, co warto zbudować, co da się połączyć i jak sprawdzimy wynik.

Porozmawiajmy