# 🌐 Guia de Multiplayer - SevenX Engine
Sistema completo de multiplayer com sincronização de estado, interpolação, predição e suporte 2D/3D.
## 📋 Índice
- [Instalação](#instalação)
- [Conceitos Básicos](#conceitos-básicos)
- [Networking Básico](#networking-básico)
- [Networking Real (QUIC)](#networking-real-quic)
- [Sincronização de Estado](#sincronização-de-estado)
- [Sistema de Lobby](#sistema-de-lobby)
- [Chat](#chat)
- [Exemplos](#exemplos)
- [Melhores Práticas](#melhores-práticas)
---
## 🚀 Instalação
### Modo Básico (Simulado)
```toml
[dependencies]
sevenx_engine = "0.2.7"
```
### Modo Completo (Networking Real)
```toml
[dependencies]
sevenx_engine = { version = "0.2.7", features = ["multiplayer"] }
```
---
## 📚 Conceitos Básicos
### NetworkManager
Gerencia conexões, jogadores e mensagens.
```rust
use sevenx_engine::*;
// Criar host
let mut network = NetworkManager::create_host("player1", "Host");
// Conectar a host
let mut network = NetworkManager::connect_to_host("player2", "Client", "127.0.0.1:8080");
```
### PlayerInfo
Informações de cada jogador:
- **ID**: Identificador único
- **Nome**: Nome do jogador
- **Posição**: (x, y, z) - z=0 para 2D
- **Rotação**: (pitch, yaw, roll)
- **Velocidade**: Para predição
- **Score**: Pontuação
- **Ping**: Latência
- **Team**: Time (opcional)
- **Ready**: Estado de pronto
---
## 🎮 Networking Básico
### 1. Criar Host
```rust
struct MyGame {
network: NetworkManager,
}
impl GameState for MyGame {
fn new() -> Self {
let network = NetworkManager::create_host("player1", "Host");
Self { network }
}
fn update(&mut self, dt: f32, input: &InputHandler, world: &mut World) {
// Atualiza posição
self.network.update_player_position(x, y, z);
// Tick de rede (importante!)
self.network.tick(dt);
}
}
```
### 2. Movimento e Sincronização
```rust
// Atualizar posição
network.update_player_position(100.0, 200.0, 0.0);
// Atualizar rotação (para 3D)
network.update_player_rotation(pitch, yaw, roll);
// Atualizar velocidade (para predição)
network.update_player_velocity(vx, vy, vz);
```
### 3. Ações
```rust
// Enviar ação genérica
network.send_player_action("jump", vec![]);
// Enviar tiro (FPS)
network.send_shoot(
(origin_x, origin_y, origin_z),
(dir_x, dir_y, dir_z)
);
// Enviar interação
network.send_interact("target_player_id");
```
### 4. Obter Jogadores
```rust
// Todos os jogadores
let players = network.get_all_players();
for player in players {
println!("{}: {:?}", player.name, player.position);
}
// Jogador específico
if let Some(player) = network.get_player("player_id") {
println!("Ping: {}ms", player.ping);
}
// Jogadores de um time
let red_team = network.get_team_players("Red");
```
---
## 🌐 Networking Real (QUIC)
### Servidor
```rust
#[cfg(feature = "multiplayer")]
use sevenx_engine::{NetworkServer, NetworkMessage};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "0.0.0.0:8080".parse()?;
let mut server = NetworkServer::new(addr).await?;
loop {
// Aceita conexões
server.accept().await?;
// Broadcast de estado
let state = NetworkMessage::GameState {
tick: 0,
data: vec![],
};
server.broadcast(state).await;
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
}
}
```
### Cliente
```rust
#[cfg(feature = "multiplayer")]
use sevenx_engine::{NetworkClient, NetworkMessage};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "127.0.0.1:8080".parse()?;
let mut client = NetworkClient::new().await?;
client.connect(addr).await?;
loop {
// Envia posição
let msg = NetworkMessage::PlayerMove {
id: "player1".to_string(),
x: 100.0,
y: 200.0,
z: 0.0,
tick: 0,
};
client.send(msg).await?;
// Recebe mensagens
while let Some(msg) = client.try_recv() {
println!("Recebido: {:?}", msg);
}
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
}
}
```
---
## 🔄 Sincronização de Estado
### Interpolação Automática
O sistema interpola automaticamente as posições dos jogadores:
```rust
// Habilitar/desabilitar predição
network.set_prediction(true);
// Configurar taxa de sincronização (Hz)
network.set_sync_rate(30); // 30 atualizações por segundo
```
### Como Funciona
1. **Cliente envia posição** → Servidor
2. **Servidor valida** e atualiza estado
3. **Servidor envia estado** → Todos os clientes
4. **Clientes interpolam** entre posições antigas e novas
5. **Predição** baseada em velocidade
### Exemplo de Interpolação Manual
```rust
// O sistema já faz isso automaticamente, mas você pode customizar:
for player in network.get_all_players() {
// Posição interpolada está em player.position
let (x, y, z) = player.position;
// Velocidade para predição
let (vx, vy, vz) = player.velocity;
}
```
---
## 🏠 Sistema de Lobby
### Criar Lobby
```rust
let lobby = LobbyInfo {
name: "Meu Lobby".to_string(),
max_players: 8,
is_public: true,
game_mode: "Deathmatch".to_string(),
map: "arena_01".to_string(),
password: None,
};
network.update_lobby(lobby);
```
### Sistema de Ready
```rust
// Marcar como pronto
network.set_ready(true);
// Verificar se todos estão prontos
if network.all_players_ready() {
println!("Iniciando jogo!");
}
```
### Times
```rust
// Mudar de time
network.change_team("Red");
// Obter jogadores do time
let red_team = network.get_team_players("Red");
let blue_team = network.get_team_players("Blue");
```
---
## 💬 Chat
### Enviar Mensagens
```rust
// Chat global
network.send_chat("Hello everyone!", ChatChannel::Global);
// Chat de time
network.send_chat("Rush B!", ChatChannel::Team);
// Whisper (privado)
network.send_chat("Secret message", ChatChannel::Whisper("player2".to_string()));
```
### Processar Mensagens
As mensagens são automaticamente processadas no `tick()`, mas você pode capturá-las:
```rust
// No process_messages(), as mensagens de chat são printadas
// Você pode customizar isso modificando o código
```
---
## 📝 Exemplos
### Exemplo 1: Jogo 2D Simples
```rust
use sevenx_engine::*;
struct MultiplayerGame {
network: NetworkManager,
player_pos: (f32, f32),
}
impl GameState for MultiplayerGame {
fn new() -> Self {
let network = NetworkManager::create_host("player1", "Host");
Self {
network,
player_pos: (400.0, 300.0),
}
}
fn update(&mut self, dt: f32, input: &InputHandler, _world: &mut World) {
let speed = 200.0;
// Movimento
if input.is_key_down(KeyCode::KeyW) {
self.player_pos.1 -= speed * dt;
}
if input.is_key_down(KeyCode::KeyS) {
self.player_pos.1 += speed * dt;
}
if input.is_key_down(KeyCode::KeyA) {
self.player_pos.0 -= speed * dt;
}
if input.is_key_down(KeyCode::KeyD) {
self.player_pos.0 += speed * dt;
}
// Sincroniza
self.network.update_player_position(
self.player_pos.0,
self.player_pos.1,
0.0
);
self.network.tick(dt);
}
fn draw(&mut self, _world: &World, frame_buffer: &mut [u8]) {
// Desenha todos os jogadores
for player in self.network.get_all_players() {
let (x, y, _) = player.position;
// Desenhar jogador em (x, y)
}
}
}
```
### Exemplo 2: FPS 3D
```rust
use sevenx_engine::*;
struct FPSGame {
network: NetworkManager,
camera: Camera3D,
renderer3d: Renderer3D,
}
impl GameState for FPSGame {
fn new() -> Self {
let network = NetworkManager::create_host("player1", "Host");
let camera = Camera3D::new(800, 600);
let renderer3d = Renderer3D::new(800, 600);
Self { network, camera, renderer3d }
}
fn update(&mut self, dt: f32, input: &InputHandler, _world: &mut World) {
// Movimento FPS
let speed = 5.0;
let forward = Vec3::new(
self.camera.yaw.sin(),
0.0,
self.camera.yaw.cos()
);
if input.is_key_down(KeyCode::KeyW) {
self.camera.position = self.camera.position + forward * speed * dt;
}
// Rotação com mouse
let (dx, dy) = input.get_mouse_delta();
self.camera.yaw += dx as f32 * 0.002;
self.camera.pitch -= dy as f32 * 0.002;
// Sincroniza
self.network.update_player_position(
self.camera.position.x,
self.camera.position.y,
self.camera.position.z
);
self.network.update_player_rotation(
self.camera.pitch,
self.camera.yaw,
0.0
);
// Atirar
if input.is_mouse_button_pressed(MouseBtn::Left) {
let direction = Vec3::new(
self.camera.yaw.sin() * self.camera.pitch.cos(),
-self.camera.pitch.sin(),
self.camera.yaw.cos() * self.camera.pitch.cos()
);
self.network.send_shoot(
(self.camera.position.x, self.camera.position.y, self.camera.position.z),
(direction.x, direction.y, direction.z)
);
}
self.network.tick(dt);
}
fn draw(&mut self, _world: &World, frame_buffer: &mut [u8]) {
self.renderer3d.clear([135, 206, 235, 255]);
// Renderiza outros jogadores
for player in self.network.get_all_players() {
if player.id == self.network.player_id {
continue; // Não renderiza próprio jogador (FPS)
}
let mesh = Mesh3D::cube(0.6, 1.8, 0.6)
.with_position(Vec3::new(
player.position.0,
player.position.1,
player.position.2
))
.with_color([255, 100, 100, 255]);
self.renderer3d.render_mesh(&mesh, &self.camera);
}
self.renderer3d.present(frame_buffer);
}
}
```
---
## ✅ Melhores Práticas
### 1. Taxa de Atualização
```rust
// Cliente: 60 FPS
// Rede: 20-30 Hz (suficiente)
network.set_sync_rate(30);
```
### 2. Predição
```rust
// Sempre habilite predição para movimento suave
network.set_prediction(true);
// Envie velocidade junto com posição
network.update_player_velocity(vx, vy, vz);
```
### 3. Validação no Servidor
```rust
// Se você é o host, valide ações dos clientes
if network.is_host {
// Verificar se movimento é válido
// Verificar se ação é permitida
// Anti-cheat básico
}
```
### 4. Compressão de Dados
```rust
// Use bincode para serialização eficiente
let data = bincode::serialize(&game_state)?;
network.send_player_action("state_update", data);
```
### 5. Tratamento de Desconexão
```rust
// Verifique conexão
if !network.is_connected() {
println!("Desconectado!");
// Voltar ao menu
}
// Monitore ping
for player in network.get_all_players() {
if player.ping > 500 {
println!("⚠️ {} com lag alto!", player.name);
}
}
```
### 6. Estatísticas
```rust
// Monitore performance
println!("Packets enviados: {}", network.stats.packets_sent);
println!("Packets recebidos: {}", network.stats.packets_received);
println!("Packet loss: {:.2}%", network.stats.packet_loss);
println!("Ping médio: {}ms", network.stats.average_ping);
```
---
## 🎯 Casos de Uso
### Deathmatch
- Times: Red vs Blue
- Scoreboard com kills/deaths
- Respawn automático
### Co-op
- Todos no mesmo time
- Objetivos compartilhados
- Chat de time
### Battle Royale
- Lobby grande (50+ jogadores)
- Zona que diminui
- Loot compartilhado
### Racing
- Sincronização de posição
- Checkpoints
- Tempo real
---
## 🐛 Troubleshooting
### Lag/Dessincronia
```rust
// Aumente taxa de sincronização
network.set_sync_rate(60);
// Verifique ping
for player in network.get_all_players() {
println!("{}: {}ms", player.name, player.ping);
}
```
### Jogadores não aparecem
```rust
// Certifique-se de chamar tick()
network.tick(dt);
// Verifique se jogadores estão conectados
println!("Jogadores: {}", network.player_count());
```
### Mensagens não chegam
```rust
// Processe mensagens
network.process_messages();
// Verifique se está enviando corretamente
network.send_message(msg);
```
---
## 📚 Recursos Adicionais
- [Exemplo Multiplayer 2D](examples/multiplayer_demo.rs)
- [Exemplo FPS Multiplayer](examples/fps_multiplayer.rs)
- [API Reference](API_REFERENCE.md)
---
## 🚀 Próximos Passos
1. **Teste os exemplos**: `cargo run --example multiplayer_demo`
2. **Adicione networking real**: Compile com `--features multiplayer`
3. **Customize**: Adapte para seu jogo
4. **Deploy**: Configure servidor dedicado
---
**Divirta-se criando jogos multiplayer! 🎮**