العب 2 ضد 2 و3 ضد 3: وضع الفريق
كوّن فريقًا مع صديق، وادمجوا ممتلكاتكم، وانتصروا معًا — أصبح في opolyx الآن مباريات فرق 2×2 و3×3.

بكلمات بسيطة
بعض المباريات تكون أفضل مع شريك. يضع وضع الفريق جانبين في مواجهة بعضهما — 2 ضد 2 في مباراة من أربعة لاعبين أو 3 ضد 3 في مباراة من ستة لاعبين — لتلعب أنت وأصدقاؤك لصالح لون واحد، لا لأنفسكم فقط.
وجودكم في الجانب نفسه يغيّر كل شيء في طريقة لعبكم معًا. زملاؤك في الفريق حلفاء لا منافسون، فينفتح أمامكم اللوح:
- إذا حللت على ممتلكات أحد زملائك في الفريق فلن تدفع شيئًا — الإيجار لا يُفرض إلا على الفريق الآخر.
- مرّروا النقد والممتلكات بين زملاء الفريق بحرية — لا توجد قاعدة الـ50%، فيمكنك أن تهب شريكًا متعثرًا ما يحتاجه دون مقابل.
- إذا أفلس أحد زملائك في الفريق، فإن ممتلكاته كلها تؤول إليك لا إلى البنك — ولا يخرج الفريق إلا حين يرحل كل أعضائه.
- تنتصرون كفريق: آخر جانب صامد، أو الجانب الأغنى عند بلوغ حد الجولات — ويحصل كلا زميلَي الفريق على مكافأة الفوز (نقاط XP وبطاقة).
نسّقوا صفقاتكم، وغطّوا أحدكم الآخر، واطردوا الفريق المنافس من اللوح معًا. إنه opolyx نفسه الذي تعرفه — مع شريك في صفّك.
للمهتمين بالتفاصيل التقنية
وضع الفريق هو مجموعة قواعد Classic مع مفهوم جديد واحد لكل لاعب: الفريق. يضيف المحرك حقل PlayerState.team وحفنة من المحدِّدات (sameTeam وteamOf وaliveTeams وteamNetWorth) التي تقرؤها القواعد: computeRent يُعفي زملاء الفريق، وdoProposeTrade يتخطى قاعدة الـ50% بينهم، والإقصاء يوجّه الممتلكات إلى زميل الفريق الحي صاحب أدنى خانة بدلًا من البنك. وتُقيَّم شروط النهاية لكل فريق — آخر فريق صامد، أو الفريق الأغنى عند سقف الجولات.
يُنجزه ثلاث عمليات ترحيل. يمنع Postgres استخدام قيمة enum جديدة في المعاملة نفسها التي تضيفها، لذا تُثبّت 0028 قيمة game_mode الخاصة بالفريق بمفردها؛ ثم تتيح 0029 لـ create_game قبولها (مع فحص اكتمال القائمة وتوازنها) وتضيف award_game_winners لمكافأة الفائزين المتعددين؛ وتضيف 0030 عمود team القابل للاختيار وما يخصه من RPC في غرفة الانتظار.
-- 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 $$ ... $$;لم تكن هناك حاجة إلى تغيير enum الخاص بـ event_kind — فبيانات الفريق تُحمَل على حقول payload اختيارية ضمن الأحداث القائمة (game_started.players[].team وplayer_eliminated.inheritedBySlot وgame_finished.winnerTeam). وتُمرَّر الفرق المختارة (لا التكافؤ) إلى initializeGame؛ ويرفض الـ daemon بدء مباراة فريق قائمتها غير مكتملة (team_roster_not_full) أو غير متوازنة (team_not_balanced). اختبارات Engine 214 / daemon 82 ناجحة، وخاصية الإنهاء في fast-check تقود الآن مباريات 2×2 و3×3 إلى نهايتها.
