Juega 2 vs 2 y 3 vs 3: modo equipo
Forma equipo con un amigo, combinad vuestras propiedades y ganad juntos: opolyx ya tiene partidas por equipos de 2×2 y 3×3.

En palabras sencillas
Algunas partidas son mejores con un compañero. El modo equipo enfrenta a dos bandos — 2 vs 2 en una partida de cuatro jugadores o 3 vs 3 en una de seis — para que tú y tus amigos juguéis por un color, no solo por vosotros mismos.
Estar en el mismo bando lo cambia todo en la forma de jugar juntos. Tus compañeros son aliados, no rivales, así que el tablero se abre:
- Si caes en la propiedad de un compañero no pagas nada: el alquiler solo se cobra al otro equipo.
- Pasaos dinero y propiedades entre compañeros sin restricciones: no hay regla del 50%, así que puedes regalar sin más a un compañero en apuros lo que necesite.
- Si un compañero se arruina, todo su patrimonio pasa a ti, no al banco: un equipo solo queda fuera cuando todos sus miembros han caído.
- Ganáis como equipo: el último bando en pie, o el bando más rico cuando se alcanza el límite de rondas, y ambos compañeros reciben la recompensa de victoria (XP y una carta).
Coordinad vuestros intercambios, cubríos las espaldas y sacad juntos al equipo rival del tablero. Es el mismo opolyx que conoces, pero con un compañero de tu lado.
Para los más técnicos
El modo equipo es el conjunto de reglas Classic con un nuevo concepto por jugador: el equipo. El motor añade un campo PlayerState.team y un puñado de selectores (sameTeam, teamOf, aliveTeams, teamNetWorth) que leen las reglas: computeRent exime a los compañeros de equipo, doProposeTrade omite la regla del 50% entre ellos y la eliminación envía el patrimonio al compañero vivo de menor casilla en lugar de al banco. Las condiciones de fin se evalúan por equipo: el último equipo en pie, o el equipo más rico al llegar al tope de rondas.
Lo implementan tres migraciones. Postgres prohíbe usar un nuevo valor de enum en la misma transacción que lo añade, así que 0028 confirma por sí sola el game_mode del equipo; luego 0029 permite que create_game lo acepte (con una comprobación de plantilla completa y equilibrada) y añade award_game_winners para la recompensa de varios ganadores; y 0030 añade la columna team seleccionable y su 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 $$ ... $$;No hizo falta cambiar el enum de event_kind: los datos de equipo viajan en campos opcionales de payload sobre eventos ya existentes (game_started.players[].team, player_eliminated.inheritedBySlot, game_finished.winnerTeam). Los equipos elegidos (no la paridad) se enhebran en initializeGame; el daemon se niega a iniciar una partida por equipos cuya plantilla no esté completa (team_roster_not_full) o no esté equilibrada (team_not_balanced). Las pruebas de Engine 214 / daemon 82 en verde, y la propiedad de terminación de fast-check ahora lleva partidas 2×2 y 3×3 hasta el final.
