Compare commits

..
9 Commits
Author SHA1 Message Date
marcocosta10000 10603a120f chore(test): update file permissions for Playwright MCP artifacts 2026-10-31 15:58:05 -03:00
marcocosta10000 a4b1cc8d78 fix(city): enforce right-hand traffic and refine collision sampling
Every block now circulates clockwise so adjacent blocks use opposite
lanes of a shared road, eliminating contra-mão paths. Collision
detection samples bodies more densely (0.35 step, 0.88 lateral
tolerance) to catch near-misses, and corner radii were increased for
smoother turns.

Also adds cosmetic car details — front/rear license plates, side
mirrors with mounting arms, and a roof trim panel — plus updated
traffic-rule screenshots.
2026-10-24 16:48:33 -03:00
marcocosta10000 a1357fe953 feat(city): add vehicle tail lights, beams and smooth dusk lighting 2026-10-24 16:34:07 -03:00
marcocosta10000 693cd4cb00 gfgfg 2026-10-24 15:42:20 -03:00
marcocosta10000 c299a4ae21 feat(city): implement marketplace, missions, customization and admin dashboard
- Add database migrations for market_listings, missions and character cosmetics
- Create controllers for marketplace, missions, presence and character customization
- Implement admin world dashboard with live platform metrics
- Add feature tests for world functionality
- Include phase 2 design documents and gap analysis
2026-10-17 23:21:23 -03:00
marcocosta10000 a620f83dd8 feat(city): add player marketplace, mission journal, character customization and presence
- Player-to-player marketplace with listings, buying and selling
- Mission system with progress tracking and money rewards
- Character appearance customization (skin, hair, face, beard, accessory)
- Multiplayer presence feed showing nearby citizens in near-real-time
- Admin world dashboard with live platform metrics
- Bus and train transportation with temporary ride state
- Mobile joystick controls and minimap HUD
- Education bonus applied to work salary
2026-10-17 22:51:20 -03:00
marcocosta10000 18778b3d26 fix(city): correct vehicle yaw calculation and expose orientation API
- Extracts yawFromDelta helper to standardize rotation math
- Removes incorrect PI/2 offset causing reverse-facing vehicles
- Accounts for direction sign in shuttle vehicle rotation
- Adds vehicleOrientations() for test validation
2026-10-17 22:25:53 -03:00
marcocosta10000 fa25dd7307 feat(city): add pedestrian traffic signals with walk/wait indicators
- Adds 3D pedestrian signal heads at each intersection corner
- Implements pedestrian signal state logic tied to vehicle traffic phases
- Displays localized wait banner when pedestrian signal is red
- Includes test asset for pedestrian signal visualization
2026-10-17 22:20:34 -03:00
marcocosta10000 090b530481 feat(city): add plaza exercise system with health tracking
- Adds CityPlazas support class for deterministic public plaza generation with outdoor gym equipment
- Implements exercise and stop-exercise actions with proximity validation to equipment
- Introduces health (0-100) and exercise_count attributes to Character model
- Reduces hospital stay duration from two game days to one game hour
- Adds 3D gym equipment rendering (bench, bars, bike, treadmill) in city viewer
- Includes exercise state machine handling in world ticker with energy drain
- Adds comprehensive PlazaExerciseTest and updates HospitalAdmissionTest
- Provides localized UI strings for health HUD and exercise prompts
2026-10-17 22:10:50 -03:00
145 changed files with 3719 additions and 143 deletions
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
Regular → Executable
View File
View File

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 138 KiB

View File

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

View File

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

View File

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

View File

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

View File

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 109 KiB

View File

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

View File

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 109 KiB

View File

Before

Width:  |  Height:  |  Size: 218 KiB

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

View File

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 170 KiB

View File

Before

Width:  |  Height:  |  Size: 282 KiB

After

Width:  |  Height:  |  Size: 282 KiB

View File

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

View File

Before

Width:  |  Height:  |  Size: 223 KiB

After

Width:  |  Height:  |  Size: 223 KiB

View File

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 105 KiB

View File

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

View File

Before

Width:  |  Height:  |  Size: 203 KiB

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

View File

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

View File

Before

Width:  |  Height:  |  Size: 235 KiB

After

Width:  |  Height:  |  Size: 235 KiB

View File

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB

View File

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

Before

Width:  |  Height:  |  Size: 261 KiB

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

View File

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 129 KiB

View File

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

View File

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 182 KiB

View File

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 129 KiB

View File

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

View File

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

View File

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

+1
View File
@@ -0,0 +1 @@
56096
+1
View File
@@ -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>

Some files were not shown because too many files have changed in this diff Show More