Jogue 2 vs 2 e 3 vs 3: o modo equipe
Junte-se a um amigo, combinem suas propriedades e vençam juntos — o opolyx agora tem partidas em equipe 2×2 e 3×3.

Em palavras simples
Algumas partidas são melhores com um parceiro. O modo equipe coloca dois lados frente a frente — 2 vs 2 numa partida de quatro jogadores ou 3 vs 3 numa de seis — para que você e seus amigos joguem por uma cor, e não apenas por si mesmos.
Estar do mesmo lado muda tudo na forma como vocês jogam juntos. Seus companheiros de equipe são aliados, não rivais, então o tabuleiro se abre:
- Se você cair na propriedade de um companheiro de equipe, não paga nada — o aluguel só é cobrado da outra equipe.
- Passem dinheiro e propriedades entre companheiros de equipe à vontade — não existe a regra dos 50%, então você pode simplesmente dar de presente a um parceiro em apuros aquilo de que ele precisa.
- Se um companheiro de equipe falir, todo o patrimônio dele vai para você, não para o banco — uma equipe só está fora quando todos os seus membros se foram.
- Vocês vencem como equipe: o último lado de pé, ou o lado mais rico quando o limite de rodadas chega — e ambos os companheiros de equipe recebem a recompensa de vitória (XP e uma carta).
Coordenem suas trocas, deem cobertura uns aos outros e espremam a equipe rival para fora do tabuleiro juntos. É o mesmo opolyx que você conhece — com um parceiro do seu lado.
Para os mais técnicos
O modo equipe é o conjunto de regras Classic com um novo conceito por jogador: a equipe. O motor ganha um campo PlayerState.team e um punhado de seletores (sameTeam, teamOf, aliveTeams, teamNetWorth) que as regras leem: computeRent isenta os companheiros de equipe, doProposeTrade pula a regra dos 50% entre eles, e a eliminação encaminha o patrimônio para o companheiro de equipe vivo de menor slot, em vez do banco. As condições de fim são avaliadas por equipe — a última equipe de pé, ou a equipe mais rica no teto de rodadas.
Três migrações o implementam. O Postgres proíbe usar um novo valor de enum na mesma transação que o adiciona, então a 0028 confirma o game_mode da equipe sozinha; em seguida a 0029 deixa create_game aceitá-lo (com uma verificação de elenco completo e equilibrado) e adiciona award_game_winners para a recompensa de vários vencedores; e a 0030 adiciona a coluna team selecionável e seu RPC de sala de espera.
-- 0028_team_mode_enum.sql — its own migration (see above)
alter type game_mode add value 'team';
-- 0030_team_picker.sql — pickable side; NULL = slot-parity default (slot % 2)
alter table game_players
add column team smallint check (team is null or team in (0, 1));
-- SECURITY DEFINER lobby write (RLS has no user write on game_players):
-- a player sets their own seat; the creator may set any seat (to arrange bots).
create function set_player_team(p_game uuid, p_slot int, p_team smallint)
returns void language plpgsql security definer as $$ ... $$;Não foi preciso mudar o enum de event_kind — os dados de equipe viajam em campos opcionais de payload sobre eventos já existentes (game_started.players[].team, player_eliminated.inheritedBySlot, game_finished.winnerTeam). As equipes escolhidas (e não a paridade) são costuradas no initializeGame; o daemon se recusa a iniciar uma partida em equipe cujo elenco não esteja completo (team_roster_not_full) ou não esteja equilibrado (team_not_balanced). Os testes Engine 214 / daemon 82 no verde, e a propriedade de terminação do fast-check agora leva partidas 2×2 e 3×3 até o fim.
