> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qwacks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# اللعب الجماعي

> الفرق والمطابقة والجلسات، واتصال اللاعبين عبر وسيط Flock.

يجمع **اللعب الجماعي** في Flock اللاعبين ويصل بينهم. يكوّن الأصدقاء [فريقًا](/ar/guides/parties.md)،
ثم يجد الفريق أو اللاعب المنفرد [مطابقة](/ar/guides/matchmaking.md) أو ينضم إلى لعبة صديق برمز، وكل
لعبة هي [جلسة](/ar/guides/sessions.md): يستضيفها لاعب واحد، ويشغل الآخرون مقاعد فيها. ثم
[تصل حزمة التطوير بين اللاعبين](/ar/guides/connecting-players.md) عبر شبكة لعبتك: Netcode for GameObjects
في Unity، وشبكة المحرّك نفسه في Unreal. يتصل اللاعبون الموجودون على شبكة المضيف به مباشرة، ويمرّ
الآخرون عبر وسيط Flock، فلا يحتاج أحد إلى فتح منفذ في الموجّه، ثم ينتقلون في Unity إلى مسار مباشر إلى
المضيف حين يتمكّن الطرفان من الوصول أحدهما إلى الآخر. وحين يغادر المضيف، يتولّى لاعب آخر الاستضافة.

> [!NOTE]
>
> **النطاق:** تُعرَّف طوابير المطابقة وإعدادات اللعب الجماعي لكل **لعبة**؛ أما الفرق والمقاعد فتخصّ اللاعب.

> **[الفرق](/ar/guides/parties.md)**
>
> أصدقاء يبقون معًا من لعبة إلى أخرى.

> **[المطابقة](/ar/guides/matchmaking.md)**
>
> املأ لعبة من طابور، منفردًا أو مع فريق.

> **[الجلسات](/ar/guides/sessions.md)**
>
> لعبة واحدة: مضيف ولاعبوه ورمز انضمام.

> **[اتصال اللاعبين](/ar/guides/connecting-players.md)**
>
> Netcode for GameObjects أو شبكة Unreal نفسها، والوسيط وتغيّر المضيف.

## الإعداد

**لوحة التحكم**

افتح **اللعب الجماعي ← الجلسات** واضغط **إعدادات اللعب الجماعي**. القيم الافتراضية تناسب معظم
الألعاب:

| الإعداد | الافتراضي | ما يفعله |
| - | - | - |
| **الحد الأقصى للاعبين في الجلسة** | 8 | عدد المقاعد في جلسة يستضيفها لاعب أو تصنعها مطابقة، من 2 إلى 16. |
| **مهلة المشارك (ثوانٍ)** | 90 | اللاعب الصامت مدة أطول من هذه يفقد مقعده. |
| **مهلة المضيف (ثوانٍ)** | 60 | المضيف الصامت مدة أطول من هذه يحلّ محلّه اللاعب الأقدم جلوسًا. |
| **الحد الأقصى لعمر الجلسة (ثوانٍ)** | 14400 | تنتهي كل جلسة بعد هذه المدة (4 ساعات) مهما كان نشاطها. |
| **إنشاء جلسة عند تكوّن مطابقة** | مفعّل | يحصل اللاعبون المتطابقون على جلسة يلعبون فيها. |
| **توزيع بيانات اعتماد الوسيط** | مفعّل | يتصل اللاعبون على شبكات مختلفة عبر وسيط Flock. وعند إيقافه لا يتصل إلا اللاعبون على شبكة المضيف، أو عبر منفذ مُوجَّه إليه. |

ثم أنشئ طابورًا لكل نمط من **اللعب الجماعي ← نظام المطابقة**؛ راجع
[المطابقة](/ar/guides/matchmaking.md).

**Unity**

1. ثبّت **Netcode for GameObjects** بالإصدار 1.x أو 2.x من Package Manager. لا يُبنى دعم Flock
   للشبكة إلا عند تثبيته. ويجب أن يستخدم كل لاعبي اللعبة الإصدار الرئيسي نفسه. وقد جرى التحقق من
   اللعب الجماعي على Unity 2021.3 مع Netcode 1.14، وعلى Unity 6000.3 مع Netcode 2.13.
2. في **Flock → Settings**، اضبط **Party Refresh Seconds**: كل كم ثانية تقرأ حزمة التطوير فريق اللاعب
   في الخلفية (10 افتراضيًا؛ والقيمة 0 توقف ذلك).
3. استخدم `NetworkManager` واحدًا مع Unity Transport، واترك حجم الرسالة على قيمته الافتراضية.
4. سجّل دخول اللاعب قبل أي استدعاء للعب الجماعي، ونفّذ كل استدعاء من الخيط الرئيسي. وتُطلق كل
   أحداث اللعب الجماعي على الخيط الرئيسي.
5. تبدأ السكربتات التي تستخدم اللعب الجماعي بـ `using Flock;` و`using Flock.Providers;` (وأضف
   `using Flock.Exceptions;` لـ `FlockErrorCode`، و`using Unity.Netcode;` لـ `NetworkManager`).
   والسكربت الموجود في تعريف تجميع خاص به يشير إلى `Flock.Runtime`، وإلى
   `Flock.Multiplayer.Netcode` من أجل `StartNetcodeAsync`.

كل الاستدعاءات على `FlockClient.Instance.Multiplayer`، أو على كائن يعيده.

يحتوي مجلد **Samples/Multiplayer** في الحزمة على عيّنتين من شاشة واحدة:
**FlockPlayWithFriendsSample** (استضِف واقرأ الرمز بصوت عالٍ، فينضم صديق)،
و**FlockQuickMatchSample** (يجد اللاعبون بعضهم في طابور). أضف أيًّا منهما إلى GameObject فارغ
واضغط Play في نسختين من اللعبة.

**Unreal**

1. استخدم Unreal Engine من 5.4 إلى 5.8، وFlock Unreal SDK بالإصدار 1.35.0 أو أحدث. يعمل اللعب الجماعي
   على شبكة المحرّك نفسه، فلا شيء آخر تحتاج إلى تثبيته.
2. في **Project Settings → Plugins → Flock SDK Settings**، تحت **Multiplayer**، اضبط **Party Refresh
   Seconds**: كل كم ثانية تقرأ حزمة التطوير فريق اللاعب في الخلفية (10 افتراضيًا، أي نحو 6 طلبات في
   الدقيقة لكل لاعب؛ والقيمة 0 توقف ذلك).
3. أعطِ المضيف وضع لعب (game mode) لا يُدخل إلا لاعبي الجلسة: Blueprint مبنيًّا على **Flock Game Mode
   Base** (أو **Flock Game Mode**، لحالات المباراة) ومضبوطًا في **Project Settings → Maps & Modes**، أو
   وضع لعب خاصًّا بك يستدعي تحقّق Flock في `PreLoginAsync`؛ راجع
   [من ينضم](/ar/guides/connecting-players.md#who-is-joining). والمضيف الذي يفتقده لا يُدخل أحدًا
   (`join_check_missing`).
4. أبقِ على شبكة IP الخاصة بالمحرّك. مع نظام Steam الفرعي على الإنترنت، اضبط
   `bUseSteamNetworking=False` تحت `[OnlineSubsystemSteam]` في `Config/DefaultEngine.ini`: فمقابس
   Steam لا تستطيع الاستماع على عنوان IP، فينتهي Travel To Session بـ `could_not_start`. ولا يتأثّر
   تسجيل الدخول عبر Steam.
5. سجّل دخول اللاعب قبل أي استدعاء للعب الجماعي، ونفّذ كل استدعاء من خيط اللعبة. وتُطلق كل أحداث
   اللعب الجماعي على خيط اللعبة.
6. تُضمّن شيفرة C++ التي تستخدم اللعب الجماعي `FlockSubsystem.h` و`Multiplayer/FlockParty.h` أو
   `Multiplayer/FlockMultiplayerSession.h`، في وحدة تعتمد على `Flock` في ملف `.Build.cs` الخاص بها.

كل الاستدعاءات على `UFlockSubsystem::GetMultiplayerProvider()`، أو على كائن يعيده. وفي Blueprint،
كل استدعاء عقدة تحت **Flock | Multiplayer**.

يحتوي مجلد **Content/Samples/Multiplayer** في الإضافة (فعّل **Show Plugin Content** في
Content Browser) على عيّنة مبنية بـ Blueprint فقط، بدءًا من SDK 1.36.0:
يسجّل **BP\_FlockSampleGameInstance** الدخول باسم جهاز، ويستضيف، وينضم برمز، ويبحث عن مباراة
سريعة، وينتقل إلى الجلسة وينتقل مجددًا عند تغيّر المضيف؛ و**FlockMultiplayerSample** هو مستواها،
ويعمل بـ Flock Game Mode Base. اضبط **Game Instance Class** على `BP_FlockSampleGameInstance`
في **Project Settings → Maps & Modes**، وافتح المستوى، وشغّله في لعبتين مستقلتين، كل منهما
مسجّلة الدخول باسم جهاز خاص بها.

![بطاقة العيّنة: حقل اسم الجهاز، وزرّا Sign In وHost، وحقل رمز الانضمام وزر Join، وحقل اسم الطابور، وزرّا Quick Match وLeave، وسطر الحالة مع الرمز](https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-in-game.png?fit=max\&auto=format\&n=sKCVX05gMuqzHxSa\&q=85\&s=663013f462f2009675ccf7458de8f357)

عيّنة Unreal أثناء اللعب: يعرض سطر الحالة رمز الانضمام الذي يكتبه الصديق لينضم.

## أي إعداد يناسب لعبتك

| لعبتك | يلتقي اللاعبون عبر | الوسيط |
| - | - | - |
| اللعب التعاوني المحلي: أجهزة على شبكة واحدة (حفلة LAN، أو شبكة Wi-Fi واحدة) | رمز انضمام الجلسة | عند الحاجة فقط (الافتراضي): يتصل اللاعبون على شبكة المضيف به مباشرة. أو أبدًا، فلا وسيط إطلاقًا. |
| اللعب التعاوني عبر الإنترنت مع أصدقاء على شبكات أخرى | رمز انضمام الجلسة | عند الحاجة فقط |
| المطابقة عبر الإنترنت مع لاعبين لا تعرفهم | طابور | عند الحاجة فقط |
| أصدقاء يُطابَقون معًا، ضد آخرين أو معهم | فريق، ثم طابور | عند الحاجة فقط |
| صنّاع البث المباشر واللعب التنافسي، حيث لا يجوز أن يرى أحد عنوان IP لغيره | أيٌّ مما سبق | دائمًا، في كل لعبة |
| Steam أو Epic Online Services أو شبكتك الخاصة | أيٌّ مما سبق | لا يُستخدم |

لا يحتاج عدة لاعبين على جهاز واحد (شاشة مقسّمة، أو أذرع تحكم مشتركة) إلى أيٍّ من هذا: فتلك لعبة واحدة
بلاعب Flock واحد، واللعب الجماعي في Flock يصل بين الأجهزة.

**لوحة التحكم**

* **اللعب التعاوني المحلي:** لا شيء غير إعدادات اللعب الجماعي.
* **اللعب التعاوني مع الأصدقاء عبر الإنترنت:** اترك **توزيع بيانات اعتماد الوسيط** مفعّلًا.
* **المطابقة عبر الإنترنت:** طابور لكل نمط من **اللعب الجماعي ← نظام المطابقة**، بأصغر مطابقة
  وأكبرها.
* **أصدقاء يُطابَقون معًا:** طابور تتسع أكبر مطابقة فيه للفريق كله.
* **صنّاع البث واللعب التنافسي:** لا شيء آخر؛ فالاختيار يتمّ في اللعبة.

**Unity**

**اللعب التعاوني المحلي، واللعب التعاوني مع الأصدقاء.** يستضيف لاعب واحد ويشارك رمز الانضمام (بصوت
عالٍ في الغرفة، أو عبر ردهة لعبتك أو قائمة أصدقائها أو محادثتها)، وينضم الآخرون به. يتصل
اللاعبون على شبكة المضيف به مباشرة؛ ومع `WhenNeeded` الافتراضي، يمرّ الصديق الموجود على شبكة أخرى
عبر وسيط Flock، ثم ينتقل إلى مسار مباشر حين يتمكّن الطرفان من الوصول أحدهما إلى الآخر. ويلعب الهاتف
والحاسوب معًا بالطريقة نفسها. وهذا ما تفعله **FlockPlayWithFriendsSample** بالضبط.

```csharp theme={null}
// The host's game.
FlockMultiplayerSession session = await FlockClient.Instance.Multiplayer.HostSessionAsync(4);
joinCodeLabel.text = session.JoinCode;
await session.StartNetcodeAsync(NetworkManager.Singleton);

// Each other player's game, with the code the host shared.
FlockMultiplayerSession joined = await FlockClient.Instance.Multiplayer.JoinSessionAsync(typedCode);
FlockNetcodeStartResult started = await joined.StartNetcodeAsync(NetworkManager.Singleton);
// started.ThroughRelay is false for a player on the host's network.
```

للعبة تعمل على الشبكة المحلية فقط، مرّر `new FlockNetcodeOptions { Relay = FlockRelayUse.Never }` في
كل لعبة؛ وعندها يحصل اللاعب الموجود في مكان آخر على `CouldNotConnect` ما لم يُوجَّه منفذ إلى المضيف.

**المطابقة عبر الإنترنت.** وهذا ما تفعله **FlockQuickMatchSample**.

```csharp theme={null}
FlockMatchmakingResult found = await FlockClient.Instance.Multiplayer.FindMatchAsync("casual-1v1");
if (found.IsMatched && found.Session != null)
    await found.Session.StartNetcodeAsync(NetworkManager.Singleton);   // the player who waited longest hosts
else
    ShowMessage("No match: " + found.Outcome);
```

**أصدقاء يُطابَقون معًا.** يكوّن الأصدقاء [فريقًا](/ar/guides/parties.md) ويبحث القائد عنهم جميعًا؛
وتسمع لعبة كل عضو النتيجة.

```csharp theme={null}
party.SearchEnded += async result =>
{
    if (result.IsMatched && result.Session != null)
        await result.Session.StartNetcodeAsync(NetworkManager.Singleton);
};

if (party.IsLeader)
    await party.FindMatchAsync("squads");
```

**صنّاع البث واللعب التنافسي.** تمرّ كل حزمة عبر وسيط Flock، ولا تعرف أي لعبة عنوان IP لغيرها؛
وتقطع كل حزمة المحطة الإضافية للوسيط.

```csharp theme={null}
await session.StartNetcodeAsync(NetworkManager.Singleton, new FlockNetcodeOptions { Relay = FlockRelayUse.Always });
```

**Steam أو Epic Online Services أو شبكتك الخاصة:** راجع
[الشبكات الأخرى](/ar/guides/connecting-players.md#other-networking).

**Unreal**

تعمل الأمثلة في Game Instance الخاصة بلعبتك، التي تبقى بعد تغييرات المستوى التي يجريها Travel To
Session. و`TravelOptions` من نوع `FFlockTravelToSessionOptions` محفوظ هناك، وقيمة `HostLevel` فيه
هي المستوى الذي يفتحه المضيف.

**اللعب التعاوني المحلي، واللعب التعاوني مع الأصدقاء.** يستضيف لاعب واحد ويشارك رمز الانضمام (بصوت
عالٍ في الغرفة، أو عبر ردهة لعبتك أو قائمة أصدقائها أو محادثتها)، وينضم الآخرون به. يتصل
اللاعبون على شبكة المضيف به مباشرة؛ ومع `WhenNeeded` الافتراضي، يمرّ الصديق الموجود على شبكة أخرى
عبر وسيط Flock.
زرّا **Host** و**Join** في العيّنة يفعلان هذا بالضبط، في Blueprint.

```cpp theme={null}
FFlockMultiplayerProvider* Multiplayer = GetSubsystem<UFlockSubsystem>()->GetMultiplayerProvider();

// The host's game.
Multiplayer->HostSession(4, FFlockCommandData(), true, [this](TFlockResult<UFlockMultiplayerSession*> Hosted)
{
    if (Hosted.IsSuccess())
    {
        Session = Hosted.Value;
        ShowJoinCode(Session->GetJoinCode());
        Session->TravelToSession(this, TravelOptions, [](TFlockResult<FFlockTravelToSessionResult> Travel) {});
    }
});

// Each other player's game, with the code the host shared.
Multiplayer->JoinSession(TypedCode, [this](TFlockResult<UFlockMultiplayerSession*> Joined)
{
    if (Joined.IsSuccess())
    {
        Session = Joined.Value;
        Session->TravelToSession(this, TravelOptions, [](TFlockResult<FFlockTravelToSessionResult> Travel)
        {
            // Travel.Value.bThroughRelay is false for a player on the host's network.
        });
    }
});
```

للعبة تعمل على الشبكة المحلية فقط، اضبط `TravelOptions.Relay = EFlockRelayUse::Never` في كل لعبة؛
وعندها يحصل اللاعب الموجود في مكان آخر على `could_not_connect` ما لم يُوجَّه منفذ إلى المضيف.

**المطابقة عبر الإنترنت.**
زر **Quick Match** في العيّنة يفعل هذا، في Blueprint.

```cpp theme={null}
Multiplayer->FindMatch(TEXT("casual-1v1"), FFlockMatchmakingOptions(), [this](TFlockResult<FFlockMatchmakingResult> Found)
{
    if (Found.IsSuccess() && Found.Value.IsMatched() && Found.Value.Session != nullptr)
    {
        Session = Found.Value.Session;   // the player who waited longest hosts
        Session->TravelToSession(this, TravelOptions, [](TFlockResult<FFlockTravelToSessionResult> Travel) {});
    }
    else if (Found.IsSuccess())
    {
        ShowMessage(TEXT("No match: ") + Found.Value.Outcome);
    }
});
```

**أصدقاء يُطابَقون معًا.** يكوّن الأصدقاء [فريقًا](/ar/guides/parties.md) ويبحث القائد عنهم جميعًا؛
وتسمع لعبة كل عضو النتيجة.

```cpp theme={null}
Party->OnSearchEnded.AddDynamic(this, &UMyGameInstance::PlayMatch);

if (Party->IsLeader())
{
    Party->FindMatch(TEXT("squads"), FFlockMatchmakingOptions(), nullptr);
}

void UMyGameInstance::PlayMatch(const FFlockMatchmakingResult& Result)
{
    if (Result.IsMatched() && Result.Session != nullptr)
    {
        Session = Result.Session;
        Session->TravelToSession(this, TravelOptions, [](TFlockResult<FFlockTravelToSessionResult> Travel) {});
    }
}
```

**صنّاع البث واللعب التنافسي.** تمرّ كل حزمة عبر وسيط Flock، ولا تعرف أي لعبة عنوان IP لغيرها؛
وتقطع كل حزمة المحطة الإضافية للوسيط. اضبط ذلك في كل لعبة:

```cpp theme={null}
TravelOptions.Relay = EFlockRelayUse::Always;
```

**Steam أو Epic Online Services أو شبكتك الخاصة:** راجع
[الشبكات الأخرى](/ar/guides/connecting-players.md#other-networking). يحتاج Travel To Session إلى شبكة IP
الخاصة بالمحرّك، فاللعبة التي تستخدم مقابس Steam تنشر اتصال Steam خاصًّا بها.

## ما تتولّاه حزمة التطوير عنك

* **تحفظ كل مقعد.** ترسل نبضة الجلسة كل 20 ثانية ما دامت اللعبة تعمل.
* **تُبقي كائناتك محدّثة.** تقرأ الفريق والبحث والجلسة في الخلفية، وتطلق أحداثًا عند حدوث تغيير:
  انضمام لاعب، أو تغيّر القائد أو المضيف، أو انتهاء بحث، أو انتهاء الجلسة.
* **تجد الجلسة من جديد** بعد إعادة تشغيل اللعبة (`GetMySessionAsync`، أو `GetMySession` في Unreal)،
  والفريق كذلك (`GetMyPartyAsync`، أو `GetMyParty`).
* **تتخلّى عن المقعد عند إغلاق اللعبة**، فيرى الآخرون ذلك فورًا.

## ما الذي يُحتسب استدعاءً للواجهة البرمجية

القراءات في الخلفية (الفريق والبحث والجلسة وانتظار المضيف حتى يعلن مكانه) والنبضات **لا** تُحتسب
استدعاءات مدفوعة. وتتشارك حدًّا قدره **120 في الدقيقة لكل لاعب**، والقيم الافتراضية في حزمة
التطوير تستخدم أقل من 60. أما الأفعال فتُحتسب كالمعتاد: إنشاء فريق أو جلسة أو الانضمام إليهما، وبدء بحث،
والمغادرة، وتحقّق المضيف من كل لاعب ينضم، وتسجيلات الدخول إلى الوسيط، وإخبار اللاعب المارّ عبر الوسيط
المضيفَ بعنوانه على الوسيط (مرة لكل عنوان).

## أي الألعاب يناسبها

المضيف أحد اللاعبين، والجلسة تتسع لـ 16 لاعبًا كحدّ أقصى، والمطابقة بالأسبقية: من يبحث أولًا يُطابَق
أولًا.

| يناسبها جيدًا | يناسبها بحذر | لا يناسبها حاليًا |
| - | - | - |
| الألعاب التعاونية من 2 إلى 8 لاعبين: استكشاف الأبراج المحصّنة، والبقاء، وصدّ الموجات | المواجهات الودّية 1 ضد 1 و2 ضد 2، لا التصنيفية | ألعاب MMO والعوالم الدائمة |
| ألعاب الحفلات والقتال والسباق مع الأصدقاء | ألعاب التصويب السريعة: للمضيف أفضلية، واللاعب الذي يبقى على الوسيط يلعب عبر محطته الإضافية | باتل رويال والألعاب من 50 إلى 100 لاعب |
| ألعاب الطاولة والورق والأدوار | من 9 إلى 16 لاعبًا: يرسل المضيف إلى الجميع، وهذا يُحسب على الهاتف | اللعب التصنيفي الذي يحتاج خوادم مخصّصة ومطابقة حسب المهارة |
| الهاتف والحاسوب معًا | العوالم التي يحفظها لاعب: احفظ الحالة خارج المضيف | ألعاب المتصفح (لا يستطيع المتصفح إرسال UDP) |

## الحدود حاليًا

* **لا خوادم مخصّصة.** يستضيف لاعبٌ كل جلسة.
* **لا مطابقة حسب المهارة أو المنطقة بعد.** يحفظ Flock ما يرسله البحث لكنه يطابق بترتيب البحث.
  استخدم طابورًا لكل نمط ومنطقة.
* **لا يستطيع المضيف إخراج لاعب، وبيانات الجلسة تُضبط مرة واحدة** عند إنشائها.
* **نوع واحد من الشبكات لكل محرّك.** في Unity، Netcode for GameObjects بالإصدارين 1.x و2.x؛ وفي Unreal، شبكة IP
  الخاصة بالمحرّك نفسه، لا مقابس Steam. تستخدم الشبكات الأخرى الاتصال المنشور للجلسة ورمز الانضمام
  مباشرة؛ راجع [اتصال اللاعبين](/ar/guides/connecting-players.md).
* **في Unreal، يبقى اللاعبون المارّون عبر الوسيط عليه.** لا مسار مباشر في Unreal SDK بعد، فتقطع كل حزمة
  من حزمهم المحطة الإضافية للوسيط.
* **لاعبو المتصفح** يستطيعون استخدام الفرق والمطابقة والجلسات، لا الوسيط: فالمتصفح لا يستطيع إرسال
  UDP.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.