Nome e Avatar

Resumo

Cada jogador é representado na mesa por um nome e um avatar. Como toda a leitura social do Conduta passa por essa identidade, o sistema impõe regras de validação no cadastro e na troca de nome — protegendo o tom do jogo, evitando confusão entre jogadores e dando peso econômico a quem quiser mudar de identidade depois do primeiro acerto.

Esta nota responde o card de design Definir regras de validação de nome e avatar e depende de Sistema de Nomes Únicos (#159).

Identidade do jogador: display vs. nickname interno

O jogador tem uma única identidade visível — o nome de display. Internamente o sistema mantém uma chave estável separada do que aparece na tela, para que troca de nome não quebre histórico nem referências.

CampoQuem vêMuda?Validações
Nome de displayOutros jogadores, na mesa, chat, HUD, perfilSim, sob a política de troca abaixoRegex, banlist, unicidade
ID internoNinguém — apenas backend, logs, telemetriaNuncaGerado pelo sistema, opaco ao jogador
  • Toda referência de gameplay (votos, habilidades, histórico, banimento, denúncia) usa o ID interno.
  • A camada de UI sempre resolve ID → nome de display no momento da renderização. Trocar de nome não afeta posse de itens, reputação acumulada, denúncias pendentes, nem histórico de partidas.
  • Não existe um “nickname público” separado do nome de display. Um jogador, um nome.

Validação de nome

Tamanho

  • Mínimo: 3 caracteres.
  • Máximo: 15 caracteres.
  • Espaços não fazem parte do conjunto permitido; o nome é uma única palavra contígua.

Conjunto permitido

  • Letras A–Z e a–z.
  • Dígitos 0–9.
  • Letras com acento, desde que aplicados sobre uma letra (ex.: á, ç, ô, ã). Acento diacrítico solto, sem letra-base, não é permitido.
  • Caracteres especiais, restritos a este conjunto: . - _ '.

Conjunto bloqueado

Qualquer ocorrência reprova o nome:

! @ # $ % ¨ & * ( ) + = \ | / ? ° ¹ ² ³ £ ¢ ¬ § ´ ` ~ ^ [ ] { } ª º ; : , < > "
  • Emojis/emotes não são permitidos em nenhuma posição do nome.
  • Acentos diacríticos isolados também caem aqui.

Regex de referência

Implementação canônica do conjunto + tamanho. Vale como contrato entre cliente e backend; o backend é a fonte da verdade.

^[\p{L}\p{M}0-9.\-_']{3,15}$
  • \p{L} cobre letras Unicode (inclui acentuadas), tornando “todos os acentos sobre letra” válidos sem listar cada um.
  • \p{M} permite marcas combinantes apenas quando acopladas a uma letra; combinada com a regra “sem acento solto” abaixo, isso cobre o caso á decomposto sem permitir um acento isolado.
  • O conjunto especial é literal: . - _ ' apenas.

Validações complementares aplicadas além do regex (a regex sozinha não dá conta):

  1. Rejeitar nomes que comecem ou terminem com caractere especial (.-_').
  2. Rejeitar dois caracteres especiais consecutivos.
  3. Rejeitar qualquer codepoint da categoria So (símbolos), Sk ou bloco emoji — captura emote mesmo que escape do regex base.
  4. Normalizar para NFC antes de comparar tamanho e duplicata, para que á decomposto e composto contem como o mesmo nome.

Banlist de palavras ofensivas

Decisão: lista própria com seed de biblioteca pública, aplicada em três camadas. Esse é o padrão usado por Riot, Blizzard, Roblox, Epic e Supercell — uma camada só não cobre o problema, e a indústria converge nesse desenho combinado.

  • Idiomas cobertos no V1: PT-BR e EN. Outros entram só com localização do jogo, e cada idioma exige falante nativo na curadoria — gírias e ataques são culturais, não traduzíveis.
  • Banlist mora em config de backend, recarregável sem deploy de cliente.

Camada 1 — Validação automática no submit

Bloqueio in-line no momento de cadastrar ou trocar de nome.

  • Lista própria forkada de LDNOOBW (LDNOOBW/List-of-Dirty-Naughty-Obscene-and-Otherwise-Bad-Words) para EN, com fork curado para PT-BR. A lista pública resolve cobertura inicial; o fork resolve tom — Conduta é adulto e algumas palavras “feias” do genérico fazem parte do vocabulário do jogo. A curadoria deixa passar tom e bloqueia ataque/discurso de ódio.
  • Allowlist de exceções sobre a banlist para evitar falso-positivo (scunthorpe, assassin, bass, cocktail, analysis). Caminho profissional é manter exceção curada, não relaxar a banlist.
  • Match aplicado depois de normalização agressiva, em ordem:
    1. NFC + casefold.
    2. Strip de separadores permitidos (. - _ ').
    3. Reverso de leet: 4→a, 0→o, 1→i/l, 5→s, @→a, $→s, 3→e, 7→t, !→i.
    4. Colapso de letras repetidas (niiigerniger).
    5. Remoção de zero-width, RTL marks e homóglifos cirílicos/gregos.
  • Resultado da match é score, não booleano: alto → bloqueia no submit; médio → passa mas marca para Camada 2; baixo → passa limpo.

Camada 2 — Re-scan e revisão humana

A banlist evolui. Toda atualização dispara um job que revarre a base de nomes existentes e marca os que agora batem.

  • Marcados (e os “médios” da Camada 1) entram em fila de revisão humana.
  • Confirmado ofensivo → renomeação forçada, sem queimar o free change do jogador e sem disparar cooldown (ver Política de troca de nome).
  • Ferramenta interna pode começar simples: planilha + endpoint admin. SaaS dedicado entra só quando moderação humana virar gargalo.
  • Este passo é o que separa estúdio sério de projeto amador — sem ele, todo nome que passou um dia fica para sempre.

Camada 3 — Denúncia de jogadores

  • Botão de report no perfil e no chat alimenta a mesma fila da Camada 2.
  • Threshold por volume: N denúncias únicas em janela de tempo → auto-suspensão do nome até revisão. V1: 3 denúncias únicas em 24h. Evita que nome ofensivo fique vivo o weekend inteiro esperando moderador.
  • Peso por reputação do denunciante: contas novas ou com histórico de denúncia falsa pesam menos no threshold. Padrão Riot/Blizzard.

O que ficou de fora do V1 (e por quê)

  • AI/LLM como executor automático: nunca decide sozinho sobre conta real. Pode entrar como sinal de triagem na Camada 2 (ex.: OpenAI Moderation API é barato e útil para ranking), mas não como bloqueio direto.
  • SaaS de moderação (Hive, Sightengine, Two Hat/Community Sift — esta última é o padrão-ouro, usada por Roblox e Supercell): só faz sentido quando o jogo passa de ~50k MAU e moderação humana não escala. Avaliar quando a operação justificar, não antes.
  • Sofisticação além do leet básico (typoglycemia, Unicode confusables exóticos, anagramas): entra como melhoria, não como bloqueio do V1.

Tratamento de duplicatas

Decisão: bloqueio, não sufixo numérico.

  • O sistema rejeita qualquer cadastro ou troca para um nome já em uso e devolve erro pedindo outro nome. Não sugere sufixo automático nem cria nikolas2, nikolas3.
  • Razão: o nome é elemento de leitura social — gerar jogador123 automaticamente polui a mesa com nomes parecidos e dilui a identidade. Forçar o jogador a escolher um nome único protege o pilar do jogo.
  • A comparação é case-insensitive e em forma normalizada (NFC + casefold). Nikolas, NIKOLAS e nikolas colidem entre si.
  • A unicidade é garantida pelo backend (índice único na tabela de display name). O cliente só reflete o erro retornado.
  • Liberação do nome após o jogador trocar para outro: não imediata. Há um período de “carência” antes do nome voltar ao pool, para evitar sequestro de identidade logo após troca. Valor exato a definir junto com a tabela de moderação.

Política de troca de nome

TrocaCustoCooldown
Primeira trocaGrátisNenhum
Trocas seguintesR$ 10 convertidos em Propina ou valor intencionalmente alto em Reputação14 dias entre trocas
  • A troca gratuita é única por conta e serve para corrigir o nome inicial sem fricção.
  • A partir da segunda troca, vale o cooldown de 14 dias mesmo que o jogador esteja disposto a pagar — o tempo é uma trava por si só, não só o custo.
  • O preço em soft coin é deliberadamente absurdo: o caminho rápido para trocar é pagar em Propina; Reputação é viável, porém penoso.
  • Renomeação forçada por moderação não consome a troca gratuita do jogador nem dispara cooldown — o jogador continua com o direito ao primeiro free change e fica imediatamente elegível para nova troca.
  • O valor exato em Reputação será fechado junto da tabela geral de preços (ver Economia).

Avatar

⚠️ Sistema desenhado nesta rodada, partindo do campo que já existe. O backend já persiste o avatar como um índice inteiroavatarIndex dentro do objeto PlayerProfile em Cloud Save, gravado pelo PlayerProfileStore e resolvido em partida pelo PlayerProfileResolver. A definição abaixo formaliza o card Definir sistema de Avatar (fonte, moderação, custo, raridade) sobre esse campo, não do zero.

O avatar é o ícone que representa o jogador na mesa, no chat, no HUD e no perfil — o segundo elemento de identidade ao lado do nome.

Modelo: catálogo fechado de ícones (sem upload)

Decisão: o avatar é escolhido de um catálogo curado pelo estúdio, não enviado pelo jogador. Cada entrada é um ícone identificado por índice — o mesmo avatarIndex que o código já grava e resolve.

  • Não há upload de imagem pelo jogador no V1. Toda arte vem do catálogo do jogo.
  • Como o catálogo é fechado e curado na fonte, não existe moderação de imagem por usuário — a curadoria acontece uma vez, na criação do ícone, e não a cada perfil. Isso responde à pergunta de moderação do card: o vetor de conteúdo visual gerado pelo jogador simplesmente não existe nesta versão.
  • O código atual já trata avatar como índice de catálogo: bots recebem um índice aleatório em [0, 8), ou seja, o catálogo embarcado hoje tem ~8 entradas. O sistema abaixo expande esse catálogo e dá regras de obtenção a cada entrada.
  • ⚠️ Se um dia entrar upload de imagem custom (fora do escopo desta decisão), a moderação de imagem volta como pendência — aí com o desenho de UGC que SaaS de moderação cobrem. As camadas de moderação de nome servem de referência de abordagem.

Fontes de obtenção

O jogador acumula ícones por seis trilhos, cobrindo progressão gratuita e compra:

FonteTrilhoLiga com
Subir de nívelGratuito (progressão)Progressão
MissõesGratuito (atividade)Missões e Desafios
ConquistasGratuito (marcos)Histórico e Estatísticas
Compra com ReputaçãoSoft coinReputação
Compra com PropinaHard coinPropina · Catálogo IAP
Compra de PersonagemConteúdoFragmentos de Personagem
  • As três primeiras são desbloqueio por mérito (tempo de jogo, atividade, marcos). As três últimas são aquisição — gasto de moeda ou compra de um personagem que já vem com ícone associado.
  • “Compra de Personagem” entrega o ícone junto do personagem; é o vínculo entre o catálogo de avatar e o de personagens (ver a pergunta ainda aberta sobre “o que é um personagem” em Fragmentos de Personagem).

Categorias temáticas

Eixo de tema do ícone, ortogonal à raridade. Lista inicial, expansível com o conteúdo:

  • Bandeira — país/região do jogador.
  • Conquista — marca um feito específico.
  • Personagem — arte ligada a um personagem do catálogo.
  • Eventos — ícones de evento, em geral de disponibilidade limitada.
  • Nível — marcam faixas de nível de conta.
  • …e por aí vai.

Raridade

Três faixas, definidas por como o ícone é obtido e por quanto tempo fica disponível:

RaridadeComo se obtémDisponibilidade
DesbloqueáveisMissões, conquistas, nível ou desafiosPermanente — sempre obtenível por quem cumprir o requisito
SazonaisTemporadas e eventos (primavera, verão, Halloween, Natal…)Janela limitada; pode (ou não) voltar em temporada futura
ExclusivosItens raros/limitados: apoiadores, beta testers, promoções especiaisNão retornam — funcionam como sinal de status
  • Desbloqueáveis são o piso: recompensam o loop padrão e nunca somem.
  • Sazonais criam urgência e dão motivo para voltar em datas comemorativas.
  • Exclusivos são prova social — quem tem, não consegue depois.

Relação com cosméticos e identidade

  • O avatar é o “ícone de jogador” citado como sink em Catálogo IAP e Propina. Isto resolve, pelo lado do avatar, a pergunta aberta em Propina sobre se “ícone de usuário” e “avatar” seriam conceitos distintos: são o mesmo sistema — um catálogo único de ícones indexados.
  • A Borda de personagem (moldura ao redor do avatar, ver Catálogo IAP e Propina) é um cosmético separado: emoldura o ícone, mas não é o ícone.
  • Equipar um avatar já possuído é livre — sem custo e sem cooldown, ao contrário da troca de nome. O custo está na obtenção do ícone, não em equipá-lo. (A confirmar junto da tabela de preços — ver abaixo.)

O que ainda precisa ser definido

  • Valor exato da troca de nome em Reputação (soft coin).
  • Período de carência antes de um nome liberado voltar ao pool.
  • Conteúdo concreto da banlist curada e processo de revisão (quem aprova, com que cadência).
  • Regra de tratamento para nomes que passam na validação automática mas são denunciados depois (renomeação forçada, suspensão temporária, etc.).
  • Avatar — preço de cada ícone em Reputação e em Propina, fechado junto da tabela geral de preços (ver Economia e Catálogo IAP).
  • Avatar — tamanho-alvo do catálogo além das ~8 entradas já embarcadas, e a arte de cada categoria temática.
  • Avatar — mapeamento personagem → ícone: quais personagens entregam qual avatar; depende da definição de “personagem” ainda aberta em Fragmentos de Personagem.
  • Avatar — consolidar com o sink “Ícone de jogador” de Catálogo IAP: confirmar que é exatamente este sistema, para não manter dois catálogos paralelos.
  • Avatar — rotação dos Sazonais e critério dos Exclusivos (calendário de eventos; regra de apoiador/beta tester/promoção).
  • Avatar — confirmar que equipar um ícone já possuído é livre (sem custo nem cooldown); o custo fica só na obtenção.

Ver Também