ECS vs POO: Por que a Orientação a Objetos Não Funciona Tão Bem em Jogos
“Herança múltipla com 10 níveis de subclasses, código espaguete, performance patética… isso é o que você ganha tentando fazer jogo com POO pura.” – alguém que tentou e falhou
📜 Um pouco de história…
Se você programou nos anos 90 ou 2000, POO (Programação Orientada a Objetos) era o evangelho. Todo mundo batia na tecla de “encapsulamento, herança e polimorfismo”. E com razão! Para software tradicional – como sistemas de gestão, bancos ou e-commerce – a POO fez maravilhas.
Mas… quando o assunto é jogos, as coisas não são tão simples.
🎮 O problema com jogos
Jogos são um caos.
Você tem milhares de objetos interagindo ao mesmo tempo: projéteis, partículas, inimigos, jogadores, itens no chão, árvores que pegam fogo, sistemas climáticos dinâmicos, IA, física…
Tentar controlar tudo isso com uma árvore de herança tradicional é como tentar segurar um polvo com luvas de boxe.
Imagine:
class Inimigo {
void mover();
void atacar();
}
class InimigoVoando : Inimigo {
void voar();
}
class InimigoComEscudo : Inimigo {
void defender();
}
class InimigoVoandoComEscudo : InimigoVoando, InimigoComEscudo {
// caos absoluto
}
Daqui a pouco você tem classes como InimigoComArmaduraQueVoaAtiraSeEscondeQuandoChove
. Boa sorte mantendo isso.
💡 A virada: ECS
Foi aí que surgiram arquiteturas como o ECS – Entity Component System.
Primeiro popularizado em engines como Unity, mas inspirado por ideias anteriores de Data-Oriented Design, o ECS muda completamente a forma de pensar.
Ele parte de uma ideia radical:
“Herança é um problema. Separar dados de lógica é a solução.”
🧩 Como funciona o ECS?
Em vez de classes, você tem:
- Entities (Entidades) → são apenas IDs, como
42
,102
, etc. - Components (Componentes) → são dados puros. Ex:
Vida(100)
,Posição(x=10, y=5)
,Velocidade(3.5)
- Systems (Sistemas) → são funções que processam dados. Ex:
SistemaDeMovimento
,SistemaDeCombate
É como montar Lego:
[ Entidade #001 ]
- Componente: Vida(100)
- Componente: Posição(0,0)
- Componente: Velocidade(5)
O sistema de movimento pega todas as entidades com Posição
+ Velocidade
e as move. Simples, direto, performático.
Sem herança. Sem acoplamento. Sem dor de cabeça.
🚀 Por que ECS é melhor para jogos?
Vamos ser diretos.
1. Performance absurda. Como os componentes são dados puros, você pode armazená-los em arrays contíguos na memória. Isso significa cache-friendly, simd-friendly, multithread-friendly. Lembra da sua IA travando quando tinha 500 inimigos? ECS não sofre disso.
2. Composição em vez de herança.
Quer que uma entidade voe? Adiciona ComponentePodeVoar
. Quer que pare de voar? Remove. Sem precisar herdar nada.
3. Separação de responsabilidades. Se você estudou Clean Architecture ou DDD, sabe o valor de separar dados de lógica. ECS leva isso ao extremo.
4. Escalabilidade real. Projetos grandes com dezenas de sistemas e centenas de tipos de entidades se mantêm organizados, testáveis e eficientes.
🤔 Mas por que ainda usam POO?
Por inércia. Porque é o que se ensina. Porque é mais fácil de entender no começo. Porque funciona até certo ponto.
Mas, com o tempo, a conta chega. O código vira uma cebola: camadas e camadas de herança e gambiarra tentando adaptar comportamentos emergentes.
🎓 A lição de design
A verdadeira lição aqui não é “POO é ruim”. Não é. POO é ótimo em muitos contextos. Mas em jogos, a composição supera a herança quase sempre.
ECS é uma forma prática de aplicar essa filosofia.
📚 Para se aprofundar:
- Game Programming Patterns – Robert Nystrom
- Engines como Bevy (Rust) e Flecs (C++)
- Palestra do Ryan Hipple onde aborda Scriptable Objects que pode servir para guardar os dados (Components)
💬 Conclusão
Se você quer fazer jogos mais performáticos, mais escaláveis, e mais flexíveis, aprenda ECS. No começo parece complicado. Mas depois que você entende, volta para POO só em último caso.
E lembra: “favor composição ao invés de herança” não é só uma frase bonita. É um grito de socorro vindo de quem já manteve 10 mil linhas de código acoplado por subclasses demais.