Underground 2 Revived
Play Need for Speed: Underground 2 (2004) in Chrome and Firefox with WebGPU graphics, Web Audio, up to 120 fps widescreen, controller support, free roam and Online races with friends. Fan project, not
브라우저 기반 무료 FPS, 브라질 5진 영감·44캐릭터·5맵·26무기·봇·라운드·다양한 혼란
FPS satírico de navegador com 5 facções brasileiras: 44 personagens, 5 mapas, 26 armas, bots, rounds e muita treta. Jogue grátis no navegador.
게임JavaScript · PythonGitHub @corosolto온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
FPS satírico de navegador: 5 facções brasileiras caricatas, 44 personagens, 5 mapas e 26 armas — rounds e Capture the Flag contra bots, direto na aba, sem instalar nada. Three.js + vanilla JS, zero build. Gerado em par com agentes de IA (Claude, Kimi, Codex/GPT, GLM) — AI generated & AI friendly.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
AI generated & AI friendly — construído em par com agentes de IA, e cada commit diz qual escreveu (trailer Agent:, convenção em CONTRIBUTING.md): FPS gratuito de navegador em Three.js: 5 facções brasileiras caricatas, 44 personagens originais, 5 mapas satíricos e 26 armas — rounds e Capture the Flag contra bots, direto na aba. Sem download, sem instalação, sem cadastro.README 전문 보기 ↗
AI generated & AI friendly — construído em par com agentes de IA, e cada
commit diz qual escreveu (trailer Agent:, convenção em CONTRIBUTING.md):
FPS gratuito de navegador em Three.js: facções brasileiras caricatas, personagens originais, mapas satíricos e armas. Partidas contra bots e multiplayer beta, direto na aba. Sem download ou instalação para jogar.
| O que | Quanto | Onde confere |
|---|---|---|
| Código do jogo | 67.475 linhas em 163 arquivos | git ls-files public/js/*.js | xargs wc -l |
game.js | 9.062 linhas | wc -l public/js/game.js |
main.js | 5.300 linhas | wc -l public/js/main.js |
| Armas com GLB | 27 | git ls-files 'public/models/weapons/*.glb' | wc -l |
| GLBs de personagem | 74 | git ls-files 'public/models/characters/*.glb' | wc -l |
| Props em GLB | 217 | git ls-files 'public/models/props/*.glb' | wc -l |
| Clipes de animação versionados | 897 | git ls-files public/models/anims | wc -l |
| Personagens jogáveis | 63, em 7 grupos | array CHARACTERS de characters.js |
| Mapas no menu | 12 | MAPS menos MAPAS_PARADOS |
| Arnêses visuais em HTML | 25 | git ls-files 'public/*.html' | wc -l |
| Scripts do arnês | 891 | git ls-files 'tools/eval/*.mjs' 'tools/eval/*.py' | wc -l |
| Scripts de pipeline | 120 | git ls-files 'tools/*.mjs' | wc -l |
| Tarefas de entrada escritas | 26 | git ls-files 'docs/issues/[0-9]*.md' | wc -l |
| Versão | 2.1.0-alpha.128 | public/js/version.js e package.json (batem) |
Bloco gerado por
node tools/gen-docs.mjs. Fonte:o comando da coluna direita de cada linha
O multiplayer está em beta. O cliente de rede vive em
public/js/net.js, com os transportes empublic/js/transporte.js— salas públicas e privadas por código de convite saem do mesmo cliente. Para testar o jogo local sem configurar um servidor multiplayer, comece pelo modo singleplayer. No celular há beta instalável como PWA com controles de toque (public/site.webmanifest).
▶ Jogue: https://www.corosolto.com.br/
O jogo já se chamou CS BRASIL. É o mesmo jogo, e o nome antigo segue registrado como nome alternativo pra quem procura por ele.
Este jogo nasceu gerado por IA a partir de um único prompt — o prompt original está em
docs/historico/PROMPT.md.
| Você é… | Leia |
|---|---|
| curioso | esta página, e depois https://www.corosolto.com.br/ |
| dev novo (ou agente) | docs/README.md → CONTRIBUTING.md |
| quer entender a stack | docs/docs/stack.md — Three.js, Astro, Supabase, geração de asset, skills |
| quer contribuir hoje | issues abertas e CONTRIBUTING.md; confira o estado antes de escolher |
| quer saber o que está quebrado | as issues abertas |
Site de documentação (Docusaurus, com instrumentação de IA, quality gates e
arquitetura): cd docs && npm install && npm start → http://localhost:3000/docs/.
| Camada | Ferramenta | Versão |
|---|---|---|
| Motor 3D (WebGL) | Three.js, vendorizado | r160 |
| Jogo | ES modules vanilla, zero build | 163 arquivos |
| Site | Astro com SSR | ^7.1.1 |
| Hospedagem | adapter Vercel | ^11.0.6 |
| Banco | Postgres gerenciado (RLS; schema privado, fora do repo) | ^2.110.7 |
| Browser nas réguas | Playwright | ^1.62.1 |
| Pipeline de GLB | gltf-transform | ^4.4.1 |
| Compressão de malha | meshoptimizer | ^1.2.0 |
| Imagem (build e API) | sharp · resvg | ^0.35.3 · ^2.6.2 |
| Esta documentação | Docusaurus | 3.10.2 |
| Runtime de CI | Node | 22 |
Three.js sai de public/vendor/three.module.js (sem CDN, sem npm no runtime). Astro e Vercel de package.json + astro.config.mjs + vercel.json. Dos scripts de tools/, 305 importam Playwright, 125 importam gltf-transform e 14 importam meshoptimizer.
Bloco gerado por
node tools/gen-docs.mjs. Fonte:dependencies/devDependencies do package.json · REVISION de public/vendor/three.module.js
O detalhe de cada uma — por que o jogo não tem build, como o asset é gerado (mint.gg, Tripo3D, Meshy, OpenRouter), o que Playwright e gltf-transform fazem aqui, e o que são as skills de agente — está em Stack e ferramentas.
Um repositório, duas zonas com regras diferentes:
public/ · JavaScript vanilla com ES modules, Three.js
vendorizado em public/vendor/ (a revisão está na tabela de stack acima),
zero build. Nunca vira framework.
Não existe public/index.html: o HTML do jogo é src/pages/index.astro,
servido na rota /. (Este README já afirmou o contrário por meses e mandava
todo dev novo para o arquivo errado.)src/ · Astro com SSR na Vercel. Landing,
ranking global, perfis públicos, páginas de conteúdo e as rotas /api/*. Aqui
framework é bem-vindo — mas o jogo continua intocado.O ranking e a telemetria vivem num Postgres gerenciado (schema privado, fora do repo) — o ranking está
desligado por flag hoje, a coleta não parou (ver a seção abaixo). A
service_role key fica só no servidor; a anon key é pública por design, e a
segurança vem das policies e dos grants por coluna.
Sem contagem na árvore abaixo — os números vivem no bloco gerado lá em cima.
Índice por número escrito à mão desatualiza no primeiro commit; é a mesma razão
de o tools/eval/ARCH.md ser gerado.
STATUS.md estado de hoje (leia primeiro)
astro.config.mjs Astro + adapter Vercel · `site` COM www (canonical)
vercel.json build, headers de segurança (CSP…) e cache
src/
layouts/Layout.astro shell do site: nav, footer, CSS global, JSON-LD base
lib/site.ts nome, host, descrições e @id de JSON-LD (fonte única)
lib/supabase.ts client admin (service_role, só no servidor)
lib/safe-url.ts allowlist de avatar + fetch com trava de SSRF
lib/ratelimit.ts rate limit durável (contado no Postgres)
data/jogo.ts armas/mapas/personagens em forma de dado, pro site
pages/index.astro O JOGO, na rota `/`
pages/ranking.astro leaderboard (SSR, com cache de CDN)
pages/u/[...path] perfil público por jogador + badge PNG
pages/sitemap.xml.ts sitemap dinâmico, cobre os perfis
pages/api/* register, submit-match, leaderboard, badge, avatar…
public/ O JOGO (vanilla, zero build)
js/ vendor/ models/ style.css robots.txt llms.txt og-image.png
audio/ ⚠ NÃO versionado — ver "Áudio" abaixo
tools/ pipeline de asset (gen-asset, gen-image, otimização de GLB)
gen-arch.mjs GERA tools/eval/ARCH.md (índice + tabela de conflito)
gen-docs.mjs GERA os blocos numéricos deste README e de docs/
tools/eval/ o arnês de medição e os quality gates de qualidade
docs/ documentação para devs (Docusaurus) + as issues de entrada
.agents/skills/ skills de agente (.claude/skills/ são symlinks pra cá)
Duas pastas NÃO vêm no clone, por decisão registrada: public/audio/ (direitos
incertos) e references/ (telas-alvo da UI e frames de referência, que ficam só na
máquina do dono). O que sobrevive das references/ são os números medidos:
tools/eval/ref_ui.json e tools/eval/ref_viewmodel.json, esses versionados. Régua que
precisa rodar em CI lê o JSON, nunca o PNG.
O site completo (é o modo que você quer — inclui o jogo):
git clone https://github.com/corosolto/client.git
cd client
npm ci
npm run fetch-audio # opcional: sem o pacote, o jogo usa sons sintetizados
npm run dev # http://localhost:4321 — o jogo está em /
Use Node/npm compatíveis com os engines do package-lock.json, incluindo Astro e
suas dependências. A instalação foi conferida em 10/10/2026 com Node 23.6.0 e npm 11.6.0.
Confira node --version e npm --version no mesmo terminal antes de instalar.
Build e preview:
npm run build # gera dist/ (client + server)
npm run preview # serve dist/client estaticamente
python3 -m http.server -d public serve só os assets do jogo — o HTML não
está lá. Use npm run dev.
Comandos atuais do quality gate: veja o bloco gerado no AGENTS.md e em docs/docs/comecando.md.
npm run arch # regenera tools/eval/ARCH.md (índice + tabela de conflito)
npm run docs # regenera os blocos numéricos deste README e de docs/
Nada commita com invariante vermelha. O catálogo do arnês está em
tools/eval/README.md.
Documentação que carrega número é gerada. npm run docs:check (dentro do
check:fast) reprova quando um bloco gerado diverge do código — foi assim que
uma linha afirmando "game.js tem 3.234 linhas" sobreviveu até o arquivo
dobrar de tamanho.
npm run eval:vmenpm run eval:invariantsleem GLBs depublic/models/. Numa árvore sem os assets baixados, os dois falham comENOENT— é ambiente, não regressão.
O repo agora inclui integração project-scoped do Graphify para múltiplos adapters:
agent skills via .agents/Arquivos principais:
AGENTS.md e CLAUDE.md: instruções de uso do grafo.codex/, .claude/, .opencode/, .kimi/, .agents/: skills/config por adaptergraphify-out/graph.json: grafo consultávelgraphify-out/GRAPH_REPORT.md: resumo navegávelgraphify-out/graph.html: visualização local do grafoBuild inicial do grafo:
code-only, local e determinísticoAtualizar depois de mudanças de código:
./scripts/graphify update .
./scripts/graphify cluster-only . --graph ./graphify-out/graph.json --no-label
Regenerar do zero:
./scripts/graphify extract . --code-only --out . --force
./scripts/graphify cluster-only . --graph ./graphify-out/graph.json --no-label
Observação: a versão atual do Graphify extrai este repo muito bem em JS/TS/SQL, mas ainda
reporta parsing parcial em arquivos .astro. Isso é limitação do extrator atual, não do
projeto.
| Tecla | Ação |
|---|---|
| W A S D | Mover |
| Mouse | Mirar |
| Shift | Correr |
| Ctrl ou C | Agachar — mira bem mais estável |
| Espaço | Pular |
| Clique esq. | Atirar |
| Clique dir. | Luneta / ADS |
| R | Recarregar |
| 1 / 2 / 3 | Primária / pistola / faca |
| Z / X / V | Rádio estilo CS (comandos de voz) |
| M | Trocar de time (a qualquer momento) |
| Tab | Placar |
| Esc | Pausar |
Regras, lidas das constantes de public/js/game.js:
| Regra | Valor | Constante |
|---|---|---|
| Grupos · personagens | 7 · 63 (B 9 · C 9 · E 8 · F 9 · M 9 · P 10 · U 9) | CHARACTERS |
| Mapas no menu | 12 — 2 abrem em rodadas, 10 em captura | MAPS menos MAPAS_PARADOS |
| Respawn | 2,2 s | RESPAWN_DELAY |
| Round | 99 s, 3 vitórias | ROUND_TIME / ROUNDS_TO_WIN |
| Captura | alvo = todas as bandeiras do mapa, 2 rodadas (rede de segurança 480 s) | capsToWin = ctfPts.length / CTF_ROUNDS_TO_WIN |
| Regeneração de vida | DESLIGADA — ?regen=1 religa | REGEN |
Ranking / páginas /u/ | DESLIGADOS — é uma flag, volta numa linha | RANKING_ON em src/lib/site.ts |
Bloco gerado por
node tools/gen-docs.mjs. Fonte:constantes de public/js/game.js · RANKING_ON de src/lib/site.ts
O menu aceita de 1 a 8 bots por lado (settings.bots); o padrão é 4×4. O time
com mais abates leva o round. AWP mata com um tiro em qualquer lugar do corpo.
Multikills disparam anúncios estilo Unreal Tournament.
Regeneração de vida está DESLIGADA (decisão do dono, 05/08/2026): vida só
volta com respawn. ?regen=1 religa a regra antiga — inteira, com a simetria
jogador↔bot. Ela foi desligada porque era invisível: sem ícone, sem som e
sem linha nas configurações, e regra que o jogador não percebe é
indistinguível de defeito.
Os mapas registrados, e em que modo cada um abre:
| Id | Nome no menu | Abre em | Arquivo em public/js/ | Linhas |
|---|---|---|---|---|
amazonia | Treta na Amazônia | captura | — | — |
escadao | Escadão (Morro) | captura | — | — |
praca_poderes | Praça dos Três Poderes | rodadas | — | — |
piscina_treta | Piscina da Treta | rodadas | — | — |
loja_h | Loja H (Estacionamento) | captura | — | — |
ferro_velho | Ferro Velho do Zé | captura | — | — |
quebrada | Quebrada (Rua do Baile) | captura | — | — |
corrego | Córrego (Favela de SP) | captura | — | — |
lajes | Lajes (Comunidade) | captura | — | — |
posto_treta | Posto da Treta | captura | — | — |
upa_24h | UPA 24h da Treta | captura | — | — |
velho_oeste | Sertão da Treta | captura | — | — |
12 mapas no menu — 2 abrem em rodadas e 10 em captura. ctfMode abre o mapa em captura, não prende: o jogador troca no menu (é a MOD1). Há 24 arquivos map_*.js em public/js/; mapas em MAPAS_PARADOS ficam fora do menu.
Bloco gerado por
node tools/gen-docs.mjs. Fonte:objeto MAPS menos MAPAS_PARADOS de public/js/maps.js
RANKING_ON = false em src/lib/site.ts. Decisão do dono em
04/08/2026: "vamos desabilitar o ranking por enquanto, depois a gente ajeita".
O motivo é o de sempre nesta base — o modelo é client-authoritative, o placar
é forjável, e publicar classificação forjável é publicar número errado.
É flag, não remoção. Com false:
/ranking e /u/* respondem 200 com aviso + noindex — não 404. As URLs
estão indexadas e vão voltar no mesmo endereço;/api/leaderboard responde {disabled:true}; o cliente não conhece a flag,
ele reage à resposta da API. Uma fonte de verdade, no servidor.O que NÃO parou: a coleta. submit_match continua gravando (valida token,
rate limit por nick/IP/dia, tetos absolutos e consistência física) e a telemetria
nova continua medindo. Quando o ranking voltar, o histórico está lá.
docs/seguranca.mdA correção definitiva é o servidor de jogo escrever com service_role e o RLS
bloquear o cliente; está na fila junto do multiplayer.
public/audio/)A pasta não é versionada: as vozes e memes têm direitos incertos, e o repositório público leva só o código. Sem o pacote, o jogo usa sons sintetizados e funciona normalmente.
npm run fetch-audio # ou: AUDIO_PACK_URL=<zip> bash scripts/fetch-audio.sh
O jogo carrega audio/manifest.json (veja audio/manifest.example.json, esse
sim versionado). Samples originais do CS 1.6 são propriedade da Valve e não
são distribuídos aqui.
site com www no astro.config.mjs — todo canonical sai daí/sitemap.xml dinâmico, cobrindo uma URL por jogadorpublic/robots.txt e public/llms.txtVideoGame com @id estável, mais ItemList,
ProfilePage/Person, HowTo, FAQPage e BreadcrumbList por páginaCache-Control de CDN em /ranking, /u/* e /mapaO código está sob AGPL-3.0 (GNU Affero General Public License, versão 3) — é o que vale hoje, e a fonte é o arquivo LICENSE na raiz do repositório. Nenhum outro arquivo tem autoridade sobre isso.
Bloco gerado por
node tools/gen-docs.mjs. Fonte:título lido do texto do LICENSE, conferido contra o campo license do package.json
Migrado de MIT para AGPL-3.0 em 07/08/2026. As contribuições feitas antes da troca entraram sob MIT — licença permissiva e compatível com a AGPL: elas continuam MIT dentro do todo, e o conjunto é distribuído sob AGPL-3.0. Quem contribuiu antes não perde nada nem precisa de novo consentimento (a direção incompatível seria a inversa).
public/vendor/.Feito para rir, não para brigar.