marcocosta10000 e230c391ad feat(city): add landing gear, cockpit glass, and winglets to aircraft
Implement proper ground clearance and landing gear for all aircraft
types (airliner, regional, prop). Add cockpit glass at the nose,
winglets at wing tips, and configurable propeller blade length.
Wheels now touch the runway surface (y=0) with the fuselage lifted
by clearance values.
2026-10-31 22:40:17 -03:00

City10 — Cidade 3D Virtual com Agentes de IA

City10 é uma plataforma full-stack de simulação urbana 3D com agentes de inteligência artificial, construída sobre Laravel 13 e Three.js. O visualizador3D é jogável no navegador: trânsito semafórico, pedestres, agentes (Prefeito, lojistas), conversas de rua com IA, praças com academia e uma praia com lazer. O raciocínio dos NPCs acontece através da API OpenRouter.ai, restrito a uma lista de modelos gratuitos.

Plataforma operada pela Syspanel — Santa Rita do Sapucaí/MG, Brasil. Contato: contato@syspanel.com.br · WhatsApp: (35) 99226-1684 · www.syspanel.com.br


Visão Geral da Arquitetura

Camada Tecnologia Responsabilidade
Backend / Painel Admin Laravel 13 (PHP ≥ 8.3) Autenticação, API REST, regras de negócio, consentimento LGPD
Banco de Dados MariaDB (MySQL) Persistência de usuários, lojas, agentes, conversas e consentimentos
Cache / Fila Database (sessões/cache/jobs) Sessões, cache, agendamentos e throttle
Frontend 3D Three.js Mundo jogável no navegador (cidade, trânsito, praia, clima)
Tempo Real Polling HTTP + SSE Presence (~2,5 s), chat (~2,5 s) e stream de resposta de NPC (SSE)
Cérebro dos Agentes OpenRouter.ai Raciocínio dos NPCs e conversas com modelos gratuitos

Fase 1 — Plataforma (Entregue)

  • Estrutura Laravel 13 com autenticação diferenciada (Admin / Usuário Comum).
  • Migrations: usuários com role, lojas com coordenadas 3D (pos_x, pos_y, pos_z), agentes de IA e trilha de consentimento legal (LGPD).
  • API REST (Sanctum) para usuários, lojas, agentes, cidade e documentos legais.
  • CAPTCHA matemático próprio (soma), sem dependências externas, nos formulários públicos.
  • Multi-idioma: Português (Brasil), Inglês e Espanhol — selecionável pelo usuário.
  • Termos de Uso, Política de Privacidade e Política de Cookies (LGPD), versionados e com aceite auditável (data, hora, versão, IP).
  • Banner de cookies com link para os Termos de Uso e Privacidade.
  • Página inicial responsiva (desktop e smartphone).

Fase 2 — Mundo 3D Jogável (Entregue)

O visualizador /city carrega o mundo completo em tempo real:

  • Cidade de 72 quarteirões (grade 9 × 8 de blocos de 40 m; bounds −120..160 × −120..120), com rio e ponte a oeste, extensão rodoviária ao sul, casas de jogadores e um conjunto de lugares públicos com letreiros luminosos: hospital, escola, prefeitura, universidade, corpo de bombeiros (prédios cívicos) e supermercado, drogaria, restaurante, cabeleireiro, banco, hotel e shopping (11 lojas no total, todas com placa frontal + letreiro vertical blade).
  • Trânsito: carros, motos, bikes e ônibus com tráfego à direita, loop por quarteirão e semáforos por cruzamento (fases NS/EW com amarelos e all-red; veículos param na linha de parada antes das faixas).
  • Faixas zebradas reais (barras longitudinais paralelas ao fluxo, design MUTCD) com calçadas e meio-fios interrompidos nas travessias — 323 faixas no layout atual.
  • Pedestres com travessia sincronizada ao semáforo; bloqueio de travessia do jogador no vermelho.
  • Praças (1 a cada 4 células) com academia externa: exercícios com pose, efeito em saúde/energia e missão “Shape em dia”.
  • Praia a leste (/city + App\Support\Beach): areia, mar com ondas animadas (deslocamento de vértices), espuma na orla, banhistas, nadadores, surfistas, salva-vidas (torre + patrulha), quadra de basquete com jogadores e bola em arremesso, barracas de comidas, cadeiras e guarda-sóis. O jogador pode relaxar na areia (tecla E → POST /city/actions/beach), recuperando energia/saúde por tick até o máximo.
  • Dois aeroportos derivados dos bounds (pavimento + sinalização de pista com designadores, taxiways com eixo amarelo, pátio de embarque com posições de estacionamento de aeronaves, terminal com pontes articuladas, hangars, torre de controle e helipista): 7 aeronaves de 7 companhias (jato comercial, jato regional, monomotor e helicóptero) executam o ciclo completo taxi → decolagem → cruíse sobre a cidade → aproximação → pouso → taxi → gate, com contagem de decolagens/pousos em stats().flights.
  • Torre de controle com IA: o agente atc "Torre de Controle City10" (modelo AI_ATC_MODEL, poolside/laguna-xs-2.1:free) gera clearances de decolagem a cada decolagem (POST /city/airport/dispatch, cooldown de 30 s) numa cadeia de modelos AI_ATC_MODEL → default → AI_FALLBACK_MODEL (xiaomi/mimo-v2.6-flash), com texto determinístico quando tudo falha; o clearance mais recente aparece como aviso "✈ ...".
  • Agentes vivos: prefeito itinerante, lojistas nas lojas, pedestres com rotas, mais trens (passagem de nível com barreiras), ônibus/trem embarcáveis, avião e barcos no rio.
  • Dia/noite e clima com ciclo de horas, névoa, chuva e sombras que seguem o jogador.
  • Conversas de rua com outros jogadores e NPCs (ver próxima seção).
  • Performance: batching estático por material, sombra seguindo o jogador (janela ±120), lâmpadas/rodas com LOD por distância e fachadas a 256 px — medições ~30–60 fps numa GTX 770.

Controles

Controle Ação
W A S D Andar (A/D = lateral)
Mouse (pointer lock) Olhar; arrastar na cena quando sem lock
← → Viram a câmera (não andam de lado)
Joystick virtual (mobile) Vertical = andar, horizontal = virar a câmera
E Contexto: exercício na praça / relaxar na praia / parar
Espaço Pular
Clique num NPC Abrir chat
Chegar perto de alguém Chat abre sozinho; sai de perto ele fecha

Conversas de Rua (/talk/person) e IA por Personagem

  • Registro por dia: cada fala gravada em person_talks (from/to de character ou agent + talked_on + is_fallback), consultável via GET /talk/person?kind=agent|character&peer=ID.
  • Fio da meada: o histórico completo (dias anteriores + hoje) é enviado como contexto nas respostas de IA — placeholders de erro (is_fallback) ficam visíveis na UI mas nunca entram no contexto do modelo.
  • Quem responde:
    • Par com humano vivo (sessão tocada nos últimos 5 min) → relay puro, nunca é substituído por IA;
    • Par sem humano (cidadãos demo, NPCs) → persona anônima de morador responde via OpenRouter, sem dados cadastrais no payload.
  • Resposta de IA é gerada after-response (não depende de worker de fila), com espaçamento por par, allow-list de modelos, fallback localizado em falha e auditoria em last_decision.
  • Identidade por personagem: colunas em characters — ai_model, ai_age, ai_gender, ai_personality, ai_bio (persona injetada no prompt; recém-criados já nascem com personalidade/idade).
  • Modelo por personagem (ordem de resolução, sempre validado em allowed_models): coluna ai_model → mapa AI_CHARACTER_MODELS (id ou nome) → slot determinístico do pool AI_MODELS → AI_DEFAULT_MODEL.

Requisitos

  • PHP ≥ 8.3 (com pdo_mysql, mbstring, curl, zip, gd, bcmath)
  • Composer 2
  • MariaDB ≥ 10.6 (ou MySQL ≥ 8.0)
  • Node.js ≥ 18 (apenas para assets Vite/Tailwind, opcional na Fase 1)
  • Docker (opcional, para o ambiente dockercity10)

Instalação

1. Dependências PHP

composer install

2. Configuração do ambiente

cp .env.example .env
php artisan key:generate

Edite o .env e configure o banco de dados:

DB_CONNECTION=mariadb
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=<sua_senha>

3. Chave do OpenRouter.ai e modelos

A chave não é versionada. Insira-a apenas no .env local:

OPENROUTER_API_KEY=<sua_chave>
AI_DEFAULT_MODEL=deepseek/deepseek-v4-flash-0731

# Pool de modelos gratuitos distribuídos deterministicamente entre os
# personagens (cada um mantém o próprio modelo estável).
AI_MODELS=deepseek/deepseek-v4-flash-0731,nvidia/nemotron-3.5-lightning:free,liquid/lfm-2.5-2.6b:free,openrouter/free,nvidia/nemotron-3-ultra-550b-a55b:free

# Override por personagem: "nome ou id=modelo" separado por vírgula.
AI_CHARACTER_MODELS=

# AI_ATC_MODEL: default model of the control-tower agent (airport
# clearances: takeoff authorizations). Must be allow-listed.
AI_ATC_MODEL=poolside/laguna-xs-2.1:free

# AI_FALLBACK_MODEL: tried when the preferred model of a call fails
# (owner-approved paid model with near-zero cost).
AI_FALLBACK_MODEL=xiaomi/mimo-v2.6-flash

4. Banco de dados

php artisan migrate --seed

5. Servidor de desenvolvimento

php artisan serve --port=16980

A aplicação ficará disponível em http://localhost:16980.

Ambiente Docker (dockercity10)

O container dockercity10 já expõe a aplicação na porta do host 16980 (container :80, Apache + PHP-FPM) e o MariaDB na porta 16981. Após clonar o projeto em /app (bind-mount), rode as migrations dentro do container:

docker exec -it dockercity10 bash -c "cd /app && php artisan migrate --seed"

Contas de Teste (ambiente de desenvolvimento)

Papel E-mail Senha
Administrador marcocosta@gmx.com Mega886ax
Usuário Comum user@sistema.net User123

⚠️ Estas credenciais são exclusivas para desenvolvimento. Altere-as ou remova-as (php artisan db:seed --class=UserSeeder após ajustar) antes de qualquer implantação em produção.


Testes

php artisan test            # suíte completa (PHPUnit)
./vendor/bin/pint           # formatação de código

Destaques da suíte (testes de recurso): autenticação/LGPD, ações da cidade (exercício, posição com clamp até a orla da praia), social, mercado, missões, conversas de rua (PersonTalkTest — histórico multidiário, resolução de modelo, ausência de PII no payload) e lazer na praia (BeachLeisureTest — geometria no payload, efeitos e zona).


Estrutura de Endpoints da API

Base URL: http://localhost:16980/api (Bearer Sanctum)

Públicos

Método Rota Descrição
GET /auth/captcha Gera desafio matemático (necessário para login/registro)
POST /auth/login Autentica e emite token Sanctum
POST /auth/register Cria conta de usuário comum
GET /legal/documents Lista a versão atual dos documentos legais

Autenticados (Bearer token)

Método Rota Descrição
GET /auth/me Perfil + status de consentimento
PATCH /auth/profile Atualiza nome, idioma ou senha
POST /auth/logout Revoga o token atual
GET /city/world Snapshot da cidade (lojas + agentes com coordenadas 3D)
GET/POST /stores Lista/cria lojas
GET/PUT/DELETE /stores/{id} Gerencia uma loja (dono ou admin)
GET /stores-world/seed Mundo de lojas (seed 3D)
GET /legal/status Status de aceite dos documentos
POST /legal/accept Registra o aceite (auditoria LGPD)
GET /legal/history Histórico de consentimentos do usuário

Somente Administrador

Método Rota Descrição
CRUD /api/users Gestão de usuários
CRUD /api/agents Gestão de agentes de IA
GET /api/agents-meta/models Lista os modelos gratuitos permitidos
GET /api/agents-world/seed Mundo de agentes (seed 3D)
GET/POST /stores, /citizens, /cities, /world Admin web (aprovação de cidadãos, cidades, mundo)

Rotas Web da Cidade (sessão de navegador)

Todas exigem login + termos aceitos.

Método Rota Descrição
GET /city Visualizador 3D (HTML + bundle Three.js)
GET /city/data Payload do mundo: layout, lojas, agentes, praças, prédios, beach
GET /city/presence Cidadãos online (posições, is_me) — throttle 60/min
GET/POST /talk/person Conversas de rua: histórico/contexto e envio (throttle 120 e 30/min)
POST /city/actions/position Sincroniza posição (clamp até a orla da praia)
POST /city/actions/{action} Ações: eat, drink, sleep, wake, work, study, buy, sell, build, apply-job, exercise, stop-exercise, beach, ride, accident…
POST/GET /city/chat/{agent} (+/stream) Conversa com NPC (envio + SSE de resposta)
POST/GET /city/messages/{character} Mensagens assíncronas entre personagens
POST /city/social/{verb} · GET /city/social/inbox Amizade, casamento, filho, inbox
GET /city/airport Sites dos aeroportos, torre (ATC) e clearance atual
POST /city/airport/dispatch Pede um clearance de decolagem à torre (cooldown 30 s)
GET/POST /city/market (/buy, /sell) Mercado
GET/PUT /city/customize Personalização do personagem

Modelos de IA Permitidos

Somente os modelos abaixo podem ser usados (validado no backend em config/ai.php; os quatro últimos foram verificados ao vivo no catálogo do OpenRouter). Exceção aprovada pelo responsável: xiaomi/mimo-v2.6-flash (pago, custo mínimo ~1,4e-7/token, verificado ao vivo) — usado como fallback de todas as cadeias de chamada:

poolside/laguna-m.1:free                cohere/north-mini-code:free
deepseek/deepseek-v4-flash-0731:free    qwen/qwen3.8-27b:free
nvidia/nemotron-3-ultra-550b-a55b:free  nvidia/nemotron-3-super-120b-a12b:free
google/gemma-4-31b-it:free              google/gemma-4-26b-a4b-it:free
openai/gpt-oss-20b:free                 nvidia/nemotron-nano-12b-v2-vl:free
nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free
nvidia/nemotron-3-nano-30b-a3b:free     nvidia/nemotron-nano-9b-v2:free
poolside/laguna-xs-2.1:free             inclusionai/ling-3.0-flash-vl:free
qwen/qwen3.7-flash:free
deepseek/deepseek-v4-flash-0731         nvidia/nemotron-3.5-lightning:free
liquid/lfm-2.5-2.6b:free                openrouter/free
xiaomi/mimo-v2.6-flash                  (fallback — ver nota acima)

Segurança e Conformidade (LGPD)

  • Senhas armazenadas com bcrypt (cast hashed).
  • Tokens de API (Sanctum) revogáveis por usuário.
  • RBAC: papéis admin / user com middleware dedicado.
  • CAPTCHA matemático nos formulários públicos (login/registro).
  • Consentimento auditável: data, hora, versão do documento, IP e user-agent gravados em user_consents (imutáveis).
  • Banner de cookies com opção de aceitar/recusar cookies não essenciais.
  • Direitos do titular (art. 18 LGPD): histórico de consentimentos disponível ao usuário; contato para exercer direitos: contato@syspanel.com.br.
  • IA sem PII: ao chamar o OpenRouter envia-se apenas contexto simulado da cidade e o diálogo/identidade in-world — nunca e-mail, senha ou dados de conta (regras em RULES.md, seção 2).

Licença

Software Proprietário — © 2026 Syspanel. Todos os direitos reservados. Veja o arquivo LICENSE para os termos completos de uso.

Bibliotecas de terceiros utilizadas são compatíveis com uso comercial (por exemplo: Laravel — MIT; Three.js — MIT). O crédito aos autores originais está registrado em RULES.md.


Contato


© 2026 — Todos os direitos reservados — Powered by Syspanel — www.syspanel.com.br

S
Description
No description provided
Readme
33 MiB
Languages
PHP 53.9%
JavaScript 30.2%
Blade 13.4%
HTML 2.3%
Shell 0.1%