O Navistron rastreia todas as sessões de jogo — mesmo as que o jogador não registra com um nome. Mas diferente da maioria dos sistemas de analytics, o tracking do Navistron é completamente anônimo por design: sem IP, sem cookies, sem fingerprinting de dispositivo, sem localStorage de identificação. Neste artigo, vamos explorar como esse sistema funciona, quais dados são capturados, como são categorizados e para que servem.
Por Que Rastrear Sessões Anônimas?
Nem todo jogador quer registrar seu nome no ranking. Alguns preferem jogar casualmente sem se comprometer com um nome. Outros simplesmente fecham a aba ao terminar. Sem tracking anônimo, esses jogadores seriam invisíveis — o sistema não saberia quantas partidas realmente acontecem, quais tiers são alcançados, quanto tempo as pessoas jogam, ou qual é a distribuição real de dificuldade.
O tracking anônimo permite que o Navistron tenha métricas completas: o total real de partidas é totalRegistered + totalAnonymous, e estatísticas como tempo médio de jogo ou distribuição de tiers consideram todos os jogadores, não apenas os que registraram score.
Unregistered vs Unknown: Dois Tipos de Sessão Anônima
O Navistron classifica sessões anônimas em dois tipos, baseados na ação do jogador após o game over:
- Unregistered — O jogador viu a tela de game over, teve a oportunidade de digitar um nome, e clicou "Skip". Foi uma decisão consciente de não registrar. Os dados são enviados via
fetchpadrão paraPOST /api/anonymous-sessionscomtype: "Unregistered". - Unknown — O jogador não tomou nenhuma ação. Isso inclui: fechar a aba do navegador, navegar para outra URL, ou clicar em "Jogar de Novo" sem ter clicado Save nem Skip. A razão do abandono é desconhecida (daí o nome).
Essa distinção é valiosa para analytics: uma alta proporção de Unregistered sugere que jogadores estão engajados mas preferem privacidade. Uma alta proporção de Unknown pode indicar que o fluxo de game over não está engajando — o jogador abandona antes de interagir.
O Mecanismo de Captura: pendingSession e sessionResolved
O sistema usa duas variáveis de controle no engine do jogo: pendingSession (objeto com dados da partida) e sessionResolved (flag booleana). Quando a nave é destruída, endGame() cria o pendingSession com 7 campos de gameplay e define sessionResolved = false.
A sessão permanece "pendente" até que uma dessas ações ocorra:
- Save & Ranking — Chama
DB.save()na collectionscores. DefinesessionResolved = true,pendingSession = null. Nenhuma sessão anônima é criada. - Skip — Chama
AnonymousDB.save({ ...pendingSession, type: 'Unregistered' }). DefinesessionResolved = true,pendingSession = null. - beforeunload — Se
pendingSessionexistir e!sessionResolved, chamaAnonymousDB.saveBeacon({ ...pendingSession, type: 'Unknown' }). - startGame() — Se ainda houver sessão não resolvida, salva como
"Unknown"viaAnonymousDB.save()antes de resetar tudo.
Isso garante que toda partida gera dados: ou vai para scores (registrado) ou para anonymous_sessions (anônimo). A única exceção é se o navegador crashar antes do beforeunload ser disparado.
sendBeacon: Coletar Dados ao Fechar a Aba
O navigator.sendBeacon() é a peça-chave para capturar sessões Unknown. Diferente do fetch tradicional (que é cancelado quando a página fecha), o sendBeacon é "fire-and-forget" — o navegador garante que a requisição é enviada mesmo durante a destruição da aba.
No Navistron, o handler de beforeunload serializa os dados do pendingSession em um Blob com tipo application/json e envia para /api/anonymous-sessions. Não há resposta — o sendBeacon não retorna uma Promise. Se a requisição falhar (navegador muito antigo, crash forçado), os dados se perdem silenciosamente — mas na vasta maioria dos casos, funciona.
As sessões Unregistered (Skip) e Unknown por novo jogo usam fetch normal, pois a página continua aberta e pode aguardar a resposta.
Os 9 Campos Capturados por Sessão Anônima
Cada documento na collection anonymous_sessions contém exatamente 9 campos:
- type (String) —
"Unregistered"ou"Unknown". Validado no servidor: valores inválidos são convertidos para"Unknown" - score (Number) — Pontuação final. Default: 0
- tier (Number) — Índice do tier alcançado (0–6). Default: 0
- tierName (String) — Nome legível ("TIER I" a "TIER VII"). Default: "TIER I"
- boosts (Number) — Total de boosts coletados. Default: 0
- spread (Number) — Nível de spread final. Default: 1
- time (Number) — Segundos de sobrevivência (inteiro). Default: 0
- difficulty (Number) — Multiplicador de dificuldade final. Default: 1
- playedAt (Date) — Timestamp gerado no servidor via
new Date()
Note que não há campo name — essa é a diferença fundamental em relação à collection scores. Sessões anônimas não têm identificador de jogador. Todos os campos numéricos são sanitizados com Number() e defaults seguros no servidor.
Validação do Campo type no Servidor
O servidor não confia no cliente para o valor de type. A API de sessões anônimas valida explicitamente: ['Unregistered', 'Unknown'].includes(body.type) ? body.type : 'Unknown'. Se alguém enviar um tipo inventado (ex: "VIP", "Bot" ou qualquer string arbitrária), o servidor converte para "Unknown". Isso previne poluição dos dados de telemetria e garante que os dashboards sempre funcionem com apenas dois tipos.
Privacidade por Design: O Que NÃO É Coletado
O tracking anônimo do Navistron foi projetado para ser o oposto de surveillance analytics:
- Sem endereço IP — Nenhuma API armazena o IP do jogador em nenhuma collection
- Sem cookies — Nenhum cookie de rastreamento é emitido pelo jogo ou pelo site
- Sem device fingerprinting — Nenhum canvas fingerprint, WebGL hash, ou identificador de hardware
- Sem localStorage de tracking — O jogo não persiste identificadores locais entre sessões
- Sem conta ou login — O nome de piloto (apenas em scores registrados) é voluntário e pode ser qualquer texto
- Sem correlação entre sessões — Não há como vincular duas sessões anônimas ao mesmo jogador
O único dado semi-identificável em todo o sistema é o User-Agent, armazenado exclusivamente na collection sponsor_clicks (cliques em links de patrocinadores) — completamente separado das sessões de jogo.
Como os Dados Anônimos São Usados
Os dados da collection anonymous_sessions alimentam vários componentes do sistema:
- Stats Pages — As páginas públicas de estatísticas usam
getAggregatedStats()que combinascores+anonymous_sessionspara calcular o total real de partidas, tempo total jogado e maior score (considerando ambas as fontes) - Dashboard — O dashboard exibe gráficos específicos para sessões anônimas: sessões por dia (empilhadas Unregistered vs Unknown), distribuição de tipo (doughnut), distribuição de tiers e de faixas de score
- API /api/anonymous-sessions GET — Retorna 7 aggregations em paralelo: total de sessões, contagem por tipo, totais/médias de score e tempo, sessões por dia (30 dias), distribuição de tiers, últimas 15 sessões, e distribuição de scores por faixa (0–50, 50–100, ..., 50K+)
Ao combinar registrados e anônimos, o Navistron tem uma visão completa: se os anônimos representam 60% das partidas, o score médio real é diferente do score médio apenas dos registrados (que tendem a ser jogadores mais dedicados).
Impacto na Telemetria: Anônimos vs Registrados
A separação em duas collections permite análises comparativas poderosas. As stats pages mostram totalRegistered vs totalAnonymous lado a lado, revelando a proporção de jogadores que se engajam com o ranking versus os que jogam casualmente.
A função getAggregatedStats(period) executa 9 aggregations em paralelo via Promise.all(), consultando ambas as collections para combinar: tempo total ($sum: '$time' de cada), score mais alto (Math.max entre registrado e anônimo), e contagem total (totalRegistered + totalAnonymous). Pilotos únicos, distribuição de tiers, top jogadores e jogos recentes vêm apenas de scores, pois sessões anônimas não têm nome.
FAQ — Perguntas Frequentes sobre o Tracking Anônimo
Posso jogar sem nenhum dado ser salvo?
Na prática, toda partida finalizada (nave destruída) gera dados de telemetria — via Save, Skip ou beforeunload. No entanto, como os dados são puramente de gameplay (score, tier, tempo) e não contêm nenhuma informação identificável, não há impacto na sua privacidade. É impossível vincular uma sessão anônima a uma pessoa real.
Qual a proporção típica de Unregistered vs Unknown?
Varia conforme o perfil dos jogadores. Unregistered indica que o jogador interagiu com o game over (viu os botões e escolheu Skip). Unknown indica abandono — fechou a aba ou começou novo jogo sem agir. Consulte o dashboard público para ver a distribuição atual.
Os dados anônimos influenciam o ranking?
Não. Sessões anônimas são armazenadas na collection anonymous_sessions, completamente separada da collection scores que alimenta o ranking. Anônimos contribuem apenas para estatísticas agregadas (total de partidas, tempo total, distribuição de dificuldade), nunca para posições no ranking.
O sendBeacon funciona em todos os navegadores?
O navigator.sendBeacon() é suportado por todos os navegadores modernos (Chrome, Firefox, Safari, Edge). Pode não funcionar em navegadores muito antigos ou em cenários extremos (crash forçado do processo). Quando não disponível, a sessão Unknown daquela partida se perde — o que é aceitável dado que são dados agregados, não individuais.
Como uma sessão anônima é diferente de um score registrado?
A diferença é de um campo: scores registrados têm name (nome do piloto), sessões anônimas têm type ("Unregistered"/"Unknown"). Os outros 8 campos (score, tier, tierName, boosts, spread, time, difficulty, playedAt) são idênticos. Ambos usam sanitização server-side e timestamp gerado no servidor.
