Referência Técnica · versão 2.6.1
Referências técnicas — Jogo do Carrinho
Versão 2.6.1 · para quem vai manter o jogo · manual de quem joga · manual em PDF
Tecnologia
| Base | html5-js: um HTML único com CSS e JavaScript embutidos, script clássico (abre por file://). Sem framework, sem etapa de build. |
|---|---|
| Motor 3D | Three.js r128, cópia local em vendor/three.r128.min.js. sha256 9274bbcec8d96168626c732b5d31c775aa8cfb7eaa0599bec0c175908a2c1ce2. O sha512 é o mesmo SRI que a 1.5.2 usava no cdnjs: conferido nesta geração. |
| Carregador | GLTFLoader do three.js r128 (examples/js), sem alteração. sha256 5c15967ba830918a9caea6338712c994c354bccd4edc4569bde411c3ec06a3e6: igual ao declarado no HTML. |
| Carro | Modelado no Blender (9.454 triângulos). O carro.glb vai embrulhado em base64 em assets/modelo/carro.glb.js (gerado por harness/carro-glb-js.mjs): por file:// o Chromium recusa fetch/XHR de arquivo local. Sem o arquivo, o jogo segue com o carro procedural. |
| Versão | const VERSION = '2.6.1' no HTML, jogos/versao.json e a ficha: as três dizem 2.6.1. |
| Plataformas | desktop, mobile; orientação livre. |
| Rede | Nenhuma carga de host externo (o GATE 1 do deploy barra). Depois de aberto, o jogo pede versao.json; com a Música ligada, também a música-tema (assets/musica/jogo-do-carrinho-tema-intro.m4a e assets/musica/jogo-do-carrinho-tema-laco.m4a), quando o JOGAR fica pronto ou quando a Música é ligada, e só por http(s). |
| Licenças | Código de partida: MIT — Copyright (c) 2026 inteligenciamilgrau (https://github.com/inteligenciamilgrau/jogodocarrinho). Three.js e GLTFLoader: MIT. Arte: gerada por IA na conta OpenArt do produtor (Seedream 5 Pro, Nano Banana Pro). O texto completo das licenças, com os avisos de copyright e de permissão, está em licencas.txt, ao lado do jogo. |
Estrutura de arquivos
No repositório
| Caminho | O que é |
|---|---|
jogos/carrinho_fable_5.html | o jogo, num arquivo (20.342 linhas); publicado como index.html |
jogos/vendor/ | Three.js r128 e GLTFLoader, cópias locais |
jogos/assets/ | capa, cartões, logo, ícones, o carro (carro.glb e carro.glb.js), o trem e a música-tema (musica/: não é MIT) |
NOTICE.md | o que não é MIT no repositório: a música-tema (© MusicPlay.club, usada com permissão) |
jogos/versao.json | a versão publicada, conferida pelo jogo |
jogos/game.yaml | a ficha do jogo (cópia da ficha da run; não vai ao ar) |
jogos/manual.html, tecnico.html, manual-do-usuario.pdf, licencas.txt | a documentação e o texto das licenças MIT (gerados por harness/docs.mjs) |
jogos/carrinho_*.html (outros) | as versões da garagem multi-IA, fora do deploy |
historico/v1/index.html | a 1.5.2 congelada |
harness/ | bench, smoke, teste de atualização, capturas e geração da documentação |
deploy_ftp.mjs | staging, gates e upload FTPS |
servidor_local.mjs | servidor estático para testar por http:// |
og.jpg | a prévia de link |
index.html, capas/, COMO_ADICIONAR_SEU_JOGO.md | a garagem multi-IA (não vai ao ar) |
LICENSE | MIT License — Copyright (c) 2026 inteligenciamilgrau |
O que vai ao ar
Na pasta do jogo no anfitrião, publicada em https://dentistas.com.br/jogos/jogo_do_carrinho/. O deploy só sobe de jogos/vendor/ e jogos/assets/ o que algum HTML cita entre aspas. Tamanhos medidos nesta geração:
| No ar | Vem de | Bytes | gzip -9 | Papel |
|---|---|---|---|---|
index.html | jogos/carrinho_fable_5.html | 1.296.725 | 441.145 | o jogo |
assets/capa/capa-paisagem.webp | jogos/assets/capa/capa-paisagem.webp | 184.298 | — | capa, paisagem |
assets/capa/capa-retrato.webp | jogos/assets/capa/capa-retrato.webp | 182.988 | — | capa, retrato |
assets/cartoes/cartao-circuito.webp | jogos/assets/cartoes/cartao-circuito.webp | 25.488 | — | cartão de modo |
assets/cartoes/cartao-contrarrelogio.webp | jogos/assets/cartoes/cartao-contrarrelogio.webp | 25.458 | — | cartão de modo |
assets/cartoes/cartao-iaia.webp | jogos/assets/cartoes/cartao-iaia.webp | 37.258 | — | cartão de modo |
assets/cartoes/cartao-moedas.webp | jogos/assets/cartoes/cartao-moedas.webp | 25.318 | — | cartão de modo |
assets/favicon/favicon-192.png | jogos/assets/favicon/favicon-192.png | 11.554 | — | ícone 192 px |
assets/favicon/favicon-512.png | jogos/assets/favicon/favicon-512.png | 33.856 | — | ícone 512 px |
assets/favicon/favicon.svg | jogos/assets/favicon/favicon.svg | 1.798 | 839 | ícone |
assets/logo/logo-para-fundo-escuro.svg | jogos/assets/logo/logo-para-fundo-escuro.svg | 9.834 | 1.069 | logo |
assets/modelo/carro.glb.js | jogos/assets/modelo/carro.glb.js | 470.911 | 184.177 | o carro (GLB em base64) |
assets/modelo/trem.glb.js | jogos/assets/modelo/trem.glb.js | 988.037 | 274.256 | |
assets/musica/jogo-do-carrinho-tema-intro.m4a | jogos/assets/musica/jogo-do-carrinho-tema-intro.m4a | 720.242 | — | a música-tema: a introdução (AAC; só com a Música ligada, fora da primeira carga) |
assets/musica/jogo-do-carrinho-tema-laco.m4a | jogos/assets/musica/jogo-do-carrinho-tema-laco.m4a | 1.359.995 | — | a música-tema: o laço (AAC; depois da introdução) |
vendor/GLTFLoader.r128.js | jogos/vendor/GLTFLoader.r128.js | 96.550 | 21.894 | GLTFLoader r128 (MIT) |
vendor/three.r128.min.js | jogos/vendor/three.r128.min.js | 603.445 | 149.563 | Three.js r128 (MIT), também usado pela v1 |
og.jpg | og.jpg | 200.279 | — | prévia de link (1200×630) |
v1/index.html | historico/v1/index.html | 303.952 | 103.114 | a versão 1.5.2 guardada |
v1/favicon.svg | favicon.svg | 224 | 192 | ícone da v1 |
versao.json | jogos/versao.json | 19 | 39 | a versão publicada, lida pelo jogo |
manual.html, tecnico.html, manual-do-usuario.pdf, licencas.txt | jogos/ | gerados junto com esta página | documentação e licenças; o jogo não os carrega | |
Soma do que o jogo usa: 6.578.229 bytes em 21 arquivos (6.578,2 KB), abaixo do teto de 25 MB que o dono fixou para o jogo na 2.1 (13/10/2026; era 5 MB). Primeira carga em paisagem: 12 arquivos, 1.096,5 KB com gzip nos textos.
Seções do código
58 blocos
O script do jogo é dividido em blocos marcados /*==[SEC:NOME]==. A descrição abaixo é a primeira frase do comentário de abertura de cada bloco, como está no código.
| Seção | Linhas | Comentário de abertura |
|---|---|---|
SEC:BENCH | 1608–1685 | Instrumentação de bench e determinismo. |
SEC:COLOR | 1685–1744 | Pipeline de cor. |
SEC:VERSION | 1747–1765 | Fonte única da versão. |
SEC:SKY | 1827–1868 | Paleta do céu, escolhida em cores de tela: o hex é o que se vê. |
SEC:INSTANCING | 2041–2113 | Um draw call por família de objeto em vez de um por objeto. |
SEC:RODOVIA | 2248–2404 | A rede de estradas: o anel interno, como era, e dois ramais (leste e oeste) para a volta externa de ~1,3 km. |
SEC:CRUZAMENTO | 2404–2662 | 2.5.0 (pedido do dono, 18/10/2026): os ENCONTROS dos ramais com as vias principais viram cruzamentos de verdade. |
SEC:FERROVIA | 2662–3163 | 2.1 C (item 2 do pedido do dono): A FERROVIA DE QUALIDADE. |
SEC:PAISAGEM | 3165–3198 | A volta externa atravessa quatro paisagens, e cada uma tem regra própria de floresta, relevo e chão. |
SEC:AGUA_DO_CARRO | 3198–3230 | 2.5.2 (pedido do dono, 18/10/2026): O CARRO NO LAGO AFUNDA um TERÇO DA CARROCERIA. |
SEC:TUNEL | 3598–3838 | A volta externa atravessa a serra por dentro de um monte. |
SEC:RELEVO | 3838–4062 | 2.4 (pedido do dono, 17/10/2026): "implemente ondulações na pista e cenário também, com pequenas subidas e descidas". |
SEC:AFINAR | 4198–4354 | 2.4.1 (pedido do dono, 18/10/2026): "reduzir em um terço o número de árvores, pedras e montanhas, no mapa todo". |
SEC:PRAINHA | 4354–4473 | 2.5.0 (pedido do dono): no lugar das pedras, uma PRAINHA de areia de verdade em volta de cada lago. |
SEC:PISTA_LARGA | 4740–4894 | 2.5.0: a pista 50% mais larga (duas faixas de 3,75 m) com acostamento de terra e cascalho até ±11 m do eixo. 2.5.5: sai toda árvore com a copa a menos de 13 m do eixo de qualquer via (tirarArvoresEncostadas). |
SEC:CENARIO | 4894–5452 | Riqueza de cena (R5). |
SEC:GRAMADO | 5454–5679 | 2.1 C (item 1 do pedido do dono): o GRAMADO COM TEXTURA E MOITAS DE CAPIM. |
SEC:LADEIRA | 6263–6280 | 2.4.1 (pedido do dono): "a ladeira afeta o carro: subindo, a velocidade diminui levemente; descendo, aumenta levemente; no plano, normal. |
SEC:MOEDAS_251 | 6456–6516 | 2.5.1: os valores das moedas à metade, a moeda grande com halo e as fileiras do acostamento. A meta foi a 75 na 2.5.1 e é 100 desde a 2.5.5 (WIN_SCORE; recorde em recorde.moedas3). |
SEC:GEMAS | 6516–6671 | Prêmios únicos nas paisagens distantes: 2 diamantes de 25 pontos em pontas opostas do mapa e 5 rubis de 10. |
SEC:TRILHA | 6673–6900 | 2.5.1 (pedido do dono, 18/10/2026; a arte do cartão da Caça às Moedas): uma FILEIRA DE MOEDAS NO ACOSTAMENTO, 1 ponto cada. |
SEC:SENSOR | 7775–8773 | Raycast 2D analítico (raio x círculo). |
SEC:SHOTS | 8773–8910 | Poses canônicas de câmera para captura comparável entre versões. |
SEC:BENCH_API | 8910–8983 | Superfície que o harness consome. |
SEC:SHADOW_RULES | 8985–9006 | Quem projeta e quem recebe sombra, decidido por regra numa única traversal em vez de editar ~950 sítios de criação. |
SEC:CENARIO | 9008–9028 | Correção das exceções de sombra do cenário novo. |
SEC:SKY | 9030–9413 | Céu procedural + iluminação ambiente (IBL). |
SEC:POST | 9415–9857 | Pós-processamento: composer escrito a mão. |
SEC:CICLO | 9859–10378 | O ciclo do dia (2.1): relógio de jogo e céu por chaves de cor, 240 s. Desde a 2.5.5 a noite fechada dura dois terços (horaDe254 leva as horas da 2.5.4), e o dia ganha o tempo. |
SEC:CHUVA | 10380–10642 | Uma pancada de chuva por corrida, no mapa inteiro, sorteada na largada. Desde a 2.5.5 ela dura um terço (CHUVA_TEMPO: de 7,3 a 10,7 s), com a frente de nuvens, o molhado e as poças na mesma proporção. |
SEC:PISTA | 10644–11294 | Circuito e Contrarrelógio (P3): a mesma pista, os mesmos 12 portais e a mesma regra de volta. |
SEC:CARRO_GLB | 11296–11964 | O carro da folha, modelado no Blender (P6 da 2.0), no lugar do caixote. |
SEC:INSTANCING | 11966–11981 | Pré-compilação dos shaders. |
SEC:TIERS | 11983–12255 | Tiers adaptativos. |
SEC:REPOUSO | 12257–12299 | O 3D não é desenhado quando ninguém o vê. |
SEC:PIP | 12301–12386 | A janela "Visão da IA" (2.1, pacote A): só no computador e a 15 Hz. |
SEC:CAMERAS_B | 12388–12782 | 2.1, pacote B — as câmeras novas. |
SEC:CAMERAS_252 | 12784–12803 | 2.5.2: quatro câmeras de jogo, todas com zoom (teclas 1 a 4; C passa para a próxima; a escolhida fica no aparelho). Desde a 2.6.0, os botões 1 2 3 4 da tela (o seletor de view, SEC:VISTAS) no lugar do botão de câmera do celular, e o zoom sem os botões − e + (as teclas, a rodinha e a pinça). |
SEC:CAMERA_PERTO | 12803–12854 | 2.5.3: a câmera normal mais perto do carro (pose escalada por PERTO.k = 0,72) e andando com ele (levarComOCarro), sem o recuo pela velocidade; por cima da copa no monte (erguerDaCopa); o drone mais perto. |
SEC:MOLHADO | 12967–13452 | 2.1, pacote B — a chuva que chega a todos e a pista molhada (decisão 6 do dono; plano 4.5). |
SEC:ESTEIRA | 13454–13872 | 2.3.3 — a esteira do carro na água (pedido do dono, 16/10/2026: "quando o carrinho anda na água ele não movimenta a água, o que e irreal"). |
SEC:REGRAS_D | 13874–14241 | 2.1, pacote D — "regras e sensação" (decisões 1 a 3 do dono, 13/10/2026; correções C1-C15 e as omissões do plano). |
SEC:FAISCAS | 14241–14406 | 2.5.1 (pedido do dono: "faíscas realistas e diferentes"): as faíscas deixam de ser dois punhados iguais (ouro na coleta, metal na batida) e passam a ter TIPO. |
SEC:ESBARRAO | 14407–14882 | 2.3 (item 6). |
SEC:VOO | 14882–14956 | 2.5.1: o "+N" que sobe. |
SEC:MOVIMENTO | 15356–15368 | prefers-reduced-motion. |
SEC:ATUALIZACAO | 15370–15414 | Atualização automática (Kit, item 13). |
SEC:TOQUE | 15416–15569 | Controles de toque (P4): o jogo inteiro se joga com o polegar, em pé ou deitado. |
SEC:CAPA | 15571–16011 | A primeira página (Kit, item 3). |
SEC:CINEMA | 16013–17235 | 2.2 "Transmissão" — o modo ASSISTIR: IA x IA, o DIRETOR DE CÂMERA e a CAPA VIVA (plano, seção 7). |
SEC:TEMA | 17237–17502 | 2.5.9: a música-tema na capa e na demo (Jogo do Carrinho (Tema), MusicPlay.club, criada com Suno), em dois arquivos (a introdução e o laço), baixados só com a Música ligada e decodificados um de cada vez depois do primeiro gesto; a introdução passa ao laço no instante exato e sai da memória; o laço sem emenda num AudioBufferSourceNode (loopStart 43,811 s, loopEnd 127,126 s da música; o arquivo costurado no fim); continua na demo; ao jogar e ao voltar ao menu, crossfade de 0,5 s com a trilha procedural (temaDaHora, tocarTema, juntarNoLaco, soltarTema, chipEntra, chipSai). Sem os arquivos, a trilha procedural de sempre. 2.6.0: a rede lenta (prazos de 25 e 60 s, a trilha procedural enquanto o Tema chega e o laço atrasado: esperandoOTema, trilhaNaEspera, esperarOLaco, posAoEntrar). |
SEC:TURBO | 17504–18099 | 2.3 — o TURBO e as duas vistas aéreas que a pessoa move (pedido do dono de 15/10/2026). |
SEC:JATO | 18101–19030 | O salto a jato (2.5.2) e o salto Tesla (2.5.4): o normal sobe 5,5 m e passa por cima do trem; com a seta, o lateral sobe 7,5 m, gira 360° e pousa 9 m ao lado (de 2.5.4 a 2.5.6 em câmera lenta e com zoom; desde a 2.5.7 em velocidade normal: a câmera lenta é do REPLAY); os 14 jatos são de ar comprimido (BOCAIS_LAT, VAPOR). 2.5.5: os acertos da revisão (o caminho do lateral, a árvore no ar, os portais, o custo do vapor, o farol no giro). |
SEC:REPLAY | 19032–19491 | 2.5.7: o REPLAY do último salto lateral. O desenho da tela grava o filme (0,3 s antes até 0,5 s depois do pouso: os carros, a câmera, o trem, o vapor, as partículas e os sons); o botão REPLAY (ou R) pausa a partida e mostra o filme em câmera lenta (escalaDoVoo, o som lento da 2.5.4) em 3 visões no mesmo renderer, por viewport e tesoura: Normal, Motorista e De cima. Fechar devolve tudo (guardarCena, devolverCena). |
SEC:VISTAS | 19493–19548 | 2.6.0: o seletor de view (os botões 1 2 3 4 das câmeras, o da tela aceso) e o zoom sem os botões − e +: as teclas, a rodinha do mouse e a pinça de dois dedos. |
SEC:VOLUME | 19550–19620 | 2.6.0: o volume num modal aberto pelo alto-falante da partida (ou pela tecla E): o liga/desliga geral, Música e Efeitos; congela a corrida sem o painel de Pausa e sem calar a música. |
SEC:ROTEIRO | 19622–20177 | 2.6.0: a demo da capa como o vídeo — a história contada uma vez (corrida, salto sobre o trem, a Vermelha, salto lateral, 3,5 s do replay, a câmera na pose da capa e o morph para a arte) e o menu de volta, esperando; o botão Preview real; toque, clique, tecla ou rodinha interrompem. |
SEC:TRILHOS_SOM | 20179–20330 | 2.5.3: o som das rodas nos trilhos e dormentes da ferrovia (viaNoPonto, eventosDaVia, vozDaVia), todo em WebAudio, no ritmo da velocidade. |
Funções principais
Novas na 2.0
| função / seção | responsabilidade |
|---|---|
MODOS[modo].{iniciar,atualizar,fim,hud} | regra de cada modo; startGame(m)/endGame só despacham |
iniciarPelaCapa, mostrarCapa, filtrarFoco | entrada da partida e foco (sem o blur global) |
SEC:REPOUSO | não desenha o 3D atrás da capa/pausa |
SEC:ATUALIZACAO | versao.json ao abrir, ao voltar à aba e a cada 15 min; 1 tentativa por versão e aba |
CONTEUDO + geradores do painel | uma fonte para o painel Conteúdo e os cartões |
SEC:PISTA (alvoNaPista, portais, voltas, parciais, recordes) | Circuito e Contrarrelógio |
SEC:CARRO_GLB | carga única do GLB, clones, rodas, luzes, fallback |
SEC:TOQUE (ativarNoToque) | controles de toque por pointerId |
passosDoAquecimento, compilarAosPoucos | pré-compila as variantes de qualidade na capa |
Novas ou mudadas depois do QA, da 2.0.1 à 2.6.1
| função | responsabilidade |
|---|---|
marcarJogar, enfileirarLargada, liberarJogar, prepararCapa (roda a cada quadro: ordem 91 do registro SYS), darPasso | o PREPARO DA CAPA: estado do JOGAR, a fila da largada, a máquina de fases (sinal → passos → pronto) |
passosDoAquecimento, compilarAosPoucos, noEstado, temLuz | o aquecimento em passos: cada estado de qualidade compilado um filho da cena por vez, até 40 ms por quadro |
iniciarPelaCapa / largarDaCapa | a largada pela capa, agora com a fila do preparo |
colisaoMutua, explodeCar(c, adiarFim), textoDoFimMoedas, fimMoedas | RC-5: o choque que zera os dois decide pelo placar; o Empate |
mapCar | RC-4: seta (você) e losango (IA) |
store.set (devolve se gravou), resultadoDaPista | A2: o selo só comemora o que ficou gravado |
deploy_ftp.mjs: cargasAbsolutas, conferirCargas, V1_TROCAS | RC-1: o GATE 1 em todo HTML do staging e a v1 com o Three.js local |
pegadaSobreposta, raioNaPegada, empurrarCarros(a, b, s) | 2.0.1: no Circuito o encosto carro × carro pela pegada retangular do carro (eixos separadores), não mais pelo círculo de 3,8 m; desde a 2.1.0 a Caça às Moedas usa a mesma pegada (a batida que amassa) |
lanternaDoFreio, lanternaDe, curvaDaNoite (roda a cada quadro: ordem 13 do registro SYS) | 2.0.1: sem o pós, a faixa da lanterna cresce ao frear; o brilho noturno da pintura só acende com a noite fechada |
horaDoCiclo (roda a cada quadro: ordem 5 do registro SYS), aguaDaHora, gramaDaHora (SYS 5.1) | 2.1.0: o relógio de jogo e o ciclo de 4 min, que para na pausa; a água e a grama de cada hora. 2.5.0: o amanhecer e o anoitecer pela metade (o dia e a noite ganham o tempo); 2.5.2: toda partida larga no início do entardecer |
farolDaNoite, FAROL | 2.1.0: os faróis acendem na noite, nos dois carros, com o cone de luz no chão |
camPerseguicao, querFrente, andarGiro, camAerea, camPiloto, camDrone, entrarNaFoto, sairDaFoto, updateCamera | 2.1.0: a câmera mostra a frente do carro na ré (giro com velocidade e aceleração limitadas; corte seco com reduced-motion). 2.5.2: quatro câmeras (normal, piloto, drone e do alto), todas com zoom, e o modo foto na tecla F |
pocaEm (SYS 6 e 6.2) | 2.1.0: a chuva no mapa inteiro, a pista molhada que derrapa e as poças depois dela (até 5 s na 2.1.0; desde a 2.5.5, ~1,7 s, com a chuva a 1/3) |
vestirMonte, malhaDoMonte, pintarOMonte, arvoresDoMonte, alturaDoMonte | 2.5.0: o túnel da serra com 200 m, acompanhando a curva, dentro de um monte gramado (mesma cor do campo, árvores por cima) em que o carro pode subir e passar por cima |
encontroNasMoedas, baterCarros, amassar, amassarLataria, restaurarLataria, quebrar, passarBatida | 2.1.0: a batida carro × carro na Caça às Moedas sem explosão: a 1ª amassa os dois, a 2ª quebra os dois (fumaça, −1 vida, 2 s parados) |
pontuarMoeda, surgirDiamante (SYS 16.5), revelarDiamante, alvoNasMoedas, disputavel | 2.1.0, valores da 2.5.1: a economia da Caça às Moedas (meta 75 na 2.5.1, 100 desde a 2.5.5; moeda 1, sequência ×2, roubo ×4 só na moeda solta; punhado 5; rubi 5; diamante 13, um de cada vez depois dos 30 pontos) |
drawGauge, sentirVelocidade, linhasDeVento | 2.1.0: o velocímetro em km/h reais (32 m/s = 115 km/h), o FOV e as linhas de vento perto da máxima |
apontar, lugarDaSeta, pontoNaBorda, medirHud (roda a cada quadro: ordem 28 do registro SYS) | 2.1.0: as setas na borda para a gema e a moeda fora da tela, sem cobrir HUD, controles nem carros; sem lugar, um ponto de 16 px na borda |
soltarFumaca, moverFumaca, veuDaFumaca, lancarEstrela, voarPontos, ondeNaoVoar | 2.1.0: a fumaça da quebra (que some na linha entre a câmera e o seu carro) e a estrela cadente que vira moeda (8 pontos na 2.5.1); 2.5.1: o “+N” de cada coleta na cor do tipo, que sobe e some em 2 s |
segurarTurbo, soltarTurbo, soltarTodoTurbo, acenderTurbo, apagarTurbo, passarTurbo, turboEmpurrao, turboDaIA, turboNoHud, soltarChama, sfxTurbo, vozDoTurbo | 2.3.0, tanque de segundos desde a 2.4.0: o TURBO (SEC:TURBO) na Caça às Moedas, no Circuito e no IA × IA. A largada dá 10 s; segurar o Espaço ou o botão TURBO queima o tanque em frações e soltar para (tecla solta, dedo fora, janela sem foco, pausa e fim da partida soltam). Enquanto queima: o empurrão e o teto 8 m/s mais alto, a chama nos escapamentos e o som contínuo. O botão mostra a barra com os segundos. A IA acende só na reta e sorteia quanto tempo segura, com gerador próprio |
itensNaLargada, pegarItens, desenharItens, itensNoMapa | 2.3.0, recarga em segundos desde a 2.4.0: o item TURBO dentro do túnel soma 10 s até o teto de 30 s, uma recarga por passagem (o 2º item da mesma passagem fica para o rival), volta 20 s depois e aparece no minimapa |
zoomDoJogo, zoomPeloGesto, PINCA, zoomDaTransmissao, mexeuNaVista, soltarVista, teclaDaVista | 2.3.0: o pan/zoom da aérea da transmissão (setas, arrasto, + e −), com o diretor esperando 5 s depois do último gesto; 2.5.2: o zoom + e − em todas as câmeras do jogo; 2.6.0 (pedido do dono): os botões − e + da margem direita saíram, e o zoom ganhou a rodinha do mouse e a pinça de dois dedos sobre a cena (SEC:VISTAS) |
vestirMonte, corDaFace, caberNoPe | 2.3.0: as montanhas redesenhadas (maciço côncavo, esporões, neve nos corredores, o pé no raio de sempre) e a névoa de distância só da rocha (SYS 6.6) |
carimbarPoca, vizinhasDaPoca, secarOTunel, criarPocas (SYS 6.2) | 2.4.1: as poças nascem pequenas e crescem pela chuva toda (as vizinhas se juntam), secam depois (desde a 2.5.5, na proporção da chuva a 1/3: enchem em 8 s e secam em 6 s), e nunca debaixo do teto do túnel |
ladeiraDoCarro, cargaDoMotor, ventoDaDescida (SYS 14.6) | 2.4.1: a ladeira sentida (SEC:LADEIRA): subindo o carro avança um pouco menos e o motor ronca mais grave; descendo avança um pouco mais, o motor alivia e entra o vento (jogador e IA) |
afinarLista, afinarPorArea, montesRedundantes | 2.4.1 e 2.5.0: menos árvores (75% das da 2.4) e as montanhas só ao fundo (SEC:AFINAR), escolhido depois do sorteio do mundo |
asfaltoDaHora | 2.4.1: o asfalto mais escuro de dia, meio-termo no poente, intacto à noite |
faiscasDoContato, trancoDoEsbarrao, sfxEsbarrao, rasparCarros | 2.3.0: as batidas simples (o esbarrão de lado e a batida por trás que não quebram): faíscas no ponto do contato, tranco visual, baque e raspa; a física não muda |
carregarTremGLB, vestirTrem, trocarTremQuandoPuder | 2.3.0: a locomotiva a vapor do Blender (trem.glb.js): troca só a geometria, nunca no meio da corrida (fica na fila até o menu); se falhar, segue a locomotiva de cabine |
alturaDoAviso, alturaDoFeed | 2.3.0: o feed e o aviso medem a altura real um do outro, para nunca se cobrirem nas telas estreitas |
vestirPersonalidades, velocidadePlanejada, alvoComPersonalidade, disputaPers | 2.2.0: as personalidades do IA × IA (Verde Ousada, Vermelha Calculista) por envelope de planSpeed, pathLookahead e alvoNasMoedas; sem personalidade, os três modos usam a função de sempre |
iniciarIaIa, hudIaIa, fimIaIa, mostrarResultadoIaIa, rotulosDoModo | 2.2.0: o 4º modo, Assistir: IA × IA (a Caça às Moedas inteira entre duas IAs, sem recorde), com ASSISTIR, Assistir de novo e Voltar |
eventoCine, novoPlano, montarDrone, montarClose, cortar | 2.2.0: o diretor de câmera: planos de perseguição baixa, beira da estrada, trilho lateral, drone, close com câmera lenta, aérea e ambientação; corta no evento ou no fim do plano, na reta, sem repetir o plano |
mostrarControles, marcarControles, escolherCamera, placarDaTV | 2.2.0: os controles ao vivo (1/2/3/4, 1×/2×/4×, Voltar) e a faixa VERDE × VERMELHA da transmissão |
ligarCapaViva, CAPA_VIVA_ESPERA_S, recolherSePreciso, cutucarCapa, engolirClique | 2.2.0: a capa viva: a transmissão roda atrás da capa (até a 2.5.5 só com a música; de 2.5.6 a 2.5.8, só com os efeitos; desde a 2.5.9, com a música-tema da capa, que continua sem recomeçar, e os efeitos por baixo: ver o som da demo e SEC:TEMA); 4 s sem gesto recolhem os painéis (eram 20 s até o pedido do dono de 15/10/2026), e o primeiro toque só os devolve. 2.6.0 (pedido do dono): ela conta UMA vez a história do vídeo e para (SEC:ROTEIRO); com a história no ar, o toque, o clique, a tecla e a rodinha a interrompem (o mouse que só passa, não), e ela não recomeça sozinha (ROTEIRO.visto). 2.5.8 (pedido do dono): ela entra 6 s depois de poder entrar (o JOGAR pronto na primeira carga, o menu de volta depois de uma partida); até a 2.5.7 entrava na hora |
SOM_DA_DEMO, somDaDemo, capaCalada, temaNaDemo, ouveDemo, volumesDaDemo, alternarSomDaDemo, marcarBotaoDaDemo, noBotaoDaDemo | 2.5.6 (SEC:CINEMA 11, pedido do dono): o som da demo. Na capa viva a música vai a zero e os efeitos da partida dela tocam a 50% do volume de Efeitos (SOM_DA_DEMO.FATOR), respeitando o mudo; os sons que a capa calava por código perguntam a capaCalada(). O alto-falante #btnSomDemo liga e desliga esse som sem devolver o menu (cutucarCapa o ignora) e guarda a escolha em carSim3d.som.demo; com os Efeitos mudos, ligar o som da demo liga os Efeitos. Ao sair da capa viva, applyVolumes devolve a música e os efeitos do jogador. 2.5.9 (pedido do dono): a música não zera mais na demo — o Tema (SEC:TEMA) continua no volume de Música; o alto-falante é o som da demo inteiro (cala e libera o Tema junto com os efeitos; mostra ligado quando algo soa, temaNaDemo); ligar o som da demo liga também a Música; o Som da capa ligado libera a demo. Sem o Tema (file:// ou falha), a demo fica sem música, como na 2.5.6 |
estudioDaHora (SYS 13.5) | 2.2.0: o carro de miniatura de coleção: o reflexo de estúdio e a luz neutra que acompanham a hora do dia |
anelDaPrainha, largurasDaPrainha, naPrainha, montarPinturaDosCruzamentos | 2.5.0: a prainha de areia em volta dos lagos e a pintura dos cruzamentos (faixa contínua na principal, faixas de redução e a linha de PARE no ramal) |
vestirMoeda, animarFachos, sortearTrilhas, assentarTrecho, pegarNaTrilha, pontuarTrilha | 2.5.1: a moeda grande com halo e facho (10 pontos, uma por vez), o facho do punhado que pisca ao surgir e as fileiras de moedas no acostamento (1 cada) |
faiscarColeta, faiscasDoContato, trancoDoEsbarrao | 2.5.1: faíscas por tipo (estrela dourada na moeda, chuva dourada no punhado e na moeda grande, a cor da gema, metal que quica e esfria na batida entre os carros) |
alternarJanelaDaIA, proximaCamera, cameraGuardada, olhoDoPilotoAgora, olhoAcimaDaAgua | 2.5.2: a janela da visão da IA na tecla V, a tecla C passando pelas quatro câmeras (o botão do celular que fazia o mesmo virou, na 2.6.0, o seletor de view: SEC:VISTAS), a câmera guardada no aparelho e nenhuma câmera debaixo d’água |
acionarJato, decolar, jatoVale, passarSalto, segurarNoAr, jatoNoHud, jatoNaAgua | 2.5.2: o salto a jato (4 por partida, na Caça às Moedas e no Circuito; não no túnel; sobre o lago até a outra margem) e o botão JATO com as cargas. Desde a 2.5.4, o salto sobe 5,5 m na velocidade e no rumo da hora do botão (ver as linhas do salto Tesla). 2.6.0: a decolagem em si saiu do acionarJato para decolar (sem as condições da partida e sem gastar carga), que a demo da capa também usa |
alturaNaAgua, espumaDoCasco, dentroDeLago | 2.5.2: o carro afunda um terço no lago, com espuma em volta do casco (jogador e IA) |
lerGlbDoTrem, vestirPecaMovel, girarRodasDoTrem | 2.5.3: as rodas da locomotiva e do tênder (nós-filhos do trem.glb) giram com a velocidade do trem, e as bielas acompanham |
levarComOCarro, erguerDaCopa, desfazerErguida, alturaQueTira, PERTO, DRONE_POSE | 2.5.3 (SEC:CÂMERA_PERTO, pedido do dono): a câmera normal mais perto (a pose de sempre escalada por 0,72 em volta do ponto que ela olha: o carro no mesmo lugar da tela, 1,39× maior), andando com o carro (85 % do passo do quadro, sem o recuo que crescia com a velocidade) e passando por cima da copa no monte; o drone mais perto (13,5 m atrás, 8,6 m de altura) e com menos atraso |
viaNoPonto, eventosDaVia, dormentesCruzados, trilhosCruzados, amostrasDaVia, vozDaVia, nivelDaVia, tocarNaVia, calarVia (SYS 15.62) | 2.5.3 (SEC:TRILHOS_SOM, pedido do dono): o som das rodas nos trilhos e dormentes da ferrovia: cada dormente cruzado dá o par “ta-dum” (eixo da frente e de trás), cada junta um baque e cada trilho cruzado de lado um estalo metálico, no ritmo da velocidade, com o ronco da brita por baixo; tudo WebAudio sintetizado (sem arquivo e sem o rnd()), pelo volume de Efeitos; calado parado, no ar, fora da partida e na pausa |
ladoDaSeta, ladoQueCabe, trajetoLateral, alturaLateral, passarLateral, encerrarSalto, LATERAL | 2.5.4 (SEC:JATO, o salto Tesla, pedido do dono): o salto lateral com J e a seta segurada (no toque, a seta e o JATO): sobe 7,5 m, gira 360° para o lado da seta em volta do meio da carroceria e pousa 9 m ao lado, na velocidade e no rumo de antes. O caminho inteiro é simulado antes de sair: árvore mais alta que o carro, montanha, túnel ou limite do mundo encurtam o deslocamento de 1,5 em 1,5 m até 3 m; sem espaço, o salto é recusado sem gastar a carga |
topoDoObstaculo, topoDoTrem, fundoDoCarro, porCimaDe, porCimaDoObstaculo, porCimaDoTrem | 2.5.4: a colisão pela altura nos dois saltos: no ar o carro passa por cima do que é mais baixo que o fundo dele, com folga de 0,25 m (o trem pelo topo medido do trem.glb, as árvores pelo topo da copa, as pedras); montanhas, paredes e pilares do túnel continuam batendo |
TEMPO, lentoDoSalto, escalaDoVoo, zoomDoSalto, busLento, somDoTempo, sfxCameraLenta | 2.5.4: a câmera lenta do salto lateral (a curva desce a 0,35 na decolagem e volta a 1 exatamente no pouso; 0,6 com “reduzir movimento”), o zoom de até 22% e o som que passa por uma linha de atraso, baixando o tom e o andamento juntos, com o whoosh. De 2.5.4 a 2.5.6 ela valia para o jogo inteiro (TEMPO.escala no dt da fonte, e o cronômetro da Caça às Moedas descontava); desde a 2.5.7 o lateral é em velocidade normal na partida e a curva, o zoom e o som lento são do Replay (TEMPO.escala é a do filme) |
REPLAY, gravarQuadro, comecarFilme, fecharFilme, abrirReplay, fecharReplay, repetirReplay, quadroDoReplay, desenharVisao, visaoNormal, visaoMotorista, visaoDeCima, guardarCena, devolverCena | 2.5.7 (SEC:REPLAY, pedido do dono): o Replay do último salto lateral. O envelope de renderer.render grava, a cada quadro desenhado, os carros, a câmera, o trem, o vapor e as partículas dos jatos e os sons do salto, de 0,3 s antes da decolagem até 0,5 s depois do pouso. O botão REPLAY (acima do JATO por ~8 s; tecla R) e o “Replay do salto lateral” do resultado pausam a partida (setPaused) e mostram o filme em câmera lenta, com o som lento, em 3 visões desenhadas no mesmo renderer por viewport e tesoura (Normal, Motorista e De cima; nenhum programa novo). Repetir e Voltar ao jogo (Esc, P, toque fora); fechar devolve o que o replay mexeu e o jogo segue idêntico. 2.5.8: a visão De cima mira 75% da altura do salto (SOBE_CIMA), e o carro não encosta mais na borda de cima no pico |
ROTEIRO, comecarRoteiro, passoDoRoteiro (SYS 93.5), passoDaHistoria, semDegrausNaDemo, CENAS_DO_ROTEIRO, irParaCena, proximaCena, passarMergulho, encerrarRoteiro, interromperRoteiro, limparRoteiro, recolherAgora, iniciarPreview | 2.6.0 (pedido do dono): a demo da capa como o vídeo — a história contada uma vez com o menu recolhido (corrida, trem, corrida B, lateral, replay, fim e morph), com mergulhos no preto de 0,15 + 0,15 s entre a corrida e as cenas roteirizadas; o botão Preview real a pede na hora (ROTEIRO.pedido); acabada ou interrompida, ela devolve o menu e espera (ROTEIRO.visto, zerado na próxima largada). 2.6.1 (revisão da 2.6.0): os degraus de qualidade só descem na sessão, e a demo não os alimenta no computador (a história inteira fica fora da janela de medida); no celular ela é medida, menos o replay e as trocas de cena, para o aparelho fraco se adaptar já na demo |
montarCenaDoTrem, corredorLivre, passoTrem, camDoTrem, montarCenaLateral, lugarDoLateral, passoLateral, camDaVerde, abrirReplayDaDemo, fecharReplayDaDemo, carroProntoParaACena, iaForaDaCena, vigiarIA, calarLetreiro | 2.6.0: as cenas roteirizadas (as do vídeo: saltos.mjs da run 2.5.7). O trem: o corredor livre com o sol de lado-frente (72 rumos), o trem posto para o último vagão passar embaixo do carro, o salto normal 1,4 s depois e a câmera "Perseguição baixa" que não entra no leito; o lateral: a reta mais plana e reta da volta externa, o carro parando na faixa da direita e o salto para a esquerda com o filme do replay; o replay: 3,5 s das 3 visões sem barra nem botões e sem som lento; a Vermelha longe do lance (e parada se chegar perto) |
ARTE_CARRO, POSE_CAPA, caixaDaArte, poseDaCapa, caixaDoCarro, resolverPose, prepararPoseDaCapa, camDaCapa, montarFinal, montarMorph | 2.6.0: o fim da demo. A caixa do carro desenhado na arte da capa levada à tela pelo object-fit cover (paisagem ou retrato), a câmera resolvida como no vídeo (a distância que dá a largura e o deslocamento da lente com setViewOffset), a órbita de 24° descendo a 0,5 da altura e o morph: a arte por cima em 2 s, o clarão verde (#capaBrilho) e a arte de 1,03 para 1 |
marcarCamSel, #camSel | 2.6.0 (pedido do dono): o seletor de view — os botões 1 2 3 4 na tela, as mesmas câmeras das teclas, o da câmera da tela aceso (SEC:VISTAS) |
VOLUME, abrirVolume, fecharVolume, aoFecharVolume, teclasDoVolume, toqueForaDoVolume, bipDoVolume, volumeAberto | 2.6.0 (pedido do dono): o volume num modal (<dialog>) aberto pelo alto-falante da partida ou pela tecla E — o liga/desliga geral, a Música e os Efeitos; congela a corrida pela pausa de sempre, sem o painel de Pausa e sem calar a música; fecha com o X, Esc, E ou o toque fora (SEC:VOLUME); o toque fora só vale 500 ms depois de abrir, para o duplo clique no alto-falante não abrir e fechar (2.6.1) |
TEMA, baixarTema, baixarParte, decodificarParte, decodificarNaHora, temaFalhou, tocarTema, armarLaco, juntarNoLaco, soltarIntroducao, soltarTema, pararTema, temaDaHora (SYS 99.6), telaDoTema, temaQuer, estadoDoTema, chipEntra, chipSai, ganhoDaMusica, posicaoDoTema | 2.5.9 (SEC:TEMA, pedido do dono): a música-tema na capa e na demo (Jogo do Carrinho (Tema), MusicPlay.club, criada com Suno), em dois arquivos: assets/musica/jogo-do-carrinho-tema-intro.m4a e -laco.m4a, pedidos só com a Música ligada (o JOGAR pronto ou a Música ligada; prazo de 8 s e 30 s) e decodificados um de cada vez depois do primeiro gesto; a introdução passa ao laço no instante exato, em crossfade de 0,1 s entre sinais iguais, e sai da memória; o laço sem emenda num AudioBufferSourceNode (loopStart 43,811 s, loopEnd 127,126 s da música; o arquivo costurado no fim); uma fonte só, que continua ao entrar e sair da demo; startMusic e stopMusic passam por um envelope que escolhe a música da tela (na capa, o Tema; fora dela, a trilha procedural, com ganho próprio, audio.chipGain, e fim de fade, audio.chipFim); ao jogar e ao voltar ao menu, crossfade de 0,5 s; desligar a Música é um fade de 0,3 s (ganhoDaMusica). Sem os arquivos, a trilha procedural de sempre |
rotaDaFileira, rotaParaOAlvo, sentidoDaFileira, freioDoAlvo | 2.5.9 (pedido do dono: na demo o carro passava devagar pela fileira de moedas): com o alvo numa moeda da fileira do acostamento, a rota da IA é a própria fileira (o A* só até a primeira moeda, quando ela está longe ou fora da frente do carro), no sentido em que o carro anda, até o fim do trecho mais 6 m; antes, cada moeda pega recomeçava o A* do centro da célula de 4 m e a rota fazia uma quina a cada moeda. Na ponta da fileira, chegando por ela, a rota é só a ponta e o prolongamento no rumo do carro (sentidoDaFileira). Junto, no freioDoAlvo, a “moeda com parede logo atrás” só freia com parede de verdade (um raio que bateu): o raio livre devolve o próprio comprimento, que encolhe com a velocidade, e a IA freava a 4–5 m/s a cada moeda. Medido no IA × IA: na fileira, de 4,9 para 17,2 m/s de média e de 852 para 233 ms entre moedas; o Circuito igual |
IA_FILEIRA, moedaPassou, pertoDoTrecho, trechoLargado, IA_CURVA, vDaCurva, largarOAlvo (e, em IA_DESTRAVA, o laço largo) | 2.5.9 (revisão: a IA rápida errava uma moeda da fileira e voltava em laços de 10–20 m de raio): perto da fileira, a moeda que ficou para trás ou de lado (fora de 60° do rumo) não é alvo, e a IA segue para a próxima à frente; mirando uma fileira que ficou toda para trás, larga o trecho por 4 s. O alvo dentro do círculo de giro (raio v/2,3 acima de 9 m/s) freia até a velocidade em que a curva o alcança (vDaCurva; com o alvo à frente não freia, e no Circuito nunca). E o laço largo: mais de 6 s a menos de 25 m do mesmo alvo sem pegá-lo, a IA desiste dele (a fileira inteira, por 8 s) e conta uma órbita. Medido (o script do revisor): a maior sequência com o alvo na fileira caiu de 119,6 s para 15,4 s em 39 partidas de IA × IA, e de 93,8 s para 17,5 s nas sessões de 10 min da demo |
BOCAIS_LAT, rajadasDoSalto, forcaDeBaixo, soltarJatos, colunasDeVapor, bocaisLaterais, nuvemDeVapor, moverVapor, VAPOR, sfxJato, sfxPuff | 2.5.4: os 14 jatos de ar comprimido (sem fogo): as 4 colunas brancas de baixo, junto das rodas (subida e amortecimento do pouso), e as rajadas curtas dos 10 bocais laterais (no lateral, empurrar, girar e nivelar), o vapor que fica no ar e a nuvem no chão; o som de ar com um “tss” por rajada |
chaoSemDegrau, tremNoCaminho, travarLateral, baterNoAr, saltoForaDosPortais, coneNoGiro, tetoNoSalto, subirAsVivas | 2.5.5 (os acertos da revisão da 2.5.4): o caminho do lateral confere o chão a cada 0,5 m (de cima do monte, nada além do parapeito) e o trem na hora de cada ponto; no voo, o passo de lado que cairia da beira trava; a árvore que bate no ar para o carro, sem ré; perto de um portal a altura do voo se afasta da faixa; o cone do farol apaga no giro; o volume geral cede só o necessário no pico da decolagem e do pouso; o vapor num pool único, com só as bolhas vivas subindo para a GPU (metade no celular) |
CHUVA_TEMPO, FRENTE_CHUVA | 2.5.5 (pedido do dono): a pancada de chuva com 1/3 da duração (7,3 a 10,7 s), com as rampas, a frente de nuvens (~6,7 s antes), o molhado e as poças na mesma proporção; a hora da pancada não muda |
horaDe254, PARTES_DO_DIA, HORA_DA_LARGADA | 2.5.5 (pedido do dono): a noite fechada com 2/3 da duração (59,75 → 39,83 s); o ciclo segue com 240 s e o tempo vai para a manhã e a tarde; cada hora escrita na 2.5.4 passa pela conversão (céu, sol, lua, partes do dia, poente e alvorada) |
tirarArvoresEncostadas, distViaExata, malhasDaFloresta, OBSTACULOS_DO_SORTEIO | 2.5.5 (pedido do dono): sai toda árvore cuja copa chegue a menos de 13 m do eixo de qualquer via (2 m além do acostamento), depois de todos os sorteios: o rnd() do mundo não muda, e as moedas e gemas continuam sorteadas no mundo de antes |
WIN_SCORE, CHAVE_DO_RECORDE, CHAVES_ANTIGAS, chaveDoRecorde | 2.5.5 (pedido do dono): a meta da Caça às Moedas sobe de 75 para 100 (Você × IA e IA × IA), com os mesmos valores das moedas; o recorde vai para a chave nova recorde.moedas3, e “Limpar recordes” apaga também as antigas |
Fonte: os relatórios de construção da run (step-06) e de cada versão depois dela.
Orçamento medido
A régua do jogo é o tempo de quadro medido, não o peso do JavaScript. Meta: p50 ≤ 33 ms na partida, perfil móvel do harness (390×844 e 844×390, CPU 4× mais lenta); 2.1.0: meta ≤ 30 ms e ≤ 190 draw calls no celular deitado (medido 10–13 ms e 147), teto 220 no computador; nenhum shader compila durante a corrida (109 programas no computador, 71 no celular); 2.2.0 (junção, 15/10/2026): no celular deitado, CPU 4×, p50 19,5 ms na Caça às Moedas, 17,0 na transmissão IA × IA e 15,5 na capa viva; draw calls 153 (Moedas), 99 (transmissão com o diretor), 156 no pior plano forçado, 126 na capa viva; programas 127 no computador e 83 no celular, todos pré-compilados na capa (nenhum compila na corrida, na transmissão nem na capa viva); 2.3.0 (junção, 15/10/2026, A/B intercalado contra a 2.2 em 5 rodadas, celular deitado, CPU 4×, mediana do p50): Caça às Moedas 26,3 ms (2.2: 26,1), Circuito 24,5 (25,2), IA × IA 19,5 (20,1), capa viva 17,1 (18,1); draw calls de cena no máximo 154, 134, 130 e 135, todas ≤ 190; programas 127 e 83, iguais à 2.2 (o turbo, a névoa e o trem não criaram nenhum); 2.4.0 (integração, 17/10/2026, A/B intercalado contra a 2.3.2 no celular deitado, CPU 4×, 8 rodadas; nas 3 rodadas com a máquina quieta as duas versões ficam no teto de 60 quadros/s): lago com os 2 carros (pior caso) 17,0 ms (2.3.2: 16,9), Caça às Moedas 17,1 (17,2), Circuito 16,9 (17,1); draw calls de cena no máximo 194 no lago (2.3.2: 192; só nesse pior caso passa de 190), 154 na Caça às Moedas e 134 no Circuito; programas 127 e 83, nada compila depois da capa (a esteira, as marolas, os anéis, o relevo e o turbo por tempo não criaram nenhum); 2.5.3 (integração, 19/10/2026, A/B pareado contra a 2.5.2 no celular deitado, CPU 4×, 13 pares com a máquina quieta, mas com outros processos a 14–19 %): mediana do p50 no lago 37,1 ms (2.5.2: 42,9), Caça às Moedas com efeitos 32,5 (43,0), Circuito IA × IA 34,5 (36,3), programas 118 e 77; a 2.5.3 não ficou mais lenta que a 2.5.2, mas os valores absolutos refletem a carga da máquina, e a meta não foi remedida com a máquina ociosa (a última medida limpa é a da 2.4.0, ~17 ms); 2.5.5 (etapa 1, 20/10/2026, CPU 4×, o jogo congelado no meio do salto, 30 amostras): as funções do salto custam 0,16 ms por quadro no normal e 0,24–0,30 ms no lateral (na 2.5.4: 0,55–0,61 e 0,76–0,96), e o salto soma ~0,8 ms de quadro, dentro do ruído de ±3 ms da máquina; programas 118 e 77; a medida no celular de verdade continua pendente. Tempos em ms, mediana de 3 runs, GPU Intel Iris Xe (ANGLE/D3D11). Fonte: harness/BASELINES.md.
Computador, 1280×720
| 1280×720, Moedas, fixo | cena | sombra | programas | triângulos | p50 (3 runs) |
|---|---|---|---|---|---|
| 2.3.2 (mesma sessão) | 176 | 54 | 127 | 264 078 | 15,9 / 15,2 / 14,5 |
| 2.4.0 (baseline) | 176 | 54 | 127 | 349 612 | 16,0 / 16,8 / 16,9 |
| 2.4.0 (2ª corrida) | 176 | 54 | 127 | 349 612 | 15,7 / 16,1 / 14,9 |
Depois do P5b (troca de qualidade sem travar)
| p50 | p95 | max | >33 ms | |
|---|---|---|---|---|
| 844×390 Circuito, CPU 4× | 35,6 → 28,5 | 65,7 → 49,2 | 103,5 → 82 | 357 → 215 |
| 844×390 Circuito, CPU 1× | 8,4 → 8,3 | 13,7 → 14,2 | 30,7 → 23,4 | 0 → 0 |
| 1280×720 Moedas | 13,8 → 13,4 | 21,8 → 21,8 | 487,6 → 54,7 | 19 → 18 |
| 1280×720 Circuito | 12,2 → 12,5 | 22,3 → 22,0 | 515,1 → 45,8 | 26 → 24 |
Perfil móvel (DPR 3, toque, CPU 4×)
| viewport | modo | tier | p50 | p95 | cena | sombra | tier | meta |
|---|---|---|---|---|---|---|---|---|
| 390×844 | Moedas | real | 11,9 | 29,9 | 138 | 0 | 3 → 4 (leve) | ok |
| 390×844 | Moedas | fixo | 13,9 | 31,5 | 138 | 56 | 3 | ok |
| 390×844 | Circuito | real | 11,6 | 16,9 | 101 | 0 | 3 → 4 (leve) | ok |
| 390×844 | Circuito | fixo | 17,5 | 34,5 | 101 | 43 | 3 | ok |
| 844×390 | Moedas | real | 14,2 | 31,7 | 209 | 0 | 3 → 4 (leve) | ok |
| 844×390 | Moedas | fixo | 19,0 | 33,1 | 209 | 56 | 3 | ok |
| 844×390 | Circuito | real | 29,3 (repetição: 31,5) | 50,0 | 136 | 0 | 3 → 4 (leve) | ok, no limite |
| 844×390 | Circuito | fixo | 39,6 (repetição: 39,6) | 63,3 | 134 | 43 | 3 | fora |
Draw calls: teto 220
Teto revisto no P5 da 2.0 (12/10/2026): 150 -> 220. Cena principal (sem sombra nem pós), semente 42: 1280x720 no fim da janela do bench Moedas 200 e Circuito 201; num quadro com 2,5 s de partida Moedas 182, Circuito 178, Contrarrelógio 161; no móvel 98-138 (390x844) e 133-209 (844x390, a vista mais larga). Já passava de 150 antes do carro novo (Moedas 178). De onde vem (Moedas, 182): 126 da grade 8x8 de baldes de árvores e props (decisão da R3: baldes pequenos para o frustum e o passe de sombra descartarem; juntar baldes troca draw call por casters e triângulos), 16 por carro do carro.glb (7 materiais da carroceria + 9 peças de roda; juntar exige material ou GLB novo) e ~25 do resto (estradas, anel, montanhas, céu, gemas, trem). Corte barato achado: no máximo 6 (3 picos e 3 capas de neve fora das InstancedMesh), longe de 150. A régua de verdade é o frame time (p50/p95 aqui e perfis.movel.p50); este teto vira alarme de crescimento sem plano, ~5% acima do maior medido (209).
Peso e a exceção ao teto de JavaScript do Kit
Registrado na ficha: Exceção ao teto de JS do Kit (60 KB gzip, pensado para os motores engine/): o carrinho é um HTML único com cena 3D, pós-processamento e IA escritos à mão desde a 1.x. Na 2.6.1 (23/10/2026, harness/docs.mjs no código final): JS do jogo 403 KB gzip, index.html 441 KB gzip, o jogo no ar 6,6 MB (os acertos da revisão da 2.6.0). Na 2.6.0 (23/10/2026, harness/docs.mjs no código final): JS do jogo 402 KB gzip, index.html 440 KB gzip, o jogo no ar 6,6 MB (a demo como o vídeo, o seletor de view, o volume em modal, o Preview real, os acertos da revisão e o Tema em rede lenta somam cerca de 18 KB gzip de JS). Na 2.5.9 (22/10/2026, harness/docs.mjs no código final): JS do jogo 384 KB gzip, index.html 418 KB gzip, o jogo no ar 6,5 MB (a música-tema soma 2,08 MB, fora da primeira carga). Na 2.5.8 (22/10/2026, harness/docs.mjs no código final): JS do jogo 377 KB gzip, index.html 411 KB gzip, o jogo no ar 4,4 MB. Na 2.5.7 (22/10/2026, harness/docs.mjs no código final): JS do jogo 376 KB gzip, index.html 411 KB gzip, o jogo no ar 4,4 MB (o replay soma cerca de 5 KB gzip). Na 2.5.6 (20/10/2026, harness/docs.mjs no código final): JS do jogo 367 KB gzip, index.html 400 KB gzip, o jogo no ar 4,4 MB (o som da demo e o alto-falante somam cerca de 1 KB gzip). Na 2.5.5 (20/10/2026, harness/docs.mjs no código final): JS do jogo 366 KB gzip, index.html 399 KB gzip, o jogo no ar 4,4 MB (a 2.5.4 e a 2.5.5 somam 20 KB gzip de JS: o salto Tesla com o salto lateral, a câmera lenta, os jatos de ar e o vapor, e os acertos da revisão). Na 2.5.3 (20/10/2026, harness/docs.mjs no código final): JS do jogo 346 KB gzip, index.html 379 KB gzip, o jogo no ar 4,3 MB (a 2.5.x soma 62 KB gzip de JS: pista larga, monte do túnel, prainha, moedas novas, quatro câmeras, salto a jato, as rodas do trem, a câmera mais perto e o som das rodas nos trilhos). Na 2.4.0 (17/10/2026, harness/docs.mjs): JS do jogo 284 KB gzip, index.html 316 KB gzip, o jogo no ar 4,1 MB (o relevo, as marolas e anéis e o turbo por tempo somam 15 KB gzip). Na 2.3.3 (16/10/2026): JS do jogo 269 KB gzip, index.html 300 KB gzip, o jogo no ar 4,1 MB (a esteira na água soma 7 KB gzip). Na 2.3.0 (15/10/2026, harness/docs.mjs): o JS era 262 KB gzip, index.html 292 KB gzip, o jogo no ar 4,0 MB (o trem.glb.js soma 978 KB). Na 2.2.0 (15/10/2026, harness/docs.mjs): JS do jogo 244 KB gzip, index.html 271 KB gzip, o jogo no ar 3,0 MB, com o teto do jogo em 25 MB por decisão do dono (13/10/2026). Na 2.1.0: JS 217 KB gzip, index.html 241 KB gzip, 2,8 MB. Histórico — medido em 12/10/2026 no build aprovado pelo 07b (commit 8c34746): JS do jogo 134 KB gzip, Three.js r128 150 KB gzip, primeira carga 723 KB gzip (gzip -9, medidos por harness/docs.mjs), o jogo no ar 2,5 MB (< 5 MB). Decisão do dono (12/10/2026, noite): o teto de 5 MB do Kit vale só para o jogo (o que ele carrega), não para a pasta publicada com a documentação — com manual.html, tecnico.html e manual-do-usuario.pdf a pasta tem 6,2 MB, e o jogo não carrega nenhum dos três. A régua que vale é o frame time medido (meta p50 ≤ 33 ms no perfil móvel, atingida na medida com a máquina quieta da 2.4.0: ~17 ms; a 2.5.3 e a 2.5.5 não foram remedidas com a máquina ociosa, ver meta_de_desempenho). Aceita pela QA no ciclo 1 com esta condição de registro.
Medido nesta geração: o index.html tem 1.296.725 bytes (441,1 KB com gzip); só o JavaScript embutido, 402,8 KB com gzip. O total no ar é 6.578,2 KB, sem a documentação.
Acessibilidade testada
Testado pela QA técnica (ciclo 2 de 3, decisão: APROVAR COM AJUSTES), com teclas e dedos de verdade, não lido da ficha:
| campo | resultado | o que foi medido |
|---|---|---|
| teclado | ✔ | partida completa de Contrarrelógio sem mouse (2:21,8); ordem do Tab = ordem visual; o Tab alcança o JOGAR ocupado; foco visível em todo controle (anel amarelo de 3 px, mediana 5,6–13,3:1); 1 largada por ação |
| contraste AA | ✔ | rótulos VOCÊ/IA 16,7–19,9:1 sob o glifo (cena e pior fundo branco, 4 perfis); contagem com contorno contínuo, letra × cena p5 ≥ 3,5:1 (piso 3), miolo × contorno 18,8:1; "Preparando…" 9,97:1; capa 9,0–18,6; HUD de dia e de noite ≥ 8,1 (Circuito) e ≥ 6,5 (Moedas); resultado ≥ 5,6; pausa ≥ 11,9; parcial ≥ 6,0 |
| legenda / texto para som | ✔ | o que soa aparece por escrito (contagem, sino, explosão, árvore, parciais), espelhado no #leitor; a fila e o pronto também são anunciados (ver A8 sobre o primeiro aviso) |
| sem dependência de cor | ✔ | minimapa: seta × losango, com contornos opostos, e legenda; Empate com palavra e frase, não só com a cor neutra; selo "não salvo" com texto, não só sem o verde; o resto como no ciclo 1 (VOCÊ/IA rotulados, portal numerado, parcial com sinal e palavra) |
| tolerância de tempo | ✔ | nenhum modo tem limite; pausa por P/Esc e pelo botão de toque a qualquer momento, inclusive na contagem; tempo, IA e placar congelados medidos por 3, 6 e 8 s |
A ficha × a medição
| Campo da ficha | Ficha | QA ciclo 2 |
|---|---|---|
tecnico.acessibilidade.teclado | true | ✔ |
tecnico.acessibilidade.contraste_aa | true | ✔ |
tecnico.acessibilidade.legenda_ou_texto_alt | true | ✔ |
tecnico.acessibilidade.sem_dependencia_de_cor | true | ✔ |
tecnico.acessibilidade.tolerancia_de_tempo | true | ✔ |
Notas da ficha: alvos de toque ≥ 48 px (controles de jogo ≥ 72 px, o TURBO ≥ 64 px); piscar ≤ 3 Hz; prefers-reduced-motion.
Privacidade
Livre para todas as idades: não há pessoas no jogo, e as batidas amassam a lata ou terminam numa explosão estilizada do carro. Nada sai do aparelho: os recordes e as preferências ficam só neste navegador.
O jogo não tem conta, servidor de dados nem telemetria. Tudo o que grava fica no localStorage do navegador, com o prefixo carSim3d., por meio do objeto store (que devolve se gravou: com o armazenamento bloqueado ou cheio, o jogo segue e avisa).
| Chave | O que guarda | Quando grava |
|---|---|---|
carSim3d.camera | a última câmera escolhida (1 normal, 2 piloto, 3 drone, 4 do alto): a próxima partida começa nela | ao trocar de câmera (teclas 1 a 4, C ou os botões 1 2 3 4 da tela, desde a 2.6.0); o drone fica gravado como 5 |
carSim3d.dica | qual dica da largada mostrar na próxima corrida (um contador) | na largada da Caça às Moedas |
carSim3d.mapOn | minimapa ligado (tecla M) | na tecla M |
carSim3d.modo | o último modo jogado | ao largar |
carSim3d.musicVol | volume da música (0 a 100) | no volume (o alto-falante da partida) |
carSim3d.recorde.circuito | recorde por modo: melhor volta (com as parciais) e melhor total, em ms | ao bater a marca; "Limpar recordes" apaga |
carSim3d.recorde.relogio | recorde por modo: melhor volta (com as parciais) e melhor total, em ms | ao bater a marca; "Limpar recordes" apaga |
carSim3d.recorde.moedas | recorde antigo da Caça às Moedas (a meta antiga, até a 2.5.0): fica no aparelho, mas não é mais lido | até a 2.5.0, ao bater a marca; "Limpar recordes" apaga |
carSim3d.recorde.moedas2 | recorde antigo da Caça às Moedas (meta 75, até a 2.5.4): fica no aparelho, mas não é lido | da 2.5.1 à 2.5.4, ao bater a marca; "Limpar recordes" apaga |
carSim3d.recorde.moedas3 | recorde da Caça às Moedas: menor tempo até os 100 pontos e maior placar | ao bater a marca; "Limpar recordes" apaga (junto com os antigos) |
carSim3d.rotaIA | a opção "Mostrar a rota da IA" (linha laranja e leque do sensor) | em Detalhes, Opções |
carSim3d.sfxVol | volume dos efeitos (0 a 100) | no volume (o alto-falante da partida) |
carSim3d.som.demo | som da capa viva (Tema e efeitos) ligado ou desligado; nasce ligado, mas só soa com o som ligado | no alto-falante da capa viva, e ao ligar o Som da capa |
carSim3d.som.efeitos | efeitos ligados ou desligados | no botão Som e no volume (o alto-falante da partida) |
carSim3d.som.musica | música ligada ou desligada | no botão Som e no volume (o alto-falante da partida) |
carSim3d.recarga.<versão> (sessionStorage) | a recarga automática já feita para aquela versão, nesta aba | antes de recarregar sozinho |
Rede: o jogo aberto pede versao.json (sem cookies, sem parâmetros além de um carimbo de tempo contra cache); com a Música ligada, também a música-tema (assets/musica/jogo-do-carrinho-tema-intro.m4a e assets/musica/jogo-do-carrinho-tema-laco.m4a), quando o JOGAR fica pronto ou quando a Música é ligada. Por file://, nenhum dos dois.
Atualização automática
O jogo publicado é uma pasta estática com nomes fixos, e o navegador guarda o HTML em cache. Para a correção chegar a quem deixou a aba aberta, o jogo confere versao.json ao abrir, ao voltar para a aba e a cada 15 minutos.
- Versão igual: nada acontece.
- Versão diferente, na capa: recarrega uma vez, calado.
- Versão diferente, em partida, pausa ou resultado: mostra a faixa “Versão nova disponível” com “Atualizar agora”, sem interromper. No celular, a faixa espera a pausa ou a capa e a partida recebe uma mensagem.
- Anti-loop: uma recarga automática por versão e por aba (
carSim3d.recarga.<versão>no sessionStorage). Sem sessionStorage, não recarrega sozinho. - Os assets levam
?v=2.6.1: trocar a versão força o navegador a buscar a cópia nova.
Prova: node harness/teste-atualizacao.mjs (11 checagens, inclusive o anti-loop).
Música-tema e o laço
Desde a 2.5.9, a capa toca a música-tema: Jogo do Carrinho (Tema) — MusicPlay.club (criada com Suno). O código mora em SEC:TEMA; a regra do som da demo, em SEC:CINEMA (item 11). A música não é MIT: © MusicPlay.club, usada com permissão (gerada no Suno com plano pago; ver o NOTICE.md do repositório e o licencas.txt).
- Os arquivos. Dois, AAC-LC a 128 kbps, 48 kHz, estéreo, sem a capa embutida:
assets/musica/jogo-do-carrinho-tema-intro.m4a(a introdução, 44,4 s) eassets/musica/jogo-do-carrinho-tema-laco.m4a(o laço, 83,9 s), 2.080.237 bytes ao todo. “Jogo do Carrinho (Tema)”, criada pelo dono do jogo no Suno em 22/10/2026, com plano pago (licença de uso comercial), conta MusicPlay.club (https://suno.com/s/MTzScgQfoGAjWnhs; perfil https://suno.com/@musicplayclub; id ad683b68-3829-4910-a496-a5922f3a8d53), a faixa 1 do álbum (ALBUM_SUNO.md). O MP3 entregue (184,8 s, 48 kHz, 185 kb/s, com a capa embutida; output/2026-10-22-v2.5.9/musica/) foi cortado em 127,6 s, costurado no fim do laço (43,811 a 127,126 s; ferramentas/costura-tema.py), baixado 0,9 dB (o laço a −16,1 LUFS, pico −5,7 dBTP) e gravado em AAC-LC 128 kbps sem a capa (ffmpeg aac_mf); depois do parecer do revisor (R1), em dois arquivos: a introdução (0 a 44,4 s, 720.242 bytes) e o laço (de 0,1 s antes de 43,811 s a 0,5 s depois de 127,126 s, 1.359.995 bytes; ferramentas/dividir-tema.py), na run 2026-10-22-v2.5.9. - A memória. Os dois são decodificados um de cada vez, a introdução primeiro, e ela sai da memória depois de passar ao laço (a cópia comprimida, 0,7 MB, fica para a próxima vez que o Tema recomeçar). Medido no celular emulado (390×844, DPR 3, CPU 4×), no processo da página: o pico da decodificação caiu de ~+235 a +263 MB (um arquivo só) para ~+150 MB, e o fixo, de ~+54 a +62 MB para ~+45 MB (o AudioContext custa ~15 MB nas duas). Decodificar a 32 kHz baixaria mais o fixo, mas o Chromium reamostra o buffer na hora de tocar e o agudo cai (−2,6 dB de 8 a 12 kHz, −6,5 dB de 12 a 15 kHz, e imagens acima de 16 kHz): não foi feito.
- A rede. Só com a Música ligada: a introdução é pedida quando o JOGAR fica pronto (ou quando o jogador liga a Música) e o laço logo depois. Prazo de 25 s para a introdução e 60 s para o laço. Até a 2.5.9 eram 8 e 30 s, e o servidor do ar entrega a ~100 KB/s: a introdução, de 0,7 MB, leva uns 7 s. Desde a 2.6.0, enquanto o arquivo chega, a capa e a demo tocam a trilha procedural, e o Tema entra em crossfade de 0,5 s quando chega. A trilha só entra depois de 0,5 s de espera: na rede boa, o Tema chega antes e entra sozinho. Se a introdução acaba antes de o laço chegar, ela sai em fade na junção, a trilha cobre a espera e o Tema volta direto no laço (
TEMA.noLaco). Passado o prazo, ou com erro, a capa fica com a trilha procedural de sempre. Testado no Google Chrome com o Tema a 100 e a 50 KB/s, com o laço segurado, com 404 e com a conexão cortada. - O laço sem emenda. Toca num
AudioBufferSourceNodecomloop,loopStarteloopEnd: 43,811 s a 127,126 s da música, 41 compassos a 118,1 BPM, com o breakdown no meio. A introdução toca só na primeira volta e passa ao laço no instante exato (start(when)), em crossfade de 0,1 s entre sinais iguais: os 0,6 s depois da junção estão nos dois arquivos. O laço vem costurado no fim: os 0,35 s antes deloopEndpassam em fade para o que antecedeloopStart, e 0,1 s antes e 0,5 s depois deloopEndsão o mesmo áudio deloopStart. O salto é contínuo na amostra, mesmo que o decodificador desloque o arquivo. - Onde toca. Na capa (a primeira carga e a volta de uma partida) e na capa viva, sem recomeçar ao entrar ou sair dela. Ao jogar, crossfade de 0,5 s para a trilha procedural da partida, que tem ganho próprio (
audio.chipGain) e um fim de fade (audio.chipFim). Resultado, pausa, modo foto e replay como antes. De volta ao menu, o Tema recomeça, com a introdução. Nunca há dois Temas ao mesmo tempo (TEMA.fonteé única). - Os controles. O Som da capa e o mudo de Música ligam e desligam o Tema; desligar é um fade de 0,3 s no volume de Música (
ganhoDaMusica). O alto-falante da capa viva cala e libera o Tema junto com os efeitos da demo; ao entrar na demo com ele desligado, o Tema sai em fade de 0,5 s. O jogo segue nascendo mudo na primeira visita; o primeiro toque, clique ou tecla na capa (também num cartão ou no fundo) libera o áudio, e o primeiro toque no “Som: ligado” com o áudio ainda preso pelo navegador liga, não desliga. - O volume. O arquivo está no padrão do álbum, −16 LUFS, e toca com
NIVEL= 1, pelo volume de Música (×0,5 de fábrica). Na demo, o Tema fica uns 4,4 dB acima dos efeitos dela (o dono quis assim). A trilha procedural é 6,6 dB mais baixa, mas na largada a contagem e os motores entram juntos. - Sem os arquivos. Por
file://o navegador não deixa ler os arquivos (o jogo nem pede), e uma falha de rede, o prazo ou um erro de decodificação dão no mesmo: a capa volta à trilha procedural e a capa viva fica sem música, como até a 2.5.8, sem erro no console. - Para trocar a música. Novos arquivos nos mesmos caminhos (ou outros, em
TEMA.INTROeTEMA.LACO_ARQ), a junção e o laço emTEMA.JUNCAOeTEMA.LACO_S(amostras a 48 kHz) e o ganho emTEMA.NIVEL. A ficha registra a procedência, e o crédito fica no painel Créditos.
Leitura para os testes: window.__tema(). O TEMA.partida só muda nos testes, para gravar a volta do laço e a junção.
Como rodar local
Por file://: abrir jogos/carrinho_fable_5.html no navegador. Não precisa de servidor; o jogo só deixa de consultar versao.json.
Por http://, como no ar:
node servidor_local.mjs # http://localhost:8787/ (a raiz abre o jogo)
node servidor_local.mjs 8080 # outra porta
O servidor resolve em jogos/ o que o jogo pede por caminho relativo (vendor/, assets/, versao.json), como acontece na pasta publicada.
Harness e testes
Requisito: o Playwright do repositório OPENSQUAD (o harness o carrega de lá). Comandos, como estão em harness/README.md:
# medição completa (3 runs x 900 frames, 8 poses) — desktop 1280x720, Caça às Moedas, semente 42
node harness/bench.mjs --target jogos/carrinho_fable_5.html --http --label local --out harness/runs/local
# a baseline da semente 42 (tier fixo: o pós não cai no meio e as 8 poses saem comparáveis) — BASELINES.md
node harness/bench.mjs --target jogos/carrinho_fable_5.html --http --tier fixo --label base-2.0.0 --out harness/runs/base-2.0.0
# perfil MÓVEL (meta do GDD 2.0: p50 <= 33 ms na partida): 390x844 e 844x390, DPR 3, toque, CPU 4x,
# Moedas e Circuito, tiers ligados (real) e parados no piso (fixo); --cpus 4,1 junta a linha de referência sem freio
node harness/bench.mjs --perfil movel --target jogos/carrinho_fable_5.html --http --cpus 4,1 --frames 600 --out harness/runs/movel
# a versão publicada (desde 29/08/2026 o jogo mora no dentistas.com.br)
node harness/bench.mjs --target https://dentistas.com.br/jogos/jogo_do_carrinho/index.html --label prod --out harness/runs/prod
# comparar duas execuções e gerar o contact sheet
node harness/bench.mjs --compare harness/runs/prod harness/runs/local --out harness/runs/contact-sheet.html
# 20 loads frios, zero erros de JS/shader tolerados — por HTTP (como no ar) e por file://
node harness/bench.mjs --smoke --target jogos/carrinho_fable_5.html --http --loads 20
node harness/bench.mjs --smoke --target jogos/carrinho_fable_5.html --loads 20
# o portão da atualização automática (11 checagens)
node harness/teste-atualizacao.mjs
# diff isolado de duas imagens
node harness/diff.mjs a.png b.png saida.png --threshold 0.1
Documentação
# fotografa as telas (computador, celular em pé e deitado, e a v1)
node harness/docs-capturas.mjs --saida <pasta-de-capturas> --porta 4471
# gera manual.html, tecnico.html e manual-do-usuario.pdf em jogos/ (--destino <pasta> grava um rascunho fora do repositório)
node harness/docs.mjs --run <pasta-da-run> --capturas <pasta-de-capturas> [--destino <pasta>]
O gerador lê a ficha (jogos/game.yaml) e abre o jogo para ler CONTEUDO, FICHA e VERSION. Texto de interface citado que sumiu do jogo, chave de armazenamento sem explicação, figura ausente ou PDF acima de 5 MB derrubam a geração.
Deploy
node deploy_ftp.mjs --seco # ensaio: staging, gates, versão no ar (um GET) e a lista do que subiria; não conecta
node deploy_ftp.mjs --publicar # publica (produção: só com o OK do dono)
node deploy_ftp.mjs # sem argumento (ou --help): só mostra o uso
- Argumentos: lista fechada. Publicar exige
--publicarexplícito; argumento desconhecido é recusado antes de qualquer staging ou conexão (desde a 2.1.0). - Staging:
jogos/carrinho_fable_5.htmlviraindex.html; sobemversao.json,og.jpg, a documentação, o que o HTML cita devendor/eassets/, e a v1 emv1/. - GATE 1: em todo HTML do staging, nenhuma carga de host externo, e toda referência relativa existe.
- GATE 2: a versão no ar tem de ser diferente da que sobe.
- Ordem: v1/, arquivos de apoio,
index.htmleversao.jsonpor último. - GATE 3: confere no ar o corpo de cada resposta (o anfitrião devolve 200 com a home para caminho inexistente).
- Página do vídeo (desde a 2.5.8): o
--publicarreescreve a versão dedivulgacao/video/index.htmle sobe sóvideo/index.html, depois doversao.json. Os mp4, a capa e os pôsteres do vídeo ficam com opublicar-video. - Um só dono da versão na página:
harness/versao-pagina-video.mjs. A funçãotrocarVersaoNaPagina(html, versao)troca só a versão antiga da página (a do título), só em texto: título, og:title, twitter:title, h1 e aria-label. Atributos comosrc, datas e outros números não mudam. - O
publicar-videodo vídeo usa o mesmo módulo, com a versão dejogos/versao.json. Assim, publicar o vídeo depois do jogo não volta a versão da página. - Antes de subir, página com marcador de modelo (
{{…}}) ou com a versão antiga sobrando barra o deploy. Mp4 ou pôster citado que não está no ar gera aviso, no ensaio e na publicação. No ar, o título, o og:title e o h1 têm de dizer a versão. - Carimbo da ficha (desde a 2.5.8): com o GATE 3 limpo, o
--publicargrava emjogos/game.yamlo status, aversao_no_ar, adata_publicacaoe a data da versão no changelog (harness/carimbo-da-ficha.mjs). O ensaio mostra o que mudaria. - Trava de escopo: o script só escreve dentro da pasta do jogo no anfitrião (o caminho está no próprio
deploy_ftp.mjs). FTPS com certificado validado; as credenciais ficam fora do repositório.
A versão 1 histórica
| Versão | 1.5.2 (tag v1.5.2) |
|---|---|
| No repositório | historico/v1/ |
| No ar | https://dentistas.com.br/jogos/jogo_do_carrinho/v1/ |
| Three.js | local (../vendor/three.r128.min.js), por decisão do dono em 12/10/2026 após o QA ciclo 1 — o CDN derrubaria a v1 |
| No índice | não: o cartão do índice é da versão atual |
O deploy reescreve dois caminhos da v1 (favicon e Three.js) por string literal e aborta se a troca não acontecer exatamente uma vez. O resto da 1.5.2 fica como era, inclusive os 2 avisos de flatShading no console.
Histórico de versões
| Versão | Data | Mudança |
|---|---|---|
| 1.0.0 | 2026-08-11 | garagem multi-IA: carrinho 3D Você × IA na caça às moedas (escrito com o Claude Fable 5) |
| 1.1.0 | 2026-08-11 | roubo de alvo: moeda que a IA já perseguia vale 4 |
| 1.2.0 | 2026-08-11 | capa de jogo comercial, tela de resultados e trilha sintetizada |
| 1.5.2 | 2026-10-11 | prévia de link (Open Graph) com a arte do cartão do índice |
| 2.0.0 | 2026-10-13 | jogável no celular (toque, retrato e paisagem), modos Circuito e Contrarrelógio, primeira página do Kit, atualização automática, Three.js local; a 1.5.2 fica jogável em /v1/ |
| 2.0.1 | 2026-10-13 | no Circuito os carros encostam pela forma real, de frente para trás e lado a lado, sem se atravessar; luz de freio mais marcada no celular; o carro só ganha o brilho noturno com a noite fechada |
| 2.1.0 | 2026-10-14 | o dia que vira noite na corrida (com faróis e chuva), câmeras novas (vista aérea e modo foto), cenário com acabamento, Caça às Moedas com diamantes e pontuação nova, batida que amassa em vez de explodir; em detalhe: velocímetro em km/h de verdade, chuva com pista molhada, ciclo de 4 min de manhã à noite com faróis nos dois carros, chuva no mapa inteiro com derrapagem e poças até 5 s depois, a câmera mostra a frente do carro na ré, gramado com moitas, ferrovia com brita e trem novo, montanhas e túnel de rocha, árvores e neblina; moeda 2, sequência ×2 em 12 s, roubo ×4 só na moeda solta, rubi 10, diamantes de 25 um de cada vez depois dos 60 pontos, estrela cadente de 15; 1ª batida carro × carro amassa, 2ª quebra os dois (−1 vida, 2 s parados); velocímetro até 115 km/h com FOV e linhas de vento nos três modos; largada 3-2-1-JÁ lado a lado, setas na borda, cronômetro, recorde do aparelho e sons novos na Caça às Moedas |
| 2.2.0 | 2026-10-15 | o modo Assistir: IA × IA filmado como transmissão de TV, a capa viva que vira transmissão, o carro de miniatura de coleção, o botão de som sempre na tela; em detalhe: Verde Ousada contra Vermelha Calculista na Caça às Moedas inteira; diretor de câmera com perseguição baixa, beira da estrada, trilho lateral, drone, close com câmera lenta, vista aérea, trem e sol, barras de cinema e letreiro dos lances; teclas 1/2/3/4 e velocidade 1×, 2× e 4×, com botões no celular; o 4º cartão na capa, que vira uma transmissão ao fundo; o carro com verniz de flocos, reflexo de estúdio, aros e escapamento cromados, linhas de painel, vidro escuro e sombra de contato, e verde e vermelho mais fundos; o menu da capa viva some 4 s depois do último gesto e volta ao toque, clique ou tecla; o botão de som (alto-falante) na tela durante a partida, nos quatro modos; o Tempo do resultado do IA × IA é o tempo de jogo (conta o 2×, o 4× e a câmera lenta) |
| 2.3.0 | 2026-10-15 | o TURBO com 3 cargas e o item no túnel, a vista aérea com zoom, a locomotiva a vapor, a serra na névoa e as batidas com faíscas, o endereço novo em dentistas.com.br/jogos/jogo_do_carrinho/; em detalhe: Espaço ou o botão TURBO dão 1,5 s de empurrão até 144 km/h na Caça às Moedas, no Circuito e no IA × IA (fora do Contrarrelógio); o item no túnel soma uma carga, até 5; a IA usa o turbo pelas mesmas regras, só na reta; + e − aproximam e afastam a vista aérea; na transmissão as setas (ou o dedo) movem a vista aérea e + e − dão zoom, e a velocidade 1×, 2× e 4× foi para < e >; velocímetro a 150 com a faixa do turbo; locomotiva a vapor vermelha com fumaça na chaminé e vagões de quinas arredondadas; montanhas redesenhadas e névoa de distância nas quatro horas e na chuva; esbarrão e batida por trás com faíscas, tranco e som; o feed e o aviso nunca se cobrem nas telas estreitas |
| 2.3.1 | 2026-10-15 | logo com os furos das letras |
| 2.3.2 | 2026-10-15 | manual: três acertos de texto e paginação |
| 2.4.0 | 2026-10-17 | a esteira de ondas na água (o V de Kelvin, a espuma e os respingos atrás do carro), marolas e anéis nos lagos (do carro e da chuva), a pista e o gramado com pequenas subidas e descidas, o turbo por tempo (segurar usa e soltar para, 10 s na largada, +10 s por item até 30 s), a capa com links (Manual, Pôster e Vídeo); em detalhe: a esteira de Kelvin polida para as câmeras baixas, a superfície dos lagos com duas camadas de marolas que encrespam na chuva, anéis ao entrar e sair da água, em volta do carro devagar ou parado e nos pingos da chuva; lombadas de até ~1,8 m na pista e no gramado, com o carro, as árvores, as moedas, os portais e as câmeras seguindo o chão (ferrovia, lagos, túnel e largadas planos; a física e os recordes do Contrarrelógio não mudam); o turbo vira um tanque de segundos fracionado com a barra no botão, uma recarga por passagem no túnel (o 2º item fica para o rival) e a IA escolhendo quanto tempo segura; Manual, Pôster e Vídeo no pé da capa, e a faixa de versão nova no celular deitado sem empurrar o JOGAR |
| 2.4.1 | 2026-10-18 | poças que crescem e ladeiras; em detalhe: as poças da chuva começam pequenas, crescem enquanto chove (as vizinhas se juntam) e secam devagar depois; as subidas e descidas um terço mais inclinadas, e agora sentidas por você e pela IA (subindo o carro perde um pouco de velocidade e o motor ronca mais grave; descendo ganha um pouco, com o motor aliviado e vento); o asfalto de dia mais escuro; um terço a menos de árvores, pedras e montanhas, com o mesmo sorteio do mundo; o céu sem as nuvens de bolhas |
| 2.5.0 | 2026-10-18 | pista larga, túnel no monte, prainha; em detalhe: a pista 50% mais larga (duas faixas de 3,75 m) com acostamento de terra e cascalho; o túnel com o dobro do comprimento, acompanhando a curva, dentro de um monte gramado em que dá para subir e passar por cima; os cruzamentos dos ramais com faixa contínua na principal, sonorizadores, linha e placa de PARE; os buracos e as pedras saíram; 75% das árvores; nenhuma montanha perto da pista, e as distantes pela metade; uma prainha de areia em volta dos lagos, que agora se abrem por toda a margem; o amanhecer e o anoitecer pela metade (o dia e a noite ganham o tempo); a IA freia antes das curvas em descida |
| 2.5.1 | 2026-10-19 | moedas novas, meta 75 e faíscas; em detalhe: na Caça às Moedas a meta cai de 150 para 75 pontos e os valores vão à metade (moeda 1, punhado de 5 moedas 5, rubi 5, diamante 13 surgindo a partir de 30, estrela cadente 8); a moeda grande com halo e facho dourado vale 10 (uma por vez); fileiras de moedas no acostamento valem 1 cada; o facho do punhado pisca ao surgir e fica aceso; cada coleta solta o “+N” na cor do tipo, que sobe e some em 2 s, e faíscas próprias (estrela dourada na moeda, chuva dourada no punhado e na moeda grande, a cor da gema, laranja e azul no turbo); na batida entre os carros, faíscas de metal que quicam e esfriam, com lascas; a IA erra um pouco, como gente, e não empaca mais no monte do túnel; a câmera não entra nos pinheiros descendo o monte e a beira do lago sem o filete azul; recorde novo da Caça às Moedas |
| 2.5.2 | 2026-10-19 | câmeras novas, salto a jato e entardecer; em detalhe: quatro câmeras, todas com zoom + e −: 1 normal, 2 piloto (do banco do motorista), 3 drone (atrás e acima, seguindo com atraso) e 4 do alto; C passa para a próxima, o botão de câmera do celular passa pelas quatro e a escolhida fica para a próxima partida; o modo foto foi para o F e a janela da visão da IA para o V; o salto a jato (tecla J ou o botão JATO, 4 por partida, na Caça às Moedas e no Circuito): o carro voa baixo uns 2,5 s, passa por cima do outro carro e, sobre o lago, vai até a outra margem; dentro do túnel não funciona, e as câmeras sobem junto; no lago o carro afunda um terço, com espuma em volta do casco; o fogo do turbo sai das duas ponteiras do escapamento; toda partida começa no início do entardecer; a IA desvia do carro parado na pista; descendo o monte a câmera não dá mais o salto de um quadro; saltando logo depois de um portal a câmera não atravessa mais a faixa dele; na câmera do piloto a linha do traçado começa 9 m à frente e a espuma colada no olho some; a placa PARE saiu dos cruzamentos (ficam a linha de PARE pintada, os sonorizadores e as faixas) |
| 2.5.3 | 2026-10-20 | trem com rodas, som nos trilhos, câmera mais perto e manual novo; em detalhe: a câmera normal fica mais perto do carro e não se afasta mais quando ele corre, e o drone também chega um pouco mais perto; as rodas da locomotiva a vapor e do tênder giram com a velocidade do trem e as bielas acompanham o giro; o manual (página e PDF ilustrado), as referências técnicas e a página Sobre foram refeitos com tudo o que mudou na 2.5: a pista larga, o túnel no monte, os cruzamentos, a prainha, a partida no entardecer, as moedas novas e a meta de 75 pontos, as quatro câmeras, o salto a jato e o carro no lago; e, pedido do dono, o barulho das rodas trepidando sobre os trilhos e os dormentes quando o carro anda na ferrovia ou a atravessa, no ritmo da velocidade |
| 2.5.4 | 2026-10-20 | salto Tesla com giro; em detalhe: o salto a jato sobe o dobro (5,5 m) e passa por cima do trem, do outro carro e das árvores baixas, na velocidade em que o carro estava; com a seta para o lado (J + ← ou →, no celular uma seta e o JATO), o salto lateral sobe 7,5 m, gira 360° para o lado da seta em câmera lenta, com a câmera mais perto, e pousa uns 9 m para lá; os jatos agora são de ar comprimido, brancos: quatro colunas por baixo, junto das rodas, e dez bocais em volta do carro que disparam rajadas curtas no giro, com o rastro de vapor no ar, a nuvem no pouso e o chiado de ar no som |
| 2.5.5 | 2026-10-20 | meta 100, chuva curta e salto afinado; em detalhe: na Caça às Moedas a meta sobe de 75 para 100 pontos, com os mesmos valores das moedas, e as partidas ficam com cerca de 2 a 3 minutos (o recorde começa do zero); a pancada de chuva dura um terço do que durava (uns 7 a 11 segundos) e a noite fechada, dois terços (o dia ganha o tempo); nenhuma árvore fica a menos de 2 m do acostamento; o salto a jato ficou mais firme: o salto lateral não cai de cima do monte nem pousa no trem, a árvore que bate no ar para o carro, o voo desvia da faixa dos portais, o farol não varre o céu no giro, o vapor pesa menos no celular, o chiado de ar fica nítido na câmera lenta e o som não estoura na decolagem |
| 2.5.6 | 2026-10-20 | demo com os efeitos do jogo; em detalhe: na demonstração da tela inicial (a capa viva) a música sai e ficam os efeitos de verdade da partida — motores, pneus, moedas, o trem e as rodas nos trilhos, a chuva — na metade do volume de Efeitos, respeitando o mudo; um alto-falante no canto de cima liga e desliga o som da demonstração sem sair dela; ao jogar, a música e os efeitos voltam como você deixou; na lista de controles, o salto a jato não funciona dentro do túnel nem na boca dele |
| 2.5.7 | 2026-10-22 | replay do salto com 3 visões; em detalhe: o salto lateral (J com a seta para o lado, ou a seta e o JATO no celular) acontece em velocidade normal durante a partida, sem câmera lenta e sem a câmera chegando perto, com o mesmo giro, os jatos de ar e o pouso uns 9 m ao lado; depois dele, por uns 8 s, aparece o botão REPLAY (ou a tecla R), e no resultado da partida o “Replay do salto lateral”: a partida pausa e uma tela mostra o último salto lateral em câmera lenta, com o som lento, em três visões ao mesmo tempo — a normal do jogo, a do motorista de dentro do carro e uma de cima, perto do carro e das duas faixas; Repetir passa de novo e Voltar ao jogo (ou Esc, ou um toque fora das visões) continua a partida do ponto em que parou; na demonstração da tela inicial, um toque na cena também libera o som, e com os Efeitos em 0% o alto-falante dela mostra o som desligado |
| 2.5.8 | 2026-10-22 | capa mais longa e replay afinado; em detalhe: a capa do jogo (o logo, o carro verde e os quatro cartões) fica 6 segundos parada antes de a demonstração começar atrás dela, na primeira carga e também ao voltar de uma partida para o menu; no Replay do salto lateral, a visão De cima acompanha a altura do salto e não corta mais o carro no alto do giro; e o manual mostra o botão REPLAY numa reta |
| 2.5.9 | 2026-10-23 | música-tema na abertura; em detalhe: a música-tema do jogo, “Jogo do Carrinho (Tema)”, de MusicPlay.club (criada com Suno), toca na tela de abertura e continua, sem recomeçar, durante a demonstração (a capa viva), com os efeitos da demonstração mais baixos por baixo dela; o botão Som da capa, o volume de Música e o alto-falante da demonstração ligam, regulam e desligam a música; ao jogar, ela passa para a música da partida num crossfade de meio segundo, e volta ao voltar para o menu; o jogo continua nascendo sem som na primeira visita, e com a música desligada nem a baixa; e, na demonstração e na partida, a IA passa correndo pela fileira de moedas do acostamento, sem frear a cada moeda nem voltar para a que errou |
| 2.6.0 | 2026-10-23 | demo como o vídeo, Preview real, seletor de câmera, volume no alto-falante e zoom sem botões; em detalhe: a demonstração da tela inicial conta, uma vez, a história do vídeo do jogo — trechos da corrida, o carro verde saltando a jato por cima do trem, o salto lateral com giro para a outra pista, alguns segundos do replay em três visões e a câmera girando até o carro virar o desenho da capa — e volta ao menu, que fica esperando; o botão Preview real, à direita do JOGAR, mostra essa demonstração na hora (qualquer toque ou tecla volta ao menu); na partida, os botões 1, 2, 3 e 4 trocam a câmera (normal, piloto, drone e do alto) e mostram a da tela; o volume de Música e Efeitos saiu do canto da tela: o alto-falante abre um quadro com os dois e com o botão que liga e desliga o som (a corrida espera enquanto ele está aberto); e os botões + e − de zoom saíram da tela: o zoom fica nas teclas + e −, na rodinha do mouse e na pinça de dois dedos; e, em conexão lenta, a música-tema não cai mais: a trilha do jogo toca enquanto ela chega e dá lugar a ela |
| 2.6.1 | 2026-10-23 | acertos da revisão: as mensagens longe dos botões no celular, a demonstração sem baixar a qualidade e o duplo clique no volume; em detalhe: no celular deitado pequeno, os avisos e as mensagens ficam numa coluna à esquerda e não passam mais por baixo das setas de direção, do JATO nem do TURBO; no celular em pé, as mensagens da pista não passam mais por baixo do botão REPLAY; no computador, assistir à demonstração não baixa mais a qualidade da imagem da partida seguinte; e um duplo clique mais lento no alto-falante abre o volume sem fechá-lo |
Fora de escopo
- trilha sonora (item 2 do Kit, dispensado): em parte desde a 2.5.9 — a música-tema (Jogo do Carrinho (Tema), MusicPlay.club, criada com Suno; a faixa 1 do álbum, ALBUM_SUNO.md) toca na capa e na demonstração; a partida e o resultado seguem com a trilha sintetizada no jogo (Web Audio) até as faixas Acid na Pista e Bandeira Quadriculada (TRILHA_SONORA.md e ALBUM_SUNO.md).
- vídeo vertical de divulgação (item 11 do Kit, dispensado): fica para quando o dono decidir o calendário de lançamento; sem ele o jogo não entra no YouTube Shorts.
- Conta, ranking online e servidor de dados: não existem. Recorde é do aparelho.
- Multi-idioma: um idioma só, português do Brasil.
- Teto de 60 KB gzip de JavaScript do Kit: não se aplica a este jogo (ver Orçamento medido).
- Dirigir com o mouse: no computador, o carro só se dirige pelo teclado.
Limitações conhecidas
- Troca de modo com a largada na fila. Quem aperta JOGAR durante o preparo (rótulo “Iniciando…”) e depois toca outro cartão larga no modo tocado por último. O cartão marcado é o que joga; o rótulo do botão não repete o modo.
- Rede muito lenta. Se o carro não chega em 12 s, o JOGAR libera com o carro de reserva. Quando o carro chega, o botão volta a “Preparando…” por uma fração de segundo; um clique nesse intervalo entra na fila e larga uma vez.
- Versão 1. A 1.5.2 é servida como era, sem correção: o console dela mostra 2 avisos de
flatShading. - Equilíbrio da IA. Nos testes com piloto automático, a IA perdeu o Circuito com folga e venceu a Caça às Moedas. O comportamento dela se ajusta em
AI_MAXeplanSpeed.