CORO SOLTO: 최고의 싸움
license: AGPL-3.0
CI
pr-gates
astro
three.js
supabase
vercel
Discord
Telegram
AI 생성 및 AI 친화적입니다. — AI 에이전트와 함께 구축되었으며, 각 커밋에는 누가 작성했는지 표시됩니다 (예고 트레일러 Agent:, 규칙은 CONTRIBUTING.md에 명시):
Claude Fable 5
Claude Opus
Kimi K3
Codex GPT
GLM
Gemini
OpenRouter
Tripo3D
Meshy
mint.gg
CORO SOLTO: Treta Suprema — FPS satírico de navegador com facções brasileiras
Three.js 기반의 무료 브라우저 FPS: 풍자적인 브라질 분파들, 오리지널 캐릭터, 풍자 지도 및 무기를 갖추고 있습니다. 봇과의 전투와 멀티플레이어 베타가 탭에서 바로 가능합니다. 다운로드나 설치 없이 플레이할 수 있습니다.
<!-- BEGIN:GERADO:numeros — não edite à mão, rode `npm run docs` -->
| 무엇 | 얼마나 많은 | 확인 위치 |
|---|
| 게임 코드 | 215개 파일에 걸쳐 83,954 라인 | git ls-files public/js/*.js | xargs wc -l |
| ... | | |
블록은 node tools/gen-docs.mjs로 생성되었습니다. 출처: 각 줄의 오른쪽 열에 있는 명령어
<!-- END:GERADO:numeros -->
멀티플레이어 기능은 베타 버전입니다. 네트워크 클라이언트는 public/js/net.js에 있으며, 전송(transport) 기능은 public/js/transporte.js에 있습니다. 초대 코드를 통해 공용 및 개인 방이 동일한 클라이언트에서 작동합니다. 멀티플레이어 서버를 설정하지 않고 로컬 게임을 테스트하려면 싱글 플레이어 모드부터 시작하세요. 휴대폰에서는 터치 컨트롤이 있는 PWA(Progressive Web App) 형태로 설치 가능한 베타 버전이 있습니다 (public/site.webmanifest).
▶ 플레이하기: https://www.corosolto.com.br/
이 게임은 이미 CS BRASIL이라는 이름을 사용했습니다. 같은 게임이며, 이전 이름은 여전히 검색하는 사람들을 위해 대체 이름으로 등록되어 있습니다.
이 게임은 단 하나의 프롬프트로 AI가 생성하면서 탄생했습니다. 원본 프롬프트는 비공개 리포지토리 progress의 PROMPT.md에 있습니다.
여기서 시작하기
스택(Stack)
| 계층 | 도구 | 버전 |
|---|
| 3D 엔진 (WebGL) | Three.js, 공급업체 버전화됨 (vendorized) | r160 |
| ... | | |
Three.js는 public/vendor/three.module.js에서 가져옵니다 (CDN 없음, 런타임에 npm 사용 안 함). Astro와 Vercel은 package.json + astro.config.mjs + vercel.json을 사용합니다. tools/ 스크립트 중 224개는 Playwright를 가져오고, 114개는 gltf-transform을 가져오며, 17개는 meshoptimizer를 가져옵니다. | | |
이 블록은 node tools/gen-docs.mjs에 의해 생성되었습니다. 출처: package.json의 dependencies/devDependencies · public/vendor/three.module.js의 REVISION
각 요소 — 게임이 빌드되지 않는 이유, 에셋이 어떻게 생성되는지 (mint.gg, Tripo3D, Meshy, OpenRouter), Playwright와 gltf-transform이 여기서 하는 역할, 그리고 에이전트 스킬(agent skills)이 무엇인지 —는 스택 및 도구에 나와 있습니다.
아키텍처
하나의 리포지토리, 서로 다른 규칙을 가진 두 개의 영역:
- 게임 —
public/ · JavaScript 바닐라(vanilla)와 ES 모듈을 사용하며, Three.js로 구현됨
vendorizado된 부분은 public/vendor/에 위치함 (리뷰는 상단 스택 테이블 참조).
빌드 과정 없음 (zero build). 프레임워크가 되는 일은 절대 없음.
public/index.html이 존재하지 않음: 게임의 HTML은 src/pages/index.astro이며, / 경로에서 서비스됨. (이 README는 수개월 동안 이와 반대되는 내용을 주장하며 모든 신규 개발자를 잘못된 파일로 안내했었다.)
- 웹사이트 —
src/ · Vercel에서 SSR(서버 사이드 렌더링)을 사용하는 Astro. 랜딩 페이지, 글로벌 랭킹, 공개 프로필, 콘텐츠 페이지 및 /api/* 경로들이 위치함. 여기서는 프레임워크 사용이 환영되지만 — 게임은 여전히 건드리지 않음.
랭킹과 원격 측정(telemetry) 데이터는 관리형 Postgres에 저장됨 (스키마는 비공개이며, 리포지토리 외부). 랭킹 기능은 오늘 플래그를 통해 비활성화되었지만, 수집 자체는 중단되지 않았음 (아래 섹션 참조). service_role key는 서버에만 존재하며; anon key는 설계상 공개적이고, 보안은 정책(policies)과 컬럼별 권한 부여(grants)를 통해 확보됨.
아래 트리의 카운트에는 포함되지 않음 — 이 숫자들은 위에 생성된 블록에 위치함.
손으로 쓴 숫자 인덱스는 첫 커밋에서 업데이트되므로, tools/eval/ARCH.md가 생성되는 이유와 같은 맥락임.
STATUS.md 오늘의 상태 (먼저 읽기)
astro.config.mjs Astro + adapter Vercel · `site` COM www (정규화된 주소)
vercel.json 빌드, 보안 헤더(CSP 등) 및 캐시 설정
...
두 개의 폴더는 클론 시 포함되지 않음, 이는 기록된 결정에 따른 것임: public/audio/ (권리 불확실)와 references/ (UI의 목표 화면 및 참조 프레임으로, 오직 소유자의 기기에만 존재함). references/에서 살아남는 것은 측정된 숫자들뿐임:
tools/eval/ref_ui.json과 tools/eval/ref_viewmodel.json. 이 파일들은 버전 관리됨. CI 환경에서 실행되는 자(ruler)는 PNG가 아닌 JSON을 읽음.
로컬 환경에서 실행하기
전체 웹사이트 (원하는 모드임 — 게임 포함):
git clone https://github.com/corosolto/client.git
cd client
npm ci
...
Astro 및 그 종속성을 포함하여 package-lock.json의 engines와 호환되는 Node/npm을 사용하십시오. 설치는 2026년 10월 10일에 Node 23.6.0 및 npm 11.6.0으로 확인되었습니다. 설치하기 전에 동일한 터미널에서 node --version과 npm --version을 확인하십시오.
빌드 및 미리보기:
npm run build
npm run preview
python3 -m http.server -d public은 게임의 에셋만 제공합니다—HTML 파일이 없습니다. 대신 npm run dev를 사용하십시오.
품질 게이트 (Quality Gate)
현재 품질 게이트 명령어: AGENTS.md 및 docs/docs/comecando.md에 생성된 블록을 참조하십시오.
npm run arch
npm run docs
빨간색 불변성(invariant)을 가진 것은 커밋하지 마십시오. 아크(arnes) 카탈로그는 tools/eval/README.md에 있습니다.
숫자를 포함하는 문서는 생성됩니다. npm run docs:check (내부의 check:fast)는 생성된 블록이 코드와 다를 경우 실패합니다—이것 덕분에 "game.js가 3,234줄이다"라고 주장하는 한 줄이 파일 크기가 두 배로 커질 때까지 살아남을 수 있었습니다.
npm run eval:vm과 npm run eval:invariants는 public/models/의 GLB를 읽습니다. 다운로드된 에셋이 없는 환경에서는 두 명령어 모두 ENOENT로 실패합니다—이는 회귀(regression)가 아니라 환경 문제입니다.
Graphify를 사용한 지식 그래프 (Knowledge Graph)
이 저장소는 이제 여러 어댑터(adapter)를 위한 프로젝트 범위 통합 Graphify를 포함합니다:
- Claude Code
- Codex
.agents/를 통한 agent skills와 호환되는 어댑터 (OpenCode 및 Kimi의 설정은 2026년 11월에 저장소에서 제외됨)
주요 파일:
AGENTS.md 및 CLAUDE.md: 그래프 사용 지침
.codex/, .claude/, .agents/: 어댑터별 스킬/설정
graphify-out/graph.json: 조회 가능한 그래프
graphify-out/GRAPH_REPORT.md: 탐색 가능한 요약
graphify-out/graph.html: 로컬 그래프 시각화
그래프 초기 빌드:
code-only 모드에서 로컬 및 결정론적으로 생성됨.
- SQL(스키마 및 마이그레이션 포함; 스키마는 공개 트리가 아닌 비공개임)을 포함함.
- 외부 API를 사용하지 않음.
코드 변경 후 업데이트하기:
./scripts/graphify update .
./scripts/graphify cluster-only . --graph ./graphify-out/graph.json --no-label
처음부터 다시 생성하기 (Regenerate from scratch):
./scripts/graphify extract . --code-only --out . --force
./scripts/graphify cluster-only . --graph ./graphify-out/graph.json --no-label
참고 사항: 현재의 Graphify 버전은 이 레포지토리를 JS/TS/SQL 형식으로 매우 잘 추출하지만, .astro 파일에서는 여전히 부분 파싱(partial parsing)을 보고합니다. 이는 프로젝트 자체의 한계가 아니라 현재 추출기(extractor)의 한계입니다.
컨트롤 (Controls)
규칙: public/js/game.js의 상수에서 읽어옴:
<!-- BEGIN:GERADO:regras — não edite à mão, rode `npm run docs` -->
| 규칙 | 값 | 상수 |
|---|
| 그룹 · 캐릭터 | 7 · 63 (B 9 · C 9 · E 8 · F 9 · M 9 · P 10 · U 9) | CHARACTERS |
| ... | | |
블록은 node tools/gen-docs.mjs에 의해 생성되었습니다. 출처: public/js/game.js의 상수 · src/lib/site.ts의 RANKING_ON
<!-- END:GERADO:regras -->
메뉴는 팀당 1개부터 8개의 봇(settings.bots)을 허용합니다. 기본값은 4x4입니다. 가장 많은 처치(kills)를 기록한 팀이 라운드를 가져갑니다. AWP는 신체 어느 부위에서든 한 발로 사살할 수 있습니다. 멀티킬은 Unreal Tournament 스타일의 공지사항을 발생시킵니다.
체력 재생(Regeneration)은 비활성화되었습니다 (소유자 결정, 2026/08/05): 체력은 리스폰 시에만 돌아옵니다. ?regen=1을 사용하면 이전 규칙이 완전히 재개됩니다. 이 규칙은 플레이어와 봇 간의 대칭성을 포함합니다. 이 기능은 눈에 띄지 않았기 때문에 비활성화되었습니다: 아이콘도 없고, 소리도 없고, 설정 항목에도 표시되지 않으며, 플레이어가 인지하지 못하는 규칙은 결함과 구별할 수 없습니다.
등록된 맵 및 각 맵의 진입 방식:
<!-- BEGIN:GERADO:mapas — não edite à mão, rode `npm run docs` -->
|
| Id | 메뉴 이름 | 열리는 곳 | public/js/ 내 파일 |
|---|
amazonia | 아마존의 난투극 | 캡처 | — |
| ... | | | |
메뉴에 14개 지도가 있으며, 이 중 4개는 라운드에서 열리고 10개는 캡처에서 열립니다. ctfMode는 지도를 캡처 모드로 열어주며, 플레이어가 메뉴에서 전환할 수 있게 합니다 (이는 MOD1입니다). public/js/에는 26개의 map_*.js 파일이 있으며, MAPAS_PARADOS에 있는 지도는 메뉴 밖에 위치합니다.
블록은 node tools/gen-docs.mjs로 생성되었습니다. 출처: public/js/maps.js의 MAPS_PARADOS를 제외한 objeto MAPS
<!-- END:GERADO:mapas -->
글로벌 랭킹 — 비활성화
src/lib/site.ts에서 RANKING_ON = false로 설정되어 있습니다. 2026년 8월 4일, 소유자의 결정은 다음과 같습니다: "일단 랭킹을 비활성화하고, 나중에 수정하자."
그 이유는 이 기반 시스템의 늘 그렇듯이 — 모델이 **클라이언트 권한 기반(client-authoritative)**이기 때문에, 점수는 조작 가능하며, 조작 가능한 순위를 게시하는 것은 잘못된 숫자를 공개하는 것과 같습니다.
이는 제거가 아닌 플래그(flag)입니다. false로 설정할 경우:
/ranking 및 /u/*는 **200 응답 코드와 함께 경고 메시지 + noindex**를 반환합니다. 404 오류가 아닙니다. 해당 URL들은 여전히 색인되어 있으며 같은 주소로 돌아올 것입니다;
- 링크가 내비게이션(nav) 및 사이트 푸터에서 사라집니다;
/api/leaderboard는 {disabled:true}를 응답합니다. 클라이언트는 이 플래그에 대해 알 필요가 없으며, API의 응답에 반응할 뿐입니다. 서버 측의 진실 공급원입니다.
멈추지 않은 것: 데이터 수집. submit_match는 계속 기록하며 (토큰 유효성 검사, 닉네임/IP/일별 속도 제한, 절대 상한선 및 물리적 일관성), 새로운 원격 측정(telemetry)은 계속 측정합니다. 랭킹이 돌아올 때까지 기록은 남아있습니다.