Como o 2XKO lida com a jogabilidade online

Conheça a tecnologia usada para deixar o jogo online tão justo, rápido e divertido quanto o offline.

Oi, pessoal! Eu sou Tony Cannon, engenheiro de software sênior principal do 2XKO. Neste artigo, vamos botar as cartas na mesa e mostrar o que estamos fazendo para criar a melhor experiência online possível para vocês.

Vamos falar sobre várias tecnologias, então aí vai um resumo de tudo para quem precisar:

  • Nosso principal objetivo é criar uma experiência online segura e sem atrasos. Para isso, estamos usando vários sistemas diferentes, como arquitetura cliente-servidor, rollback de netcode e algo que chamamos de "modo Jogo Justo".
  • Para nós, antitrapaça é coisa séria. Usamos o Riot Vanguard para garantir que seus oponentes são pessoas reais que não estão usando script.
  • Temos várias ferramentas novas que estão sendo usadas para ajudar a manter nossos sistemas externos funcionando.
    • Usamos algo chamado "Servidor de Validação de Jogo" para rodar uma cópia de cada partida na nuvem, o que reforça a atuação de nossos sistemas de antitrapaça, classificação de habilidade e o modo espectador.
    • O gerenciamento de partidas agora tem a capacidade de procurar partidas em outros saguões, então é possível encontrar um oponente rapidamente mesmo se o seu saguão não está cheio.

Beleza. Vamos lá!

Criado para o online

Prestamos bastante atenção ao quesito "jogabilidade online" desde o início do desenvolvimento do 2XKO. Nossa prioridade ao criar a tecnologia principal do jogo era integrar o GGPO e transferir os testes de jogo para o ambiente online. Na época, o jogo conduzia testes ponto a ponto, mas criamos um pacote proxy no data center da Riot em Las Vegas para que os testes diários fossem rodados na internet de verdade. Afinal, é importante avaliar esse tipo de coisa logo na fase de design. Cada movimento, revezamento, animação e efeito de personagem foi criado e testado pensando no serviço online em primeiro lugar, assim poderíamos garantir que a jogabilidade online seria tão boa quanto a offline.

Arquitetura cliente-servidor

Conforme o desenvolvimento foi progredindo, mudamos o sistema ponto a ponto para uma arquitetura cliente-servidor a fim de melhorar nosso desempenho e expansão de forma mais consistente e de atender às necessidades que partidas com quatro jogadores têm. Em partidas como essas, ao usar a arquitetura servidor-cliente, cada jogador envia e recebe um terço do tráfego que seria usado no sistema ponto a ponto, reduzindo assim requisitos de banda, diminuindo a chance de perda de pacote e melhorando o desempenho geral mesmo em conexões mais fracas. Fora isso, ainda temos muitos outros motivos para usar esse tipo de arquitetura.

Privacidade e proteção de IP

Primeiramente: ao usarmos a arquitetura cliente-servidor, o seu endereço de IP nunca fica exposto a outros jogadores nas partidas, o que é um dos grandes perigos do sistema ponto a ponto. Só de jogar contra outro jogador, você acaba dando a ele a chance de encher sua rede de pacotes, o que força você a desconectar e perder a partida. Ou pior ainda: ao ter seu endereço de IP exposto, você também fica vulnerável a sofrer doxing. Levamos a segurança da nossa comunidade muito a sério, e mudar para a arquitetura cliente-servidor é o melhor jeito de proteger os IPs de todos. 

Autoridade de tempo e comando

O servidor tem outra função importante no sistema: ele serve como uma autoridade de entrada, estado e tempo. Para um desenvolvedor, após fazer o rollback funcionar, o maior fator que afeta a qualidade do netcode é o tamanho do algoritmo que equilibra essa divisão. Ou seja, acabamos tendo que passar uma parte do peso do rollback para o jogador. A ideia por trás dessa divisão é: se eu estou vendo um rollback de três quadros na minha tela, você também tem que ver a mesma quantidade na sua. Se eu estou vendo rollbacks de cinco quadros e você está vendo de um, significa que a divisão não está equilibrada.

Sem entrar em muitos detalhes, para equilibrar essa divisão, precisamos sincronizar os relógios da partida de todos os jogadores. Isso já é difícil de se fazer em uma partida de dois jogadores sob o sistema ponto a ponto. Então pense: o que podemos fazer para garantir que ambos os jogadores estejam vendo a mesma informação? (Momento nerd: tem relação com o "problema dos dois generais", que é provavelmente impossível, mas enfim...) Em uma partida de quatro jogadores, a dificuldade é maior ainda! 

Por isso que o servidor é a autoridade máxima do tempo no jogo. Ao usarmos uma autoridade central que verifica o relógio de cada jogador, conseguimos equilibrar a divisão para todos de um jeito muito melhor.

Modo "Jogo Justo"

Estamos trabalhando em outra funcionalidade, chamada "modo Jogo Justo", para melhorar a experiência online do 2XKO. Todos nós já jogamos contra alguém que estava usando Wi-Fi, dados celulares ou um computador um pouco mais lento. E o que normalmente acontece nesses casos? A partida acaba pausando e travando. Ou pior ainda: você recebe rollbacks gigantescos e vê os personagens se teleportando pela tela. Em uma partida ponto a ponto, esse, infelizmente, é o melhor resultado que conseguimos ter nessas situações. Se o jogo não recebe os comandos dos jogadores de forma mais sincronizada, nem o rollback é capaz de salvar essa questão. E é aí que certas pessoas maliciosas se aproveitam do ocorrido. Um jogador mal-intencionado pode adicionar um botão de atraso no controle dele para induzir uma perda de pacote quando bem entender, ou também pode simplesmente agarrar a barra do Windows no PC pra travar a partida. Ambas as ações vão causar um tremendo atraso, fazendo com que você ative seu combo na hora errada. 

Quando o modo Jogo Justo estiver ativado, o servidor do 2XKO vai dar um período de tempo para os comandos de cada jogador cheguem até ele. Caso os comandos se atrasem, o último que chegou daquele jogador será replicado e a partida continuará normalmente. Isso é muito importante. Afinal, com isso, independentemente do que o seu oponente tente fazer com a rede dele, a sua experiência de jogo não será afetada. Se ele apertar o botão de atraso ou se o Wi-Fi dele cair, você nem vai perceber. No entanto, isso acaba se tornando uma faca de dois gumes. Se a sua conexão de rede falhar por alguns segundos, o oponente pode conseguir usar um combo inesperado contra você.

O Jogo Justo ainda está na fase experimental, e vamos ter que trabalhar muito para calibrá-lo direitinho. Queremos punir trapaceiros que tentam ganhar vantagem com queda de pacotes sem causar problemas para as outras pessoas. Nós vamos avisar quando o sistema estiver totalmente implementado para que a comunidade nos dê o feedback necessário.

Infraestrutura e proteção global

É claro que todas essas melhorias de rede não significariam nada sem um suporte global robusto. Ou seja, vamos usar o poder total da infraestrutura de rede da Riot para fazer tudo isso funcionar. O tráfego de rede do 2XKO vai aproveitar a estrutura do Riot Direct para garantir que seus pacotes cheguem ao servidor com latências mais curtas que as da internet. Os servidores são protegidos pelo Serviço DDoS Generalizado, assim pessoas maliciosas não vão conseguir derrubar a Final de um torneio que você organizou no seu saguão particular. Usamos a Plataforma Provisória de Jogo da Riot para implementar servidores mundiais e garantir que as partidas tenham ping baixo para todos os jogadores nas regiões de lançamento. Nosso objetivo é implementar servidores perto de quase todos os jogadores espalhados ao redor do globo, mas isso vai levar um tempo. Agradecemos toda a paciência de vocês enquanto isso não acontece.

Antitrapaça do Riot Vanguard

Como competições online justas também dependem da integridade das partidas, vamos usar uma rede forte em parceria com uma proteção antitrapaça ainda mais forte. Para isso, usamos o nosso Vanguard, que dificulta a utilização de scripts e bots. Esse software tem nos ajudado muito a diminuir o número de bots no LoL em mais de 99%. Isso garante que seus oponentes são humanos de verdade que não estão trapaceando ao usar coisas como contra-ataques automáticos ou scripts que se aproveitam de erros nos golpes do outro jogador. Porém, preservar a competitividade não é algo que se resolve de uma vez e pronto — é um esforço contínuo. Vamos ficar de olho nisso e adaptar nossas medidas conforme necessário.

Intervalo de comando fixo e ritmo de quadros

Também estamos regulando nossos subsistemas de intervalo de comando e ritmo de quadros para garantir que a mecânica de jogo do 2XKO continue consistente tanto no online quanto no offline e independentemente de você estar usando PC ou console. 

Intervalo de comando

Nosso primeiro truque é adicionar um intervalo de três quadros a todos os comandos. Essa é uma técnica comum que jogos de luta usam para minimizar a duração do rollback. No 2XKO, esse intervalo acontece tanto online quanto offline. Ou seja, o ritmo de combo e a memória muscular construídos ao treinar no offline também funcionarão no modo online. Nós escolhemos essa quantidade (três quadros) anos atrás. Tudo, desde o tempo de punição até o golpe mais rápido no jogo, foi criado e testado pensando nessa aplicação de um intervalo de três quadros por comando, o que significa que o 2XKO roda muito bem independentemente da existência desse intervalo. 

Ritmo de quadros

O segundo truque que usamos foi investir pesado no ritmo de quadros. Esse ritmo dita a rapidez e a consistência com que você consegue simular, renderizar e exibir um quadro. Com um ritmo de quadros inconsistente, você pode notar o vídeo travando bastante ou perceber que seus links de um quadro às vezes simplesmente não saem, mesmo que você faça tudo no momento certo. Temos nos dedicado ao ritmo de quadros tanto para minimizar a latência dos comandos quanto para reduzir as diferenças entre console e PC. Atualmente, o tempo que demora entre você apertar um botão e o resultado aparecer na tela é praticamente idêntico no PC, no PS5 e no Xbox. Isso significa que o 2XKO deve se comportar da mesma forma, esteja você jogando offline, online, no seu PC em casa ou em um console em um evento presencial.

Servidor de validação de jogo (GVS)

Mencionei anteriormente que o servidor do jogo era a maior autoridade em questões do estado do jogo, mas não expliquei exatamente o que isso significa. Os principais beneficiados são os sistemas antitrapaça e antismurf. Todas as partidas competitivas do 2XKO executam outra cópia do jogo no servidor. Por conta disso, em uma partida 2x2, teremos uma quinta cópia do jogo sendo executada na nuvem em tempo real. Chamamos esse elemento de Servidor de Validação do Jogo ou GVS ("Game Validation Server"). 

Os benefícios que ele traz são bem significativos. Primeiro de tudo, o simples fato de termos um servidor nos permite identificar exatamente quem punir se alguém abandonar a partida no meio ou puxar o cabo da internet. Com o GVS, podemos ir um passo além: se a cópia de um jogador for diferente da dos demais devido a algum tipo de manipulação, podemos identificar esse jogador comparando o checksum do estado do jogo dele com o do GVS, neutralizando assim outra forma de forçar um empate ao modificar intencionalmente o estado do jogo. 

O GVS também envia os resultados das partidas para o nosso fluxo de dados downstream. Por exemplo: nós enviamos estatísticas detalhadas de cada partida para os serviços centralizados de ranqueamento da Riot. Esse serviço de ranqueamento processa as estatísticas de fim de partida utilizando o algoritmo TrueSkill 2 da Microsoft para determinar de forma eficiente a classificação de habilidade de um jogador em apenas algumas partidas. Isso acaba trazendo menos sofrimento de partidas desequilibradas, e esperamos que esse esforço reduza drasticamente o uso de contas smurf.

Saguões e espectadores

Além da mecânica de jogo principal, nos dedicamos muito aos sistemas periféricos, dos quais o mais significativo é o sistema de saguão. O ponto alto dos jogos de luta é jogar com um grupo de amigos em casa ou reunidos em um local próximo para por curtir um torneio ou encontro semanal. Os saguões do 2XKO procuram replicar esses sistemas sociais no ambiente online.

Partidas em andamento

Uma das minhas funcionalidades preferidas é poder assistir a uma partida que está em andamento. Ver os outros jogadores em ação é, na verdade, um dos momentos mais importantes do jogo presencial. É uma ótima forma de aprender novas técnicas para o seu personagem, ver quais ferramentas outros jogadores estão usando ou simplesmente torcer pelos seus amigos e contra o adversário que tirou você do torneio. Todas essas sensações são incríveis, e queríamos levá-las para o ambiente online.

Quando uma pessoa em um saguão do 2XKO se aproxima de um fliperama com uma partida em andamento, aparece uma tela acima da cabeça dos jogadores e, em poucos segundos, ela vê o estado exato da partida. Não importa se estão na Seleção de Campeões, começando uma partida ou no último round lutando pelo golpe final que decidirá o vencedor, ela verá exatamente o que os jogadores estão vendo, em tempo quase real — sem sincronizações longas ou atrasos na reprodução —, podendo entrar direto na ação como se estivesse lá desde o começo.

Como funciona o modo espectador no servidor

Para fazer esse sistema de espectador funcionar, foram necessárias muitas experimentações. Os jogos de luta que usam rollback, como o 2XKO, são totalmente determinísticos, então sempre é possível reproduzir o estado de uma partida se você tiver apenas os comandos. Então, se alguém se aproxima de um fliperama e começa a assistir desde o primeiro round, enviamos os comandos em ordem para essa pessoa, e tudo funciona perfeitamente. Mas e se já estivermos no meio da partida? Ainda seria possível enviar todos os comandos para cada espectador e fazer com que avancem rapidamente ao longo da partida até alcançarem o momento atual, mas isso leva muito tempo. Na verdade, as primeiras versões dos saguões do 2XKO, antes do Alpha Lab 1, funcionavam exatamente assim. Esse esquema até funcionava, mas a experiência não era grande coisa. Ter que esperar de 5 a 20 segundos para atualizar a tela fazia com que as pessoas desistissem de usar essa funcionalidade.

Quando o GVS foi implantado, tivemos a oportunidade de fazer algo mais inteligente. Lembrando que o GVS é o sistema que valida o estado do jogo em tempo real no servidor. Quando um jogador começa a assistir a uma partida em andamento, nós não enviamos todos os comandos. Em vez disso, pedimos ao GVS um registro do estado atual do jogo e começamos a enviar os comandos a partir desse ponto. Esse registro (snapshot) é um estado salvo com uso eficiente de memória, contendo apenas as partes determinísticas do sistema. Ele só tem cerca de 50 KB, então chega aos jogadores super-rápido. Em vez de avançar por três minutos de comandos, nós simplesmente carregamos o arquivo de 50 KB, e o jogador fica sincronizado instantaneamente. Parece mágica, pelo menos para mim.

Nós simplesmente não teríamos como desenvolver essa funcionalidade sem a simulação do jogo no servidor. Nas versões de protótipo do modo espectador, pegávamos o registro do primeiro jogador da partida e o enviávamos para o espectador, o que causava todo tipo de problema. Primeiro de tudo, capturar e comprimir o registro é relativamente caro. Em computadores de baixo desempenho, isso se traduzia em uma queda de FPS para o jogador toda vez que alguém começava a assistir. Só isso já é inaceitável. Dá para imaginar perder um golpe porque alguém resolveu começar a assistir à sua partida na hora errada? Além disso, não é seguro. Não queríamos abrir uma brecha para agentes maliciosos criarem um registro contendo algum tipo de ataque de transbordamento de dados ou outro método para comprometer o computador de outro jogador. Todos esses problemas são evitados quando toda origem dos dados do modo espectador é transferida para uma fonte confiável no servidor.

Gerenciamento de partidas entre saguões

Por fim, quero falar sobre a nossa funcionalidade de gerenciamento de partidas entre saguões. Os saguões do 2XKO têm várias maneiras de buscar uma partida: Você pode desafiar diretamente jogadores individuais, sentar em um fliperama e esperar que alguém venha se sentar ao seu lado, colocar sua ficha para "ser o próximo", como nos bons tempos, ou simplesmente pedir ao gerenciador que encontre um adversário para você. 

Isso funciona bem quando o saguão está cheio, mas há algumas exceções. E se todo mundo no seu saguão estiver tranquilo assistindo e só você estiver procurando uma partida? 

No Alpha Lab 1, jogar em um saguão tinha vários aspectos legais, como tabelas de classificação, sequências de vitórias e entrar num jogo em andamento para assistir, mas às vezes isso atrasava o início da partida em casos extremos como esse. Inclusive, para os jogadores que queriam entrar em uma partida online o mais rápido possível, algo como "Encontrar uma partida" no menu principal poderia ter sido uma opção mais rápida, simplesmente porque a busca seria feita em toda a base de jogadores, e não apenas entre os jogadores do saguão atual. 

No Beta Fechado, nós modificamos o gerenciador para buscar partidas em todos os saguões online, e não apenas no que você está no momento. Se ele encontrar uma partida no seu saguão atual, reservamos um fliperama no saguão e enviamos os jogadores para lá. Se a partida encontrada for com um jogador em outro saguão, a experiência é basicamente a mesma. Cada jogador em seu próprio saguão receberá uma reserva em um fliperama para jogar, e nós iremos gerar uma representação holográfica do adversário para que ele ocupe um lugar no fliperama. Quando a partida acaba, os dois jogadores voltam para os seus saguões de origem. Não se preocupe, sua sequência de vitórias ficará intacta. 

Como todos os jogadores de todos os saguões de um bloco ficam na mesma fila do gerenciador entre saguões, encontrar uma partida dentro de um saguão deve ser tão rápido quanto encontrar uma partida pelo menu principal em um sistema sem saguões. O gerenciador é calibrado para encontrar a melhor partida possível dentro de um certo tempo. Se for horário de pico e houver muita gente online, você deve conseguir uma partida equilibrada após apenas alguns segundos de espera. Se for 3h da manhã e simplesmente não houver muita gente para enfrentar, ainda assim tentaremos encontrar uma partida rapidamente, só que a diferença de habilidade entre os jogadores pode ser maior do que você veria nos horários de pico. Esse tipo de espera mais longa fora do horário de pico não é exclusividade do 2XKO; é simplesmente como o gerenciamento de partidas funciona em qualquer jogo online quando a base de jogadores é menor. A forma como priorizamos o tempo até encontrar uma partida versus a diferença de habilidade é ajustável, e adoraríamos receber seu feedback sobre como a experiência está funcionando para você. Queremos deixar tudo completamente ajustado ao longo do Acesso Antecipado.

Pensando no futuro

Abordamos muita coisa neste artigo, então parabéns por ter lido até aqui. Acreditamos fortemente que o jogo online não deve se resumir a ser apenas a segunda melhor forma de curtir um jogo de luta. Cada recurso que desenvolvemos, desde a validação no servidor e o ajuste do rollback até o espectador instantâneo e o gerenciamento de partidas entre saguões, foi pensado para tornar o jogo online tão justo, rápido e divertido quanto o offline. Dito isso, ainda estamos fazendo ajustes, testando e ouvindo atentamente o feedback de vocês nesta jornada rumo ao Acesso Antecipado e além. Contem o que estão achando e continuem mandando seus relatos de bugs e sugestões para nós.

Agradecemos por terem lido,

Tony Cannon