Saltar para o conteúdo
megapromotingVamos falar

Expertise · Jogos e simulações

Jogos, simulações e experiências interativas que se abrem a partir de um link, construídos em Three.js sobre WebGL.

Construímos experiências interativas no navegador: regras que se aplicam, um estado que muda e um motivo para a pessoa dar mais um passo. Cinco projetos construídos sobre a mesma stack, quatro deles abertos ao público agora mesmo.

Já construídoCinci 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.

Construímos jogos, simulações e experiências interativas que se abrem a partir de um link. Sem instalação, sem loja, sem plugin: o motor é Three.js sobre WebGL, e o público entra ao clicar num endereço. Essa é a stack que podemos mostrar — cinco projetos construídos, quatro deles públicos, todos abertos a quem quiser verificá-los.

Um jogo não é uma página bonita. São regras que se aplicam, um estado que muda e um motivo para a pessoa dar mais um passo. No nosso jogo de investigação, o motivo é um relógio de 72 horas: uma resposta custa-lhe 10 minutos, um deslocamento pela cidade 30, e à hora de fecho o dossier fecha com ou sem você. Na simulação de robôs, o motivo é a curiosidade: o mesmo robô, o mesmo salto, outra gravidade.

A parte que levamos mais a sério do que é habitual é a proveniência. Numa simulação, a mentira mais fácil é deixar uma animação bonita passar por física demonstrada. Na simulação de robôs, as 15 ações da interface estão marcadas no código como `cinematic`, o painel de evidências da aplicação declara `actionValidation: "none"`, e a gate de lançamento do projeto responde hoje „Release qualification: blocked”. Preferimos publicar a gate que recusa do que uma afirmação que não podemos sustentar.

Sobre Unity e Unreal dizemos as coisas de forma direta: aceitamos por encomenda, mas não temos nenhum projeto entregue neles. O que vem depois desta frase — as condições, os riscos e como começamos — está escrito abaixo, não escondido numa nota de rodapé.

Qué incluye

El trabajo, por componentes

Primeiro a regra, depois o grafismo

Um protótipo sem qualquer textura, mas com a regra correta, diz mais do que uma cena bonita sem aposta. No jogo de investigação, a regra significa cinco personagens, oito pistas das quais três são prova forte, quatro motivos, quatro finais e um relógio de 72 horas em que cada fala corta 10 minutos e um deslocamento 30. As horas 00:00–07:00 são saltadas automaticamente, para que o relógio não se esgote durante o sono.

A cena no browser, em Three.js

A mesma biblioteca em cinco repositórios: Three.js 0.184–0.185, por vezes através de `@react-three/fiber` e `@react-three/drei`, outras vezes escrita diretamente. Dois projetos usam a variante React; outros dois escrevem Three.js puro, até ao ponto em que gerimos manualmente os atributos do buffer. O maior motor próprio tem 1.824 linhas e desenha todos os satélites como um único objeto `THREE.Points`, com atributos de posição, cor, tamanho e transparência atualizados no local, frame a frame.

Renderização que desce sozinha em dispositivos fracos

O shader deste site tem três níveis: `low` com 24 iterações de raymarching e razão de pixels 0,5, `medium` com 40 e 0,65, `high` com 80, precisão `highp` e razão limitada a 2. A escolha é automática: em mobile desce para `low`, e qualquer dispositivo com 4 núcleos ou menos é rebaixado de `high` para `medium`. Se o WebGL estiver ausente, o componente termina de forma limpa em vez de lançar erro. A mesma disciplina nos outros projetos: limite de 1,6 na cena da cidade e 1,75 na do terreno, 1,5 em mobile no demonstrador de mundo, com o loop de renderização parado quando o canvas sai do ecrã.

Cenas grandes que continuam a ser um único desenho

Uma cidade com 9.506 edifícios não significa 9.506 objetos. Cada fingerprint do OpenStreetMap torna-se uma `ExtrudeGeometry` sem chanfradura e com `curveSegments: 1`, recebe a cor escrita diretamente nos vértices, tem o atributo `uv` removido — e depois tudo se funde numa única geometria através de `mergeGeometries`. Os anéis geométricos degenerados nos dados públicos são saltados com `try`/`catch`, não deixados derrubar a página.

Personagens que mentem, se lembram e cedem em condições

A verdade do caso não está na página. Os dossiers das cinco personagens — biografia, segredo, a condição em que quebra — estão num ficheiro que começa com `import "server-only"` e não pode ser importado do cliente. A personagem assinala uma pista desbloqueada através de uma tag que o jogador não vê, e o servidor só a aceita se essa personagem tiver o direito de dar essa pista. Um modelo que inventa uma pista que não lhe pertence é ignorado, não acreditado.

A língua como mecânica, não como tradução

Uma personagem responde de forma curta e defensiva em romeno, mas em russo torna-se faladora e perigosamente sincera — a regra está escrita no respetivo dossier, e a primeira fala em russo aumenta a confiança. O microfone segue a mesma língua (`ru-RU` ou `ro-RO`). Onde a localização é clássica, vamos mais longe: a simulação de robôs tem oito línguas, com o árabe marcado explicitamente como escrita da direita para a esquerda.

Simulação com fórmulas, não com impressões

A altura do salto escala com a razão das gravidades, o período de marcha com 2π√(L/g), o número de Froude com v²/(g·L), e a resistência do ar com a densidade da atmosfera do planeta. A autonomia da bateria passa por uma função de redução por temperatura com quatro limiares: acima de 20 °C sem alteração, acima de 0 °C `0,85 + 0,0075·T`, acima de −20 °C `0,55 + 0,015·T`, acima de −40 °C `0,12 + 0,02·T`, e abaixo disso 5 %. A marcha é cinemática inversa com dois segmentos, resolvida pela lei dos cossenos, com fator de apoio 0,6 por ciclo.

Som e voz construídos, não descarregados

A atmosfera do jogo de investigação não tem qualquer ficheiro áudio: a chuva é ruído rosa filtrado com passa-baixo a 1.400 Hz e passa-alto a 300 Hz, em loop; o crepitar do vinil são impulsos curtos gerados a cada 180 ms; o trovão é uma explosão de ruído com decaimento exponencial, programada para 18–48 segundos. A chuva visual é um canvas 2D separado, até 180 gotas inclinadas. A voz funciona nos dois sentidos: ditado através da interface de reconhecimento do browser e falas sintetizadas por personagem via ElevenLabs `eleven_multilingual_v2`, MP3 44,1 kHz / 128 kbps.

Formato de modelo 3D para o qual ainda não existe um carregador pronto

Os robôs Unitree G1 e Go2 vêm em MJCF, o formato MuJoCo, que não tem um carregador padrão para Three.js. Escrevemo-lo: 170 linhas que leem o XML, reconstruem a hierarquia de corpos, extraem cada articulação com o seu eixo e intervalo, e carregam a geometria através de `STLLoader` e `OBJLoader`. Entram em cena 67 ficheiros de mesh, 62 MB — 29 articulações acionadas no humanoide, 12 no quadrúpede, contadas no bloco `<actuator>` de cada modelo.

Qué aspecto tiene

El recorrido, paso a paso.

01

A regra no papel, antes de qualquer pixel

Escrevemos o que o jogador ganha, o que perde, quanto custa uma ação e quando termina. Entregamos o documento de regras e a lista de estados — não um moodboard. Se a regra não se sustém na leitura, também não se sustém desenhada.

02

Protótipo jogável sem chaves e sem custos

O jogo de investigação é percorrido integralmente e sem qualquer chave de API: o percurso recai sobre um conjunto de falas scriptadas de 237 linhas, e as vozes passam a ser as do browser. Assim, é possível ver o jogo do início ao fim antes de pagar pelo primeiro token. A mesma lógica aplicamos em qualquer projeto: o modo demonstrativo é um requisito de entrega, não um consolo.

03

Orçamento de renderização, definido antes do conteúdo

Definimos desde o início o objetivo: que dispositivo tem de funcionar de forma aceitável, qual é o limite de relação de pixels, quantos níveis de qualidade existem e quando o ciclo pára. Depois, o conteúdo encaixa nesse orçamento. É a ordem inversa da habitual, e é por isso que as nossas cenas não colapsam no telemóvel.

04

O que é demonstrado é rotulado, o que não é — também

Cada valor apresentado recebe um estatuto: medido, inferido a partir de fontes, ou simulado. O terreno na simulação de robôs recebe em cena a marca `visual_only`, para que ninguém o confunda com uma superfície de colisão. Entregamos o rótulo juntamente com o valor; é trabalho extra na construção e a única coisa que mantém a página honesta depois de sairmos.

05

Entrega com tudo o que falta

No final entregamos o código, os ativos com as respetivas licenças e a lista escrita do que não está pronto. A simulação de robôs é publicada como build estático servido por Nginx e não tem pipeline automático de publicação — isso está escrito no respetivo README, não numa nota interna. Preferimos que a lista de faltas venha de nós.

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

Os dados

Qué tocamos, dónde están y cuánto se quedan

Las preguntas que hace cualquiera que tenga un delegado de protección de datos — hechas aquí antes de que las haga él.

O que sai do browser e o que não sai
No jogo de investigação, o salvamento fica em `localStorage` sob a chave `dosarul14-save-v1` e não vai a lado nenhum. Para o servidor vai apenas a conversa, cortada às últimas 20 mensagens, com no máximo 600 caracteres por mensagem. As chaves do modelo e da voz ficam exclusivamente no servidor, nas rotas de API; a página pública nunca as vê. No demonstrador de mundo, o comando vocal é reconhecido pelo browser — o áudio não é enviado para lado nenhum.
De onde vêm os dados e os modelos
Os robôs G1 e Go2 são derivados do Google DeepMind MuJoCo Menagerie e mantêm a licença BSD-3-Clause, com a notificação incluída junto do modelo. A cidade na cena urbana é OpenStreetMap sobre Copernicus DEM GLO-30, com a data do instantâneo escrita no ficheiro de dados (2026-07-02). As fotografias ao nível da rua trazem cada uma o autor, a licença e a página de origem. O carro no demonstrador de mundo e todo o cenário na simulação de robôs são gerados a partir de primitivas — não são ativos comprados.
Proveniência exibida, não apenas respeitada
A cena urbana tem um modo que recoloreia a cidade para mostrar quais edifícios têm a altura declarada no OpenStreetMap e quais são inferidos a partir do número de pisos — 1.128 declarados face a 8.378 estimados, ou seja, 11,9 %. A exageração vertical ×3 está escrita na legenda, ao lado do intervalo real do terreno, 37,7–155,9 m. O demonstrador de mundo etiqueta cada alteração na cena com uma de quatro fontes, e a camada criativa é exibida literalmente como „simulado”.
O que significa „validado” para nós
Na simulação de robôs, uma ação só se torna validada depois de um cenário versionado, uma execução de física autoritativa, validação independente, tolerâncias declaradas e um artefacto reproduzível. Hoje nenhuma cumpre todas as cinco, por isso todas as 15 estão marcadas `cinematic` e a interface diz isso. Os relatórios MuJoCo existem e estão versionados: a queda passiva do humanoide na Terra é executada com MuJoCo 3.10.0 e passo de tempo de 1 ms, num modelo com 31 corpos, 72 geometrias, 30 articulações e massa total 33,341142 kg, com a impressão `sha256` do ficheiro. A verificação da aceleração em queda livre passa para −9,806650 m/s² com tolerância 0,049033.
O portão que diz „não”
Executado em 06.09.2026, o verificador de evidências do projeto responde: determinismo — passou; física — passou; batente de articulação calibrado — falso; qualificação para lançamento — bloqueada. O motivo está escrito: a resposta de 5 ms do batente não está calibrada em hardware real. O gate continua vermelho até estar calibrado.

Un caso

Uma simulação de treino que se recusa a mentir

A situação

Uma equipa quer mostrar em apresentações como um robô se comporta na Lua em comparação com a Terra, sem que o público técnico na sala possa dizer «isto é só uma animação».

Qué construimos

O modelo do robô é carregado do seu formato real — MJCF, através do carregador escrito por nós, com cada articulação e o respetivo intervalo; no humanoid entram 29 articulações acionadas. A marcha é cinemática inversa com dois segmentos, com fator de apoio 0,6. A gravidade altera os valores nas fórmulas, não a velocidade de uma animação: a altura do salto escala com a razão das gravidades, o período do passo com 2π√(L/g), a autonomia da bateria passa pela redução por temperatura com quatro limiares. O terreno é gerado de forma determinística a partir da semente do planeta — 80 m de lado, amplitude 0,18 m na Terra e 0,58 m na Lua — e traz na cena a marcação `visual_only`, para que ninguém o tome por superfície de colisão. Separadamente do browser corre uma validação numérica em MuJoCo, com passo de 1 ms, que escreve o resultado num relatório JSON versionado, com a fingerprint do modelo.

Qué salió

A cena abre a partir de um link, em oito línguas, incluindo escrita da direita para a esquerda. Cada ação na interface é rotulada com honestidade — hoje, todas como pré-visualização cinemática — e um painel expansível mostra exatamente o que foi verificado numericamente e o que não foi. Quando alguém na sala pergunta «está demonstrado?», a resposta está no ecrã, não no discurso.

Qué no dice el caso

Pressupõe um modelo do robô num formato aberto, com a respetiva licença verificada; uma lista escrita dos valores que devem ser apresentados; e o acordo de que os valores não validados permanecem marcados como tal, incluindo nas apresentações de vendas. Sem o terceiro ponto, o projeto não é este.

Perguntas

Lo que nos pregunta la gente antes de llamar

Em que motor constroem e por que precisamente nesse?

Three.js sobre WebGL, no browser. O motivo é prático: o entregável é um link. Não há instalação, não há loja, não há processo de revisão, e uma correção chega a toda a gente no momento da publicação. Usamo-lo em cinco repositórios — as versões 0.184 e 0.185 — às vezes através de `@react-three/fiber` e `@react-three/drei`, outras vezes escrito diretamente, até ao nível em que gerimos manualmente atributos de buffer. Quatro dos projetos estão públicos agora mesmo, por isso a afirmação pode ser verificada sem nos perguntar.

Podem fazer em Unity ou Unreal?

Fazemos por encomenda, mas a resposta honesta começa de outra forma: não temos nenhum projeto entregue em Unity ou Unreal. Procurámos em todo o código na máquina de trabalho — nenhuma referência a `UnityEngine`, nenhum ficheiro `.uproject`, nenhum `.csproj`, nenhuma macro do Unreal. Os motores nem sequer estão instalados. O que muda na prática se escolher um deles: o entregável deixa de ser um endereço web e passa a ser um build por plataforma; a distribuição passa por loja ou instalador; e os termos de licenciamento são os publicados pela Unity, respetivamente pela Epic, na data do projeto, e verificamo-los nessa altura, não os presumimos. Como procedemos: começamos com um protótipo pago e, se o projeto exigir experiência de motor que não temos internamente, dizemo-lo antes do contrato.

Funciona no telemóvel?

Sim, e é uma decisão tomada na construção, não uma esperança. O shader deste site tem três níveis de qualidade — 24, 40 e 80 iterações — e desce sozinho: no móvel começa no mais leve, e em qualquer dispositivo com 4 núcleos ou menos o nível máximo passa a ser o intermédio. O rácio de pixels é limitado em todo o lado: 0,5 no nível baixo aqui, 1,5 no móvel no demonstrador de mundo, 1,6 e 1,75 nas duas cenas do mapa urbano. Quando o canvas sai do ecrã, o ciclo pára. O que não lhe posso dar: uma cifra de fotogramas por segundo num telemóvel específico — não temos uma medição publicável desse tipo, por isso não inventamos uma.

O jogo abre no browser ou instala-se?

Tudo o que construímos até agora abre no browser. Três dos projetos são builds estáticos servidos por Nginx a partir do nosso servidor; um está no Vercel. Um jogo instalável — desktop, telemóvel ou consola — é uma conversa diferente: pressupõe conta de developer, processo de revisão, classificação etária e, muito provavelmente, outro motor. Nenhum dos nossos projetos é distribuído através de uma loja, por isso esse seria um caminho novo, com os seus passos.

Quem detém o código e os ativos no final?

O código escrito para o seu projeto pertence-lhe, e os termos são escritos no contrato antes de o trabalho começar. Quanto aos ativos, a distinção importa: os gerados a partir de primitivas ou de dados públicos vêm sem restrições adicionais — a máquina do demonstrador de mundo é construída a partir de caixas, cápsulas e cilindros, a cidade na cena urbana é OpenStreetMap sobre Copernicus DEM. Os importados mantêm a sua licença: os robôs Unitree são BSD-3-Clause do MuJoCo Menagerie, com a notificação junto ao modelo. Num projeto com gráficos criados por encomenda, a origem e a propriedade de cada ativo são definidas em lista, ativo por ativo.

O que acontece com o multiplayer?

E a reserva mais honesta que temos. Nenhum dos cinco projetos tem estado partilhado entre jogadores: o jogo de investigação mantém tudo em `localStorage`, a simulação de robôs mantém o estado na memória da página. Um jogo com várias pessoas em simultâneo exige um servidor autoritário de estado, sincronização e tratamento do atraso de rede — peças novas, não uma opção a assinalar. Isso pode ser construído, mas entra no projeto como subsistema separado, com o seu trabalho, não como opção.

Quanto tempo demora até ver algo jogável?

Não lhe dou um número que não possa sustentar. Dou-lhe a ordem: a primeira entrega é um protótipo jogável com a regra correta e o gráfico mínimo, e ele tem de funcionar sem qualquer chave de API — tal como o nosso jogo de investigação é percorrido integralmente por réplicas scriptadas. Só depois de a regra aguentar é que se acrescentam o gráfico, a voz e o modelo. Se um fornecedor lhe promete o prazo antes de ver a regra, promete algo que não mediu.

Quanto consome manter as personagens «vivas», ou seja, no modelo?

O consumo é controlado pelos limites escritos no código, não pela esperança. No jogo de investigação: o histórico enviado ao modelo é cortado às últimas 20 mensagens, a mensagem do jogador a 600 caracteres, a resposta a 400 tokens, e o tempo máximo de espera é 45 segundos. A síntese vocal corta o texto a 900 caracteres. Cada um destes limiares é uma linha que podemos mover em conjunto, com efeito direto na fatura. E continua a existir o modo sem chaves, em que o jogo funciona com réplicas scriptadas e não consome nada.

O que não fazem?

Não sustentamos que uma animação seja física demonstrada. Na simulação de robôs, todas as 15 ações estão marcadas no código como `cinematic`, o painel de provas declara `actionValidation: "none"`, e o verificador de lançamento responde hoje «Release qualification: blocked», porque a resposta de 5 ms do travão da articulação não está calibrada em hardware real. Não entregamos multiplayer como opção escondida. Não nos apresentamos como estúdio de Unity ou Unreal. E não colocamos uma demo na oferta sem dizer se é pública — o nosso jogo de investigação, por exemplo, corre apenas localmente e não tem endereço.

Em que se baseiam as afirmações acima (25 fontes)
  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 delas são código e ficheiros dos nossos repositórios. Não publicamos o nome nem a linha: juntos, numa única página, descreveriam com demasiada precisão como estão construídos sistemas que não são só nossos. Percorremo-los consigo, no repositório, a pedido — a verificação continua possível, só que se faz numa conversa.

O que gostaria que funcionasse melhor?

Conte-nos o seu processo. Em conjunto decidimos o que vale a pena construir, o que podemos ligar e como verificamos o resultado.

Vamos falar