Files
City10/README.md
marcocosta10000 46b15ec7be feat(city): add city landmarks, stores, luminous signs, and ATC echo guard
Add university and fire station civic buildings plus 7 new store types,
each with facade and luminous blade signs. Extend landmark material
colors and sign accents. Fix ATC dispatch to reject prompt-echoing AI
responses via heuristic guard. Add CityPlacesTest for collision and
roadway avoidance, and extend AirportTest and SignLabelsTest.
2026-10-31 22:22:44 -03:00

16 KiB
Executable File
Raw Permalink Blame History

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