Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10603a120f | ||
|
|
a4b1cc8d78 | ||
|
|
a1357fe953 | ||
|
|
693cd4cb00 | ||
|
|
c299a4ae21 | ||
|
|
a620f83dd8 | ||
|
|
18778b3d26 | ||
|
|
fa25dd7307 | ||
|
|
090b530481 |
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 218 KiB After Width: | Height: | Size: 218 KiB |
|
After Width: | Height: | Size: 234 KiB |
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 282 KiB After Width: | Height: | Size: 282 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
|
After Width: | Height: | Size: 234 KiB |
|
After Width: | Height: | Size: 243 KiB |
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 223 KiB |
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 277 KiB |
|
Before Width: | Height: | Size: 203 KiB After Width: | Height: | Size: 203 KiB |
|
After Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 235 KiB |
|
After Width: | Height: | Size: 188 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 398 KiB |
|
After Width: | Height: | Size: 159 KiB |
|
After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 235 KiB After Width: | Height: | Size: 235 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 131 KiB |
|
After Width: | Height: | Size: 226 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 261 KiB After Width: | Height: | Size: 261 KiB |
|
After Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 155 KiB |
|
After Width: | Height: | Size: 202 KiB |
|
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 182 KiB |
|
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
@@ -0,0 +1 @@
|
|||||||
|
56096
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
23ba6490cfcbd10fdd1ca204a8a024301fb00ee50214d88fa21f31a360d74c23
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
<div style="text-align:center;margin-bottom:1.5rem">
|
||||||
|
<h2>🏙️ City10 — Visão da Cidade 3D</h2>
|
||||||
|
<p class="subtitle">Fase 2: Transformar o grid atual em uma cidade viva com ruas, árvores, prédios variados e atmosfera</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h3>O que já existe hoje</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Chão verde com grid</li>
|
||||||
|
<li>Caixas coloridas representando lojas</li>
|
||||||
|
<li>Cápsulas amarelas para agentes</li>
|
||||||
|
<li>Órbita de câmera, zoom, clique para selecionar</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h3>O que vamos adicionar</h3>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Ruas asfaltadas</strong> com calçadas e marcações de trânsito</li>
|
||||||
|
<li><strong>Quadras/blocos</strong> com prédios de fachada variada</li>
|
||||||
|
<li><strong>Árvores, postes, bancos, floreiras</strong> — objetos de cena</li>
|
||||||
|
<li><strong>Prédios residenciais/comerciais</strong> de preenchimento entre as lojas</li>
|
||||||
|
<li><strong>Ciclo dia/noite</strong> com iluminação dinâmica</li>
|
||||||
|
<li><strong>Mini-mapa</strong> no canto da tela</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr style="border-color:var(--border);margin:1.5rem 0">
|
||||||
|
|
||||||
|
<h2 style="text-align:center">Layout da Cidade</h2>
|
||||||
|
<p class="subtitle">Três abordagens para organizar ruas e quarteirões</p>
|
||||||
|
|
||||||
|
<div class="options" style="margin-top:1rem">
|
||||||
|
<div class="option" data-choice="grid" onclick="toggleSelect(this)">
|
||||||
|
<div class="letter">A</div>
|
||||||
|
<div class="content">
|
||||||
|
<h3>Grid Clássico</h3>
|
||||||
|
<p>Ruas formando quadras regulares. Lojas em posições fixas nas esquinas e frentes. Fácil de navegar, previsível, urbano.</p>
|
||||||
|
<p style="color:var(--muted);font-size:.85rem;margin-top:.5rem">✅ Mais simples de gerar, orientação clara</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="option" data-choice="organic" onclick="toggleSelect(this)">
|
||||||
|
<div class="letter">B</div>
|
||||||
|
<div class="content">
|
||||||
|
<h3>Orgânico</h3>
|
||||||
|
<p>Ruas curvas que conectam as lojas existentes. Praça central como ponto focal. Visual mais natural e europeu.</p>
|
||||||
|
<p style="color:var(--muted);font-size:.85rem;margin-top:.5rem">✅ Mais bonito, ❌ Mais complexo de gerar</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="option" data-choice="hybrid" onclick="toggleSelect(this)">
|
||||||
|
<div class="letter">C</div>
|
||||||
|
<div class="content">
|
||||||
|
<h3>Misto (Recomendado)</h3>
|
||||||
|
<p>Grid base com quarteirões de tamanhos variados, praça central, algumas vias diagonais. Combina organização com personalidade.</p>
|
||||||
|
<p style="color:var(--muted);font-size:.85rem;margin-top:.5rem">✅ 👍 Melhor equilíbrio entre beleza e implementação</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p style="margin-top:1.5rem;text-align:center;color:var(--muted)">Clique na sua opção preferida e me diga no terminal se quer ajustar algo.</p>
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
<div style="text-align:center;margin-bottom:1.5rem">
|
||||||
|
<h2>📐 Design — Cidade 3D Fase 2</h2>
|
||||||
|
<p class="subtitle">Arquitetura, componentes, fluxo de dados e testes — revise seção por seção</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<span class="label">1. Arquitetura</span>
|
||||||
|
<p>A cena Three.js passa de <strong>órbita isométrica</strong> para <strong>exploração a pé</strong>. O backend continua o mesmo (Sanctum + <code>/city/data</code>), mas o payload ganha: ruas, prédios gerados, e um streaming de mensagens de chat via <strong>SSE</strong> (Server-Sent Events) por agente — sem dependência nova.</p>
|
||||||
|
<pre style="background:#0b1220;border:1px solid var(--border);border-radius:.5rem;padding:.75rem;overflow:auto;font-size:.8rem">Frontend (Three.js)
|
||||||
|
├── CameraController — WASD + mouse, colisão AABB
|
||||||
|
├── CityGenerator — ruas, quadras, prédios de preenchimento
|
||||||
|
├── CharacterFactory — carrega modelos GLTF por tipo de agente
|
||||||
|
├── HudOverlay — painel POSIÇÃO + minimapa
|
||||||
|
└── ChatPanel — fluxo SSE /city/chat/{agent}
|
||||||
|
|
||||||
|
Backend (Laravel)
|
||||||
|
├── CityViewerController::data() — stores + agents + city layout
|
||||||
|
├── ChatController — SSE endpoint por agente
|
||||||
|
└── AgentThinkJob (queue) — chama OpenRouter, persiste last_decision</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<span class="label">2. Componentes</span>
|
||||||
|
<table style="width:100%;border-collapse:collapse;font-size:.9rem">
|
||||||
|
<tr style="border-bottom:1px solid var(--border)"><td style="padding:.5rem"><strong>CameraController</strong></td><td>Pointer-lock, WASD, gravidade simples, raycast contra colisores AABB de prédios</td></tr>
|
||||||
|
<tr style="border-bottom:1px solid var(--border)"><td style="padding:.5rem"><strong>CityGenerator</strong></td><td>Rua central + quadras laterais a partir das posições das lojas; prédios de preenchimento procedural (seed determinística)</td></tr>
|
||||||
|
<tr style="border-bottom:1px solid var(--border)"><td style="padding:.5rem"><strong>StreetMesh</strong></td><td>Asfalto (canvas texture com faixas), calçada de ladrilho, postes a cada N metros</td></tr>
|
||||||
|
<tr style="border-bottom:1px solid var(--border)"><td style="padding:.5rem"><strong>CharacterFactory</strong></td><td>GLTF por <code>agent.type</code>; fallback: cápsula texturizada. Animação Idle/Walk/Run</td></tr>
|
||||||
|
<tr style="border-bottom:1px solid var(--border)"><td style="padding:.5rem"><strong>HudOverlay</strong></td><td>Painel POSIÇÃO (x,y,z, triângulos) + minimapa 2D no canto</td></tr>
|
||||||
|
<tr><td style="padding:.5rem"><strong>ChatPanel</strong></td><td>Abre ao clicar no NPC; mostra nome, status (pensando/respondendo), mensagens; envia via POST e recebe via SSE</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<span class="label">3. Fluxo de dados</span>
|
||||||
|
<ol>
|
||||||
|
<li>Viewport carrega → <code>GET /city/data</code> → lojas + agentes + layout de ruas</li>
|
||||||
|
<li><code>CityGenerator</code> monta ruas e prédios; prédios de loja ganham fachada custom</li>
|
||||||
|
<li>Usuário anda (WASD) → colisão por AABB → câmera segue</li>
|
||||||
|
<li>Clica em NPC → <code>ChatPanel</code> abre → <code>GET /city/chat/{agent}/stream</code> (SSE)</li>
|
||||||
|
<li>Envia mensagem → <code>POST /city/chat/{agent}</code> → job enfileirado → OpenRouter → persiste <code>last_decision</code> → SSE emite resposta</li>
|
||||||
|
<li>HUD recalcula posição a cada frame</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<span class="label">4. Tratamento de erros</span>
|
||||||
|
<ul>
|
||||||
|
<li>SSE cai → reconexão automática com backoff, indicador "reconectando"</li>
|
||||||
|
<li>OpenRouter falha → <code>error_count++</code>, backoff exponencial, status vira <code>error</code> no painel</li>
|
||||||
|
<li>GLTF ausente → fallback silencioso para cápsula (nunca quebra a cena)</li>
|
||||||
|
<li>Colisão detecta NaN → reposiciona no spawn</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<span class="label">5. Testes</span>
|
||||||
|
<ul>
|
||||||
|
<li><strong>PHPUnit</strong>: <code>CityViewerController::data()</code> retorna layout; <code>ChatController</code> valida input e rate-limit; job persiste <code>last_decision</code></li>
|
||||||
|
<li><strong>JS</strong>: <code>CameraController</code> (colisão, WASD), <code>CityGenerator</code> (determinístico com seed), reconexão SSE</li>
|
||||||
|
<li><strong>Manual</strong>: navegar, colidir, conversar com NPC, verificar HUD</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr style="border-color:var(--border);margin:1.5rem 0">
|
||||||
|
|
||||||
|
<p style="text-align:center"><strong>Esse design está correto? Aprovo para escrever a especificação formal.</strong></p>
|
||||||
|
<div class="options">
|
||||||
|
<div class="option" data-choice="approve" onclick="toggleSelect(this)">
|
||||||
|
<div class="letter">✅</div>
|
||||||
|
<div class="content"><h3>Aprovar design</h3><p>Escrever spec → revisão → plano de implementação</p></div>
|
||||||
|
</div>
|
||||||
|
<div class="option" data-choice="revise" onclick="toggleSelect(this)">
|
||||||
|
<div class="letter">✏️</div>
|
||||||
|
<div class="content"><h3>Revisar</h3><p>Quero mudar algo antes de seguir</p></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||