<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom"
>
  <channel>
    <title>Made in Bugs - Blog</title>
    <link>https://www.madeinbugs.com.br/pt-BR/blog</link>
    <description>Artigos técnicos sobre desenvolvimento de jogos pelo estúdio Made in Bugs.</description>
    <language>pt-br</language>
    <lastBuildDate>Thu, 28 May 2026 12:36:17 GMT</lastBuildDate>
    <atom:link href="https://www.madeinbugs.com.br/pt-BR/blog/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title><![CDATA[Polaroid Awards]]></title>
      <link>https://www.madeinbugs.com.br/pt-BR/blog/polaroid-awards</link>
      <guid isPermaLink="true">https://www.madeinbugs.com.br/pt-BR/blog/polaroid-awards</guid>
      <description><![CDATA[Como construímos um sistema de fotografia integrado para festivais]]></description>
      <content:encoded><![CDATA[<h2>15 minutos 🕑</h2>
<p>Descobrimos que essa é a média de tempo que o jogador joga nosso jogo durante um festival. Então, <em>como transformar 15 minutos de gameplay em algo duradouro?</em></p>
<p>Eu estava me perguntando isso alguns dias antes do <em>Fórum Eaí Jogos</em>, que aconteceu no final de abril. <a href="https://www.madeinbugs.com.br/pt-BR/projects/asumi">Asumi: Little Ones</a> é um jogo de <em>fotografia</em>, então pra mim estava óbvio: As <strong>fotos</strong> são duradouras.</p>
<p>Os jogadores sempre querem <strong>mostrar suas melhores fotos</strong>, certo? Só que, quando estamos num evento presencial, <em>como permitir que o jogador compartilhe suas fotos com seus amigos?</em> Não dá pra pedir pra cada um trazer um pendrive!</p>
<p>A resposta veio em um formato inédito e complexo, uma <strong>competição fotográfica</strong> integrada ao jogo.</p>
<p><img src="/assets/blog/polaroid-awards/polaroids.png" alt="Screenshot da câmera do jogo enquanto fotografa um animal"></p>
<h3>O fluxo</h3>
<ol>
<li>Jogador joga a demo no booth do festival</li>
<li>Durante a sessão, ele tira fotos com a câmera do jogo</li>
<li>As fotos vão automaticamente para um <strong>site dedicado</strong> e para o <strong>Discord da comunidade</strong></li>
<li>Outras pessoas votam nas melhores fotos</li>
<li>Anunciamos os vencedores semanas depois, criando engajamento prolongado</li>
</ol>
<hr>
<h2>Requisitos ✅</h2>
<p>Sabíamos que algumas coisas eram necessárias:</p>
<ul>
<li><strong>Zero fricção para o jogador</strong>: fotos sobem sozinhas, sem precisar de login</li>
<li><strong>Anonimato</strong>: cada jogador recebe um código de 5 letras (<code>BAKOM</code>, <code>TIRUP</code>) em vez de nome real</li>
<li><strong>Resiliência offline</strong>: o sistema precisa funcionar mesmo se a internet do evento for instável ou inexistente (<strong>Isso foi mega importante!</strong>)</li>
<li><strong>Votação pública</strong>: pessoas que não foram no evento conseguem votar nas fotos pelo site</li>
</ul>
<hr>
<h2>⚙ A arquitetura ⚙</h2>
<p>Para a mágica, precisamos de: <strong>Unity Engine</strong> (nosso jogo está lá rs), <strong>Supabase</strong> (banco de dados), <strong>Next.js + Vercel</strong>, um Discord bot, <strong>Brevo</strong> para emails personalizados, e, é claro, jogadores para tirar fotos.</p>
<p><img src="/assets/blog/polaroid-awards/diagrama.png" alt="Diagrama de arquitetura"></p>
<h3>Banco de dados</h3>
<p>Criamos um banco de dados online com três tabelas.</p>
<ul>
<li><strong><code>contest_sessions</code></strong> — uma linha por jogador, indexada pelo código de 5 letras</li>
<li><strong><code>contest_pictures</code></strong> — uma linha por foto, com os metadados da foto (espécies de animais visíveis, hora do dia, modo de câmera)</li>
<li><strong><code>contest_votes</code></strong> — votos anônimos vinculados a um fingerprint</li>
</ul>
<h3>Fila offline</h3>
<p>O componente mais crítico do lado Unity é o <code>ContestUploader</code>, uma fila persistente em disco inspirada em message brokers. Quando o jogador tira uma foto, ela é salva localmente e enfileirada em um arquivo JSON. Um loop assíncrono tenta enviar em 4 estágios sequenciais (upload do PNG, insert no banco, post no Discord, done). Cada estágio é idempotente — se o jogo cair entre o estágio 1 e o 2, ao reabrir ele retoma exatamente de onde parou.</p>
<p>Confuso? 😫 Resumo: <strong>Se a internet falhar, o sistema tenta de novo</strong>. Após 5 falhas consecutivas, o item vai para uma <code>dead letter queue</code> , que é um nome técnico para uma queue de itens que falharam. Isso significa que a máquina pode ficar offline por horas — ou dias inteiros — sem perder uma única foto. Ao reconectar, tudo sobe automaticamente.</p>
<p>Na prática, isso nos permitiu operar em eventos <strong>completamente sem internet</strong> (estou olhando pra você, <strong>Gamescom Latam</strong> 🙄).</p>
<hr>
<h2>O site 🌐</h2>
<p>As fotos passam por duas páginas:</p>
<div class="blog-columns">
<div><h3><a href="https://www.madeinbugs.com.br/pt-BR/picture-contest">Página do jogador</a></h3>
<p>O jogador insere seu código de 5 letras e vê todas as fotos da sessão em formato polaroid. Pode <strong>escolher uma foto favorita</strong> para entrar oficialmente na competição.</p>
<br>
<br>
<br><h3><a href="https://www.madeinbugs.com.br/pt-BR/picture-contest/voting">Votação pública</a></h3>
<p>Mostra todas as melhores fotos num grid. <em>Qualquer pessoa pode votar sem login</em> — identificação via fingerprint anônimo 🤓.</p>
</div><p><img src="/assets/blog/polaroid-awards/site.png" alt="Website"></p>
</div><hr>
<h2><a href="https://discord.gg/YX9aDaYwnx">Discord</a> e emails 📩</h2>
<p>No Discord, um bot simples conta todos os votos com ⭐ nas fotos dos jogadores. Serve como canal de votação paralelo ao site.</p>
<p>Para comunicação com os jogadores, usamos <strong>Brevo</strong> para enviar emails personalizados com o link direto para a página de cada pessoa. Quando o stand opera offline, o cruzamento entre email e código é feito por correlação temporal — o timestamp do Forms bate com o <code>created_at</code> da sessão em 1-2 minutos no fluxo natural.</p>
<hr>
<h2>Nem Tudo São Flores + o que aprendemos 🌹</h2>
<p>Eventos são ambientes hostis para software dependente de rede. Internet cai, hotspot morre, firewall bloqueia. Mesmo funcionando offline, <em>um dos stands da Gamescom infelizmente não conseguiu participar da competição</em> 😢</p>
<p>Ainda assim, ficamos muito contentes com todos que conseguiram participar 💖</p>
<p><strong>Foram 165 fotos tiradas</strong>, de <strong>mais de 15 jogadores</strong> participantes. Nunca esperávamos esse nível de participação de um jogo tão novo no mercado.</p>
<p><video src="/assets/blog/polaroid-awards/demo.mp4" autoplay loop muted playsinline></video></p>
<hr>
<p>Tem muito, muito mais coisa que eu poderia falar aqui, <em>como a ferramenta anti-spam e anti-bot, o sistema de randomização do grid de votação e o gerador de senhas únicas</em>, mas o coração do sistema é esse.</p>
<p>O Polaroid Awards continua vivo na nossa comunidade (e nas polaroids que enviamos pelo correio).</p>
<blockquote>
<p>📢 <strong>Quer participar?</strong> Ainda dá tempo de votar até <strong>31 de maio</strong>!
<a href="https://go.madeinbugs.com.br/blog-vote">Vote aqui</a></p>
</blockquote>
<p>Se você está pensando em fazer algo mirabolante parecido para o seu jogo, espero que esse post sirva como mapa e como aviso sobre as pedras no caminho.</p>
]]></content:encoded>
      <pubDate>Sat, 23 May 2026 00:00:00 GMT</pubDate>
      <author>Andress Martin</author>
      <category>engenharia</category>
      <category>eventos</category>
      <category>asumi</category>
      <enclosure url="https://www.madeinbugs.com.br/assets/blog/polaroid-awards/polaroids.png" type="image/png" />
    </item>
  </channel>
</rss>