<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Egon Portolani</title>
    <description>The latest articles on Forem by Egon Portolani (@egon_portolani_58b1e2e99e).</description>
    <link>https://forem.com/egon_portolani_58b1e2e99e</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3826137%2Fefb581c8-7453-46b5-8cb1-11a784381d8d.jpg</url>
      <title>Forem: Egon Portolani</title>
      <link>https://forem.com/egon_portolani_58b1e2e99e</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/egon_portolani_58b1e2e99e"/>
    <language>en</language>
    <item>
      <title>Como Construí um Jogo de Corrida Cyberpunk com Gemini Live AI — e o que aprendi no caminho</title>
      <dc:creator>Egon Portolani</dc:creator>
      <pubDate>Mon, 16 Mar 2026 02:01:28 +0000</pubDate>
      <link>https://forem.com/egon_portolani_58b1e2e99e/como-construi-um-jogo-de-corrida-cyberpunk-com-gemini-live-ai-e-o-que-aprendi-no-caminho-20il</link>
      <guid>https://forem.com/egon_portolani_58b1e2e99e/como-construi-um-jogo-de-corrida-cyberpunk-com-gemini-live-ai-e-o-que-aprendi-no-caminho-20il</guid>
      <description>&lt;p&gt;"This post was created for the purposes of entering the Gemini Live Agent Challenge 2026."&lt;/p&gt;

&lt;h1&gt;
  
  
  Como Construí um Jogo de Corrida Cyberpunk com Gemini Live AI — e o que aprendi no caminho
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;#GeminiLiveAgentChallenge #GoogleCloud #Flutter #GeminiAPI&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Imagine estar correndo às 6h da manhã pelas ruas de Matão, SP, com um coach de IA no seu ouvido dizendo: &lt;em&gt;"Operador, você está a 200 metros de perder o Setor Industrial para um rival. Acelere ou perca o território."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Isso é o &lt;strong&gt;First Runner&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;É um jogo de fitness cyberpunk onde você conquista territórios reais da sua cidade correndo, caminhando ou pedalando — guiado por um coach de IA ao vivo, o &lt;strong&gt;Oráculo&lt;/strong&gt;, alimentado pelo &lt;strong&gt;Gemini 2.5 Flash Native Audio&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Neste post vou contar como construímos isso, os desafios técnicos que quase nos quebraram, e o que aprendemos sobre construir agentes de IA verdadeiramente ao vivo.&lt;/p&gt;




&lt;h2&gt;
  
  
  A ideia: transformar a cidade num tabuleiro vivo
&lt;/h2&gt;

&lt;p&gt;Apps de fitness tradicionais são chatos. Eles registram sua corrida, mostram um gráfico e... é isso. A motivação desaparece em semanas.&lt;/p&gt;

&lt;p&gt;A nossa hipótese foi simples: &lt;strong&gt;e se cada rua da cidade fosse um território para conquistar?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cada quarteirão mapeado pode ser "seu". Você corre o circuito, o app registra via GPS, e aquele território fica pintado com sua cor no mapa de todos os jogadores da região. Se um rival bater seu tempo, ele toma o território. Você perde. Precisa voltar e treinar.&lt;/p&gt;

&lt;p&gt;A mecânica do &lt;strong&gt;First Run&lt;/strong&gt; — ser o primeiro a mapear um circuito — cria uma corrida pela cidade que nunca existiu antes.&lt;/p&gt;

&lt;p&gt;Mas o diferencial real é o &lt;strong&gt;Oráculo&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  O Oráculo: um agente que corre com você
&lt;/h2&gt;

&lt;p&gt;O Oráculo não é um chatbot. Ele é um agente de IA que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ouve você&lt;/strong&gt; enquanto você corre, sem precisar apertar nada&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interrompe e é interrompido&lt;/strong&gt; — barge-in real, não turn-based&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conhece sua localização GPS em tempo real&lt;/strong&gt; — pace, distância, territórios próximos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sabe o estado do jogo&lt;/strong&gt; — quais territórios seus estão ameaçados, quais rivais estão ativos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responde em menos de 1 segundo&lt;/strong&gt; — graças ao Gemini 2.5 Flash Native Audio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quando você está subindo uma ladeira pesada e fala "Oráculo, quanto falta?", ele já sabe sua localização, calcula a distância do próximo checkpoint e responde enquanto você ainda está ofegante. Sem delay. Sem robótico.&lt;/p&gt;

&lt;p&gt;Isso mudou tudo sobre como pensamos na interação homem-IA durante atividade física.&lt;/p&gt;




&lt;h2&gt;
  
  
  A arquitetura: onde as coisas ficaram interessantes (e difíceis)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Flutter App
    │
    ├── PCM Audio (16kHz, raw) ──────────────────────────┐
    │                                                     ▼
    ├── GPS Telemetry (JSON) ──────────► Node.js/Express  ──► Gemini 2.5 Flash
    │                                    (Cloud Run)          Native Audio API
    └── Firestore SDK ◄──────────────── Firebase ◄────────────────────────────
         (territories,                  Firestore
          rankings, clans)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  O pipeline de áudio
&lt;/h3&gt;

&lt;p&gt;O Flutter captura áudio bruto em &lt;strong&gt;PCM 16kHz&lt;/strong&gt; direto do microfone e transmite via &lt;strong&gt;WebSocket&lt;/strong&gt; para o nosso servidor Node.js rodando no &lt;strong&gt;Google Cloud Run&lt;/strong&gt;. Esse servidor orquestra uma sessão bidirecional contínua com o Gemini Live API.&lt;/p&gt;

&lt;p&gt;Por que PCM bruto? Porque qualquer encoding adicional introduz latência. Quando você está correndo e fala algo, você espera resposta imediata — não 800ms depois.&lt;/p&gt;

&lt;h3&gt;
  
  
  O problema do barge-in
&lt;/h3&gt;

&lt;p&gt;Esse foi o desafio mais difícil do projeto inteiro.&lt;/p&gt;

&lt;p&gt;Barge-in significa: você pode interromper o Oráculo no meio de uma frase. Ele para de falar, ouve você, responde. Assim como uma conversa humana real.&lt;/p&gt;

&lt;p&gt;O problema é que no Android, quando o app está reproduzindo áudio (o Oráculo falando), o microfone continua gravando — e ele grava o próprio áudio do app. O resultado? Um loop de feedback onde o Oráculo ouve a si mesmo e fica preso num ciclo.&lt;/p&gt;

&lt;p&gt;A solução envolveu três camadas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;AudioContextAndroid&lt;/code&gt; com &lt;code&gt;gainTransientMayDuck&lt;/code&gt;&lt;/strong&gt; — reduz o volume do speaker quando o microfone está ativo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gerenciamento preciso do audio focus&lt;/strong&gt; no Android para detectar quando o usuário está falando&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lógica de reconexão WebSocket&lt;/strong&gt; com buffer de PCM para não perder chunks de áudio durante a transição&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Semanas para resolver. Mas quando funcionou, a sensação foi de ter um parceiro de corrida real no ouvido.&lt;/p&gt;

&lt;h3&gt;
  
  
  Injeção de telemetria em tempo real
&lt;/h3&gt;

&lt;p&gt;O segundo grande desafio foi fazer o Oráculo &lt;em&gt;realmente&lt;/em&gt; saber onde você está — não de forma genérica ("você está correndo bem!"), mas com contexto tático real.&lt;/p&gt;

&lt;p&gt;A cada 5 segundos, o app injeta silenciosamente um JSON no contexto do Gemini:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pace"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5:32 min/km"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"distance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.3km"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Setor Industrial, Matão SP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nearby_territories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HQ_MATÃO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"owner"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"você"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"threat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nenhuma"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CENTRO_MATÃO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"owner"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rival_07"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"threat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alta"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"heart_rate_estimate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"elevated"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse JSON não quebra a conversa de voz — ele vai como parte do contexto de sistema enquanto o stream de áudio continua. O resultado é que o Oráculo diz coisas como: &lt;em&gt;"O Centro está vermelho. Rival 07 está a 400 metros de você. Se você virar à direita agora, passa pelo território dele antes que ele consolide."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Não é motivação genérica. É tática real baseada em dados reais.&lt;/p&gt;




&lt;h2&gt;
  
  
  Os três tracks do Gemini Live Agent Challenge
&lt;/h2&gt;

&lt;p&gt;Quando soubemos do challenge, percebemos que o First Runner tinha encaixe natural nos três tracks:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Track 1 — Live Agent:&lt;/strong&gt; O Oráculo é o agente. Conversa contínua, barge-in, contexto de GPS em tempo real. É literalmente um agente ao vivo correndo com você.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Track 2 — Creative Storyteller:&lt;/strong&gt; Após cada corrida, o Oráculo narra seu "Mission Debrief" — misturando texto épico com seus stats reais e snapshots do mapa num único output stream multimodal. &lt;em&gt;"Operador Mark V. — você conquistou 3 territórios hoje. O Parque Central foi reclamado às 06:47. Dois rivais tentaram interceptar. Falham."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Track 3 — Interface Navigator:&lt;/strong&gt; O Oráculo recebe screenshots do mapa tático e interpreta zonas vermelhas (territórios ameaçados), alertando o corredor sobre mudanças visuais no HUD em tempo real. Ele literalmente "vê" o mapa e age.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que aprendemos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Native Audio muda tudo.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Usar o Gemini Native Audio ao invés de TTS tradicional foi a decisão mais impactante. O resultado não soa como um assistente de voz — soa como uma entidade que existe. A diferença perceptual é enorme para uma atividade física onde você está em estado de flow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Latência é experiência.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Em um jogo de fitness, 2 segundos de delay é uma eternidade. Você já passou pela esquina, perdeu o contexto, quebrou o ritmo. O Cloud Run com WebSocket persistente foi essencial — sem cold starts, sem overhead de autenticação por request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Contexto &amp;gt; Inteligência.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O Oráculo não é mais "inteligente" do que qualquer outro modelo de linguagem. O que o torna diferente é a qualidade do contexto que injetamos. GPS real + estado do jogo real + histórico da corrida real = respostas que parecem mágica mas são só dados bem estruturados.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. O áudio pipeline é o produto.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A parte "difícil" do First Runner não foi a IA. Foi o pipeline de áudio. PCM buffer management, barge-in sem feedback loop, reconexão resiliente durante corridas em áreas com sinal intermitente. Se o áudio falha, o produto falha. Construa isso primeiro.&lt;/p&gt;




&lt;h2&gt;
  
  
  O modelo de negócio: B2B de tráfego físico
&lt;/h2&gt;

&lt;p&gt;Uma descoberta inesperada durante o desenvolvimento: as corridas criam tráfego físico previsível e recorrente.&lt;/p&gt;

&lt;p&gt;Isso abre um modelo B2B: academias, farmácias, cafeterias e varejistas podem se tornar &lt;strong&gt;pit stops oficiais&lt;/strong&gt; no mapa do First Runner. O Oráculo guia o corredor até esses estabelecimentos com missões contextuais. &lt;em&gt;"Operador, há um kit de hidratação disponível na Farmácia Central a 300 metros. Complete a missão de reabastecimento."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;O Google Maps já está explorando esse espaço com o Ask Maps — vemos o First Runner como a camada de gamificação e IA de voz em cima da infraestrutura de localização que o Google está construindo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stack completa
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Componente&lt;/th&gt;
&lt;th&gt;Tecnologia&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mobile frontend&lt;/td&gt;
&lt;td&gt;Flutter (Dart)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audio streaming&lt;/td&gt;
&lt;td&gt;WebSocket — PCM raw 16kHz&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Node.js / Express no Google Cloud Run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI core&lt;/td&gt;
&lt;td&gt;Gemini 2.5 Flash Native Audio via Google GenAI SDK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;Firebase Firestore (sync em tempo real)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth&lt;/td&gt;
&lt;td&gt;Firebase Authentication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maps&lt;/td&gt;
&lt;td&gt;flutter_map + OpenStreetMap / Nominatim&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web3&lt;/td&gt;
&lt;td&gt;WalletConnect / web3dart&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;App (Android testing):&lt;/strong&gt; &lt;a href="https://play.google.com/apps/testing/com.neonlabs.firstrun" rel="noopener noreferrer"&gt;play.google.com/apps/testing/com.neonlabs.firstrun&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Site oficial:&lt;/strong&gt; &lt;a href="https://www.firstrunner.com.br" rel="noopener noreferrer"&gt;firstrunner.com.br&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/egonportolani/First-Runner" rel="noopener noreferrer"&gt;github.com/egonportolani/First-Runner&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demo video:&lt;/strong&gt; &lt;a href="https://youtu.be/eQhiqb14v0M" rel="noopener noreferrer"&gt;youtu.be/eQhiqb14v0M&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Devpost:&lt;/strong&gt; &lt;a href="https://devpost.com/software/first-runner-app" rel="noopener noreferrer"&gt;devpost.com/software/first-runner-app&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Construído por Egon Henrique Portolani para o Gemini Live Agent Challenge 2026.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;#GeminiLiveAgentChallenge #GoogleCloud #GeminiAPI #Flutter #Firebase&lt;/em&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>gamedev</category>
      <category>gemini</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
