Projeto de Servidor Vortrium
★ Em Desenvolvimento ★
Atualizado em: 07 Sep 2026
Melhor visto em 1024x768

▸ BEM-VINDO

Um servidor autoritativo sem uma linha de código herdado.

O L2V atende o cliente retail sem modificação — revisões de protocolo 140 e 152, com conteúdo High Five. O protocolo e a geodata são restrições que herdamos; tudo atrás deles é nosso. O servidor é autoritativo: o cliente envia intenções, nunca estado.

Sem L2J, sem núcleo bifurcado, sem codec escrito à mão. Dezoito módulos Gradle com module-info.java em todos eles, de modo que o compilador é a primeira coisa a recusar uma violação de arquitetura.

Vinte regras invioláveis seguram o desenho no lugar, e metade delas é recusada por uma máquina, não por revisão.

▸ O QUE JÁ FUNCIONA

um cliente real entra, chega ao mundo e anda

Login e jogo são duas portas de um mesmo processo desde o primeiro dia. Tudo abaixo existe no repositório com testes em cima; tudo que não está abaixo não existe, e o roadmap diz isso sem rodeios.

A conversa de login

O handshake herdado por inteiro: bloco RSA de credenciais, fluxo Blowfish, módulo embaralhado. Senhas com Argon2id, limite de taxa por endereço e por conta, recuo a cada falha.

A passagem para o mundo

Lista de servidores, token de sessão de uso único e uma porta de jogo que expira o token na primeira vez que o aceita. Contas nascem de um comando, nunca da porta.

Codec gerado

Cada pacote, enum e primitiva de buffer sai dos arquivos de schema. O schema.lock quebra o build se um campo é removido, reordenado ou muda de tipo, ou se um opcode é renumerado.

Entrar e sair do mundo

Criação, seleção e entrada de personagem contra o Postgres, com templates e itens iniciais do datapack — e o caminho de volta, para a lista de personagens ou para a tela de login.

Tick e zonas

Uma platform thread por zona, um escritor, dois encontros por tick. Uma mensagem postada no tick N é aplicada no tick N+1, sempre.

Movimento em chão real

Movimento resolvido célula a célula contra uma grade de colisão convertida, mapeada em memória fora da heap. A* sobre a mesma grade para as rotas.

Gestão de interesse

Aparecer, mover e sumir saem como CharInfo, MoveToLocation e DeleteObject, decididos por uma grade de células e nunca por uma varredura da zona.

Chat e equipamento

Uma linha de chat e uma troca de equipamento saem pelo mesmo três por três de células. A plateia é respondida na thread que a possui, não juntada na borda.

Pegar e largar

O cliente diz o que está tentando alcançar e onde acha que está; a segunda informação é descartada. A zona mede a distância e decide qual dos dois jogadores chegou primeiro.

Inventário que sobrevive ao restart

O que um personagem carrega é gravado no Postgres e lido de volta na entrada. O contador que dá identidade a cada item também sobrevive ao restart, então a numeração continua em vez de recomeçar.

Dinheiro como saldo

Moeda é um saldo, não uma linha na bolsa, então dinheiro no chão deixou de parecer dinheiro destruído. E dois pacotes não mexem mais na mesma bolsa no mesmo instante.

Razão e transações

Nada pode ser adicionado, removido ou movido sem dizer para onde vai o registro e por quê. Transações se aplicam juntas ou se desfazem de trás para frente dentro de um tick.

Catálogos do datapack

O catálogo de skills e as tabelas de atributos por classe são convertidos do conteúdo do cliente e carregados no boot em estruturas imutáveis. O combate precisa dos dois antes de poder ser escrito.

Alvo

Um jogador consegue mirar em algo, e quem decide no que foi mirado é o servidor. Tudo para que um alvo serve, dano, skills e morte, ainda está pela frente.

Determinismo e replay

Quinhentos ticks sobre sessenta e quatro entidades, com semente, produzem o mesmo hash de estado em toda execução; duas zonas trocando tráfego por quatrocentos ticks também.

A sonda

Instrumentação sobre cada costura que a simulação já expõe, para que um silêncio pare de parecer uma resposta. Não decide nada e só é ligada em nível de debug.

▸ MEDIDO, NÃO PROMETIDO

JMH com o profiler de alocação, dentro do build
24 B
alocados por tick

Independentemente da quantidade de entidades, e zero bytes por entidade por tick. Um teste pergunta à JVM e quebra o build se não for plano.

34 µs
para 1.000 caminhantes

Contra um orçamento de 60.000 µs, com movimento resolvido em uma grade de colisão real.

100
entidades por cliente, no máximo

As 24 mais próximas atualizadas a cada tick, o resto a cada quinto — dê no que der em um cerco.

140 Mbit
para 3.000 jogadores

Onde um broadcast sem gestão custa 380. O gargalo real é a gestão de interesse, não o tick.

▸ POR QUE NÃO PARTIR DO L2J

O L2J viabilizou duas décadas de servidores privados. Ele também é a razão de a maioria deles não poder ser raciocinada. Nada aqui é um fork, um port ou uma faxina nele.

01

Acumulado, não desenhado

Vinte anos de remendos sobre um núcleo que já era engenharia reversa. O comportamento mora em casos especiais, não em um modelo que alguém consiga enunciar.

02

Um codec escrito à mão

Aqui o codec é gerado de um schema versionado e de um lock file, então um campo que se move em silêncio é um build quebrado em vez de um cliente desenhando a coisa errada.

03

Locks e estado global

Um escritor por zona, nenhum estado estático mutável, nenhum lock na simulação — os três recusados pelo ArchUnit, não por convenção.

04

Nada para repetir

Tempo e aleatoriedade injetados tornam a simulação determinística, então um bug de concorrência pode ser reproduzido em vez de discutido.

▸ ARQUITETURA

as dependências apontam para um lado só

O sistema de módulos cobra a direção. O domínio não sabe nada sobre Netty, JDBC, Postgres ou um pacote; o game server é o único módulo que conhece todos os outros.

                   domain  <----- (nothing beyond the JDK)
                      ^
  collision ----------|
  datapack -----------|
                      |
                    world
                      ^
  protocol ---> net --|---> journal
                      |
                persistence
                      ^
                game-server   (composition root)
DEZOITO MÓDULOS
vortrium-bom
vortrium-protocol-schema
vortrium-protocol
vortrium-domain
vortrium-collision
vortrium-geodata
vortrium-content
vortrium-datapack
vortrium-world
vortrium-journal
vortrium-persistence
vortrium-net
vortrium-ops
vortrium-probe
vortrium-testkit
vortrium-conformance
vortrium-login-server
vortrium-game-server
edge funcionando

Netty e framing

Handshake, cifra, framing e despacho no event loop, fixo no número de núcleos. Virtual threads só para trabalho de borda que bloqueia, nunca para lógica de jogo.

protocol funcionando

Schema e codec

Records sob uma interface selada, despacho exaustivo por construção. Nove das dez formas que um formato de fio herdado exige — inclusive contagens que o fio nunca carrega e spans que o próprio codec mede.

simulation em andamento

Tick, zonas, interesse

Armazenamento colunar de entidades em vez de um array de objetos, mapas primitivos, uma free list de slots. Nenhuma alocação por entidade por tick.

domain inicial

Regras puras

Dano, skills, validação de inventário, curvas de experiência. Sem relógio de parede, sem random global, sem entrada nem saída — e sem dependência além do JDK.

collision em andamento

Chão convertido

O cliente retail High Five não traz geodata nenhuma, então a grade é convertida offline a partir de um conjunto de geodata do mesmo mundo. O servidor mapeia o chão e nunca o inventa.

durability desenhado

Journal e outbox

Snapshots write behind para o que pode ser perdido; um log append only com fsync para o que não pode. A confirmação de um evento irreversível espera pelo journal.

observability funcionando

Sonda

Instrumentação que envolve as costuras que a simulação já expõe, registra uma linha e delega. Ligada só em nível de debug, não decide nada, e só a composition root depende dela.

▸ VINTE REGRAS INVIOLÁVEIS

Uma regra sem quem a cobre é uma sugestão, e uma sugestão não sobrevive a seis meses de pressa. Cada regra nomeia o mecanismo que rejeita a violação e diz honestamente se ele já existe.

10
automatizadas
Uma máquina rejeita a violação antes de o commit terminar.
8
parciais
Metade automatizada; as notas nomeiam a metade que não é.
2
pendentes
Seguradas por revisão até existir o código que cada uma protege.
01 Nenhuma entrada ou saída na thread do tick parcial
02 Um único escritor por zona auto
03 O domínio não depende de nada além do JDK auto
04 O servidor é autoritativo; todo pacote é uma intenção pendente
05 Zero alocação no caminho quente em regime auto
06 Determinismo: tempo e aleatoriedade são injetados auto
07 Nenhum estado estático mutável auto
08 O codec é gerado, nunca escrito à mão auto
09 Nenhuma leitura de banco no runtime do jogo parcial
10 Tráfego entre zonas é só mensagem auto
11 O datapack é imutável em runtime auto
12 Um pacote inválido derruba a conexão auto
13 Nenhuma otimização sem medição parcial
14 Preview features ficam fora dos módulos de produção auto
15 Toda mutação de item emite um evento de razão parcial
16 Uma transação de item é atômica dentro de um tick parcial
17 A colisão é convertida de uma fonte, nunca autorada parcial
18 Nenhum broadcast sem gestão de interesse parcial
19 Nenhum buffer por conexão sem limite parcial
20 Um evento irreversível passa por fsync antes de ser confirmado pendente

▸ ROADMAP

nenhuma data prometida

O número acima é o roadmap ponderado por fase, não um palpite sobre o jogo. Combate, skills, NPCs e quests ainda não existem: quase tudo que está pronto é a máquina que vai ter de carregá-los.

LEGENDA
pronto
em andamento
não começou
01

Fundação e conformidade

Divisão em módulos, descritores de módulo, quality gate, as regras como testes.

pronto
02

Protocolo e gerador de codec

Linguagem de schema, codec gerado, schema.lock, fuzzing a cinquenta mil frames por direção.

pronto
03

Servidor de login

Handshake, Argon2id, limite de taxa, diretório de mundos, passagem de sessão, comando de conta.

pronto
04

Runtime do mundo

Laço de tick, zonas, barreiras, armazenamento colunar, replay determinístico.

pronto
05

Entrar e andar

Ciclo de vida do personagem, caminhada com colisão, pathfinding, visão com gestão de interesse, chat e equipamento.

pronto
06

Itens e durabilidade

Inventário, moeda e persistência estão de pé; o journal com fsync atrás deles ainda não.

em andamento
07

O mundo inteiro

Um conversor que faz streaming de três mil regiões, em vez dos tiles que cabem em uma execução.

próximo
08

Combate e skills

O catálogo de skills e as tabelas de atributos por classe carregam no boot e um jogador consegue mirar. Fórmulas High Five, dano, morte e inteligência de NPC ainda estão pela frente.

inicial
09

Sistemas e endgame

Clãs, cercos, olimpíada, instâncias, quests.

não começou
10

Carga e endurecimento

Enxame de bots contra a premissa de custo, revisão de exploits, ferramentas de operação.

em andamento

▸ LICENÇAS

aberto para contribuir, fechado para explorar

O L2V não é open source e não vai virar. O código é privado, e a licença é nominal, intransferível e revogável. O que aconteceu com o L2J não foi ele ser gratuito; foi não existir ninguém que pudesse dizer não. Aqui existe.

O QUE ENCERRA UMA LICENÇA
  1. Redistribuir o código ou um binário, para quem quer que seja, a que preço for.
  2. Manter um fork. Uma mudança sobe para o upstream, ou fica privada e acaba junto com a licença.
  3. Vender qualquer coisa que altere balanceamento de combate.
  4. Ostentar o selo de verificado rodando um core adulterado.
  5. Deixar um exploit conhecido sem patch depois que a correção saiu.
Contribuidor
ler o código e mexer nele
US$ 9 por mês
ou US$ 90 por ano
  • O repositório privado: ler e abrir pull request contra ele.
  • Revisão de quem escreveu as regras pelas quais o seu PR vai passar.
  • As discussões de design, e voto em cada RFC.
  • O datapack convertido e as builds internas, para rodar o que você mudou.
Fundador
conquistado, não vendido
conquistado
os vinte primeiros patches mergeados
  • Tudo que o contribuidor tem, para sempre, sem a mensalidade.
  • Dado por um patch de substância mergeado. Não existe forma de comprar.
  • Uma licença de operador não-comercial, inclusa.
  • Seu nome fica nos créditos independentemente do que aconteça ao projeto depois.
Operador
rodar servidor sem vender nada
US$ 180 por ano
um servidor, sem monetização de espécie alguma
  • Rodar um servidor público. Sem doação, sem loja, sem venda de nada.
  • O selo de build verificada, e listagem no diretório de servidores.
  • Patch de segurança no mesmo dia em que os contribuidores recebem.
  • As ferramentas de conversão do mundo em que o seu servidor roda.
Comercial
rodar servidor e receber por isso
US$ 150 por mês
até 300 jogadores; US$ 400 até 1.000; acima disso negociado
  • Tudo acima, mais o direito de aceitar doação e de vender.
  • Preço por pico de jogadores simultâneos, que o próprio servidor informa.
  • Resposta em um dia útil, e releases antes de virarem públicas.
  • Nada do que você vende pode alterar balanceamento de combate. Isso está na licença.

Os preços são de tabela. Brasil, América Latina e CIS pagam valor regional; peça o seu. As licenças são emitidas na mão, uma conversa de cada vez.

Onde o desenho está escrito

A referência de arquitetura é a fonte da verdade, não um resumo do código — quando as duas discordam, uma delas é um bug e o pull request diz qual. vortrium-conformance é a metade executável das regras. O repositório é privado enquanto o trabalho de protocolo se assenta.